Merge "Add unlock to see more messaging to locked shade" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
0b72c62716
@@ -21,12 +21,29 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
>
|
||||
<TextView
|
||||
android:id="@+id/no_notifications"
|
||||
<LinearLayout android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="64dp"
|
||||
android:textAppearance="?android:attr/textAppearanceButton"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:text="@string/empty_shade_text"/>
|
||||
>
|
||||
<TextView
|
||||
android:id="@+id/no_notifications"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="64dp"
|
||||
android:gravity="center"
|
||||
android:textAppearance="?android:attr/textAppearanceButton"
|
||||
android:text="@string/empty_shade_text"/>
|
||||
<TextView
|
||||
android:id="@+id/no_notifications_footer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:gravity="center"
|
||||
android:drawablePadding="8dp"
|
||||
android:visibility="gone"
|
||||
android:textAppearance="?android:attr/textAppearanceButton"
|
||||
android:text="@string/unlock_to_see_notif_text"/>
|
||||
</LinearLayout>
|
||||
</com.android.systemui.statusbar.EmptyShadeView>
|
||||
|
||||
@@ -403,6 +403,8 @@
|
||||
(quick_qs_offset_height (60dp) - ongoing_appops_chip_height (24dp) ) / 2 -->
|
||||
<dimen name="notifications_top_padding_split_shade">18dp</dimen>
|
||||
|
||||
<dimen name="notifications_unseen_footer_icon_size">16dp</dimen>
|
||||
|
||||
<!-- Height of the status bar header bar when on Keyguard -->
|
||||
<dimen name="status_bar_header_height_keyguard">40dp</dimen>
|
||||
|
||||
|
||||
@@ -1049,6 +1049,12 @@
|
||||
<!-- Text which is shown in the notification shade when there are no notifications. [CHAR LIMIT=30] -->
|
||||
<string name="empty_shade_text">No notifications</string>
|
||||
|
||||
<!-- Text which is shown in the expanded notification shade when there are currently no notifications visible that the user hasn't already seen. [CHAR LIMIT=30] -->
|
||||
<string name="no_unseen_notif_text">No new notifications</string>
|
||||
|
||||
<!-- Text which is shown in the locked notification shade when there are currently no notifications, but if the user were to unlock, notifications would appear. [CHAR LIMIT=40] -->
|
||||
<string name="unlock_to_see_notif_text">Unlock to see older notifications</string>
|
||||
|
||||
<!-- Disclosure at the bottom of Quick Settings that indicates that parental controls are enabled. [CHAR LIMIT=100] -->
|
||||
<string name="quick_settings_disclosure_parental_controls">This device is managed by your parent</string>
|
||||
|
||||
|
||||
@@ -17,9 +17,12 @@
|
||||
package com.android.systemui.statusbar;
|
||||
|
||||
import android.annotation.ColorInt;
|
||||
import android.annotation.DrawableRes;
|
||||
import android.annotation.StringRes;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
@@ -33,16 +36,30 @@ import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
|
||||
public class EmptyShadeView extends StackScrollerDecorView {
|
||||
|
||||
private TextView mEmptyText;
|
||||
private TextView mEmptyFooterText;
|
||||
|
||||
private @StringRes int mText = R.string.empty_shade_text;
|
||||
|
||||
private @DrawableRes int mFooterIcon = R.drawable.ic_friction_lock_closed;
|
||||
private @StringRes int mFooterText = R.string.unlock_to_see_notif_text;
|
||||
private @Visibility int mFooterVisibility = View.GONE;
|
||||
private int mSize;
|
||||
|
||||
public EmptyShadeView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mSize = getResources().getDimensionPixelSize(
|
||||
R.dimen.notifications_unseen_footer_icon_size);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
mSize = getResources().getDimensionPixelSize(
|
||||
R.dimen.notifications_unseen_footer_icon_size);
|
||||
mEmptyText.setText(mText);
|
||||
mEmptyFooterText.setVisibility(mFooterVisibility);
|
||||
setFooterText(mFooterText);
|
||||
setFooterIcon(mFooterIcon);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -52,11 +69,13 @@ public class EmptyShadeView extends StackScrollerDecorView {
|
||||
|
||||
@Override
|
||||
protected View findSecondaryView() {
|
||||
return null;
|
||||
return findViewById(R.id.no_notifications_footer);
|
||||
}
|
||||
|
||||
public void setTextColor(@ColorInt int color) {
|
||||
mEmptyText.setTextColor(color);
|
||||
mEmptyFooterText.setTextColor(color);
|
||||
mEmptyFooterText.setCompoundDrawableTintList(ColorStateList.valueOf(color));
|
||||
}
|
||||
|
||||
public void setText(@StringRes int text) {
|
||||
@@ -64,14 +83,53 @@ public class EmptyShadeView extends StackScrollerDecorView {
|
||||
mEmptyText.setText(mText);
|
||||
}
|
||||
|
||||
public void setFooterVisibility(@Visibility int visibility) {
|
||||
mFooterVisibility = visibility;
|
||||
setSecondaryVisible(visibility == View.VISIBLE, false);
|
||||
}
|
||||
|
||||
public void setFooterText(@StringRes int text) {
|
||||
mFooterText = text;
|
||||
if (text != 0) {
|
||||
mEmptyFooterText.setText(mFooterText);
|
||||
} else {
|
||||
mEmptyFooterText.setText(null);
|
||||
}
|
||||
}
|
||||
|
||||
public void setFooterIcon(@DrawableRes int icon) {
|
||||
mFooterIcon = icon;
|
||||
Drawable drawable;
|
||||
if (icon == 0) {
|
||||
drawable = null;
|
||||
} else {
|
||||
drawable = getResources().getDrawable(icon);
|
||||
drawable.setBounds(0, 0, mSize, mSize);
|
||||
}
|
||||
mEmptyFooterText.setCompoundDrawablesRelative(drawable, null, null, null);
|
||||
}
|
||||
|
||||
@StringRes
|
||||
public int getTextResource() {
|
||||
return mText;
|
||||
}
|
||||
|
||||
@StringRes
|
||||
public int getFooterTextResource() {
|
||||
return mFooterText;
|
||||
}
|
||||
|
||||
@DrawableRes
|
||||
public int getFooterIconResource() {
|
||||
return mFooterIcon;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
mEmptyText = (TextView) findContentView();
|
||||
mEmptyFooterText = (TextView) findSecondaryView();
|
||||
mEmptyFooterText.setCompoundDrawableTintList(mEmptyFooterText.getTextColors());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.android.systemui.statusbar.notification.collection.coordinator.dagger
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
|
||||
import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
|
||||
import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderImpl
|
||||
import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider
|
||||
import javax.inject.Inject
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
@@ -49,6 +50,7 @@ constructor(
|
||||
private val notifPipelineFlags: NotifPipelineFlags,
|
||||
@Application private val scope: CoroutineScope,
|
||||
private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider,
|
||||
private val seenNotifsProvider: SeenNotificationsProviderImpl,
|
||||
private val statusBarStateController: StatusBarStateController,
|
||||
) : Coordinator {
|
||||
|
||||
@@ -105,6 +107,9 @@ constructor(
|
||||
@VisibleForTesting
|
||||
internal val unseenNotifFilter =
|
||||
object : NotifFilter("$TAG-unseen") {
|
||||
|
||||
var hasFilteredAnyNotifs = false
|
||||
|
||||
override fun shouldFilterOut(entry: NotificationEntry, now: Long): Boolean =
|
||||
when {
|
||||
// Don't apply filter if the keyguard isn't currently showing
|
||||
@@ -115,7 +120,12 @@ constructor(
|
||||
// - summary will be pruned if necessary, depending on if children are filtered
|
||||
entry.parent?.summary == entry -> false
|
||||
else -> true
|
||||
}
|
||||
}.also { hasFiltered -> hasFilteredAnyNotifs = hasFilteredAnyNotifs || hasFiltered }
|
||||
|
||||
override fun onCleanup() {
|
||||
seenNotifsProvider.hasFilteredOutSeenNotifications = hasFilteredAnyNotifs
|
||||
hasFilteredAnyNotifs = false
|
||||
}
|
||||
}
|
||||
|
||||
private val notifFilter: NotifFilter =
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.notification.collection.provider
|
||||
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import javax.inject.Inject
|
||||
|
||||
/** Keeps track of whether "seen" notification content has been filtered out of the shade. */
|
||||
interface SeenNotificationsProvider {
|
||||
/** Are any already-seen notifications currently filtered out of the shade? */
|
||||
val hasFilteredOutSeenNotifications: Boolean
|
||||
}
|
||||
|
||||
@Module
|
||||
interface SeenNotificationsProviderModule {
|
||||
@Binds
|
||||
fun bindSeenNotificationsProvider(
|
||||
impl: SeenNotificationsProviderImpl
|
||||
): SeenNotificationsProvider
|
||||
}
|
||||
|
||||
@SysUISingleton
|
||||
class SeenNotificationsProviderImpl @Inject constructor() : SeenNotificationsProvider {
|
||||
override var hasFilteredOutSeenNotifications: Boolean = false
|
||||
}
|
||||
@@ -52,6 +52,7 @@ import com.android.systemui.statusbar.notification.collection.inflation.OnUserIn
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
|
||||
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
|
||||
import com.android.systemui.statusbar.notification.collection.provider.NotificationVisibilityProviderImpl;
|
||||
import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderModule;
|
||||
import com.android.systemui.statusbar.notification.collection.provider.VisibilityLocationProviderDelegator;
|
||||
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
|
||||
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManagerImpl;
|
||||
@@ -96,6 +97,7 @@ import dagger.Provides;
|
||||
@Module(includes = {
|
||||
CoordinatorsModule.class,
|
||||
KeyguardNotificationVisibilityProviderModule.class,
|
||||
SeenNotificationsProviderModule.class,
|
||||
ShadeEventsModule.class,
|
||||
NotifPipelineChoreographerModule.class,
|
||||
NotificationSectionHeadersModule.class,
|
||||
|
||||
@@ -32,10 +32,12 @@ import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.TimeAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.ColorInt;
|
||||
import android.annotation.DrawableRes;
|
||||
import android.annotation.FloatRange;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.StringRes;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
@@ -4556,7 +4558,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
}
|
||||
|
||||
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
||||
void setEmptyShadeView(EmptyShadeView emptyShadeView) {
|
||||
public void setEmptyShadeView(EmptyShadeView emptyShadeView) {
|
||||
int index = -1;
|
||||
if (mEmptyShadeView != null) {
|
||||
index = indexOfChild(mEmptyShadeView);
|
||||
@@ -4567,15 +4569,43 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
}
|
||||
|
||||
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
||||
void updateEmptyShadeView(boolean visible, boolean areNotificationsHiddenInShade) {
|
||||
void updateEmptyShadeView(
|
||||
boolean visible, boolean areNotificationsHiddenInShade, boolean areSeenNotifsFiltered) {
|
||||
mEmptyShadeView.setVisible(visible, mIsExpanded && mAnimationsEnabled);
|
||||
|
||||
if (areNotificationsHiddenInShade) {
|
||||
updateEmptyShadeView(R.string.dnd_suppressing_shade_text, 0, 0);
|
||||
} else if (areSeenNotifsFiltered) {
|
||||
updateEmptyShadeView(
|
||||
R.string.no_unseen_notif_text,
|
||||
R.string.unlock_to_see_notif_text,
|
||||
R.drawable.ic_friction_lock_closed);
|
||||
} else {
|
||||
updateEmptyShadeView(R.string.empty_shade_text, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateEmptyShadeView(
|
||||
@StringRes int newTextRes,
|
||||
@StringRes int newFooterTextRes,
|
||||
@DrawableRes int newFooterIconRes) {
|
||||
int oldTextRes = mEmptyShadeView.getTextResource();
|
||||
int newTextRes = areNotificationsHiddenInShade
|
||||
? R.string.dnd_suppressing_shade_text : R.string.empty_shade_text;
|
||||
if (oldTextRes != newTextRes) {
|
||||
mEmptyShadeView.setText(newTextRes);
|
||||
}
|
||||
int oldFooterTextRes = mEmptyShadeView.getFooterTextResource();
|
||||
if (oldFooterTextRes != newFooterTextRes) {
|
||||
mEmptyShadeView.setFooterText(newFooterTextRes);
|
||||
}
|
||||
int oldFooterIconRes = mEmptyShadeView.getFooterIconResource();
|
||||
if (oldFooterIconRes != newFooterIconRes) {
|
||||
mEmptyShadeView.setFooterIcon(newFooterIconRes);
|
||||
}
|
||||
if (newFooterIconRes != 0 || newFooterTextRes != 0) {
|
||||
mEmptyShadeView.setFooterVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mEmptyShadeView.setFooterVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEmptyShadeViewVisible() {
|
||||
@@ -5348,9 +5378,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
|
||||
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
||||
private void inflateEmptyShadeView() {
|
||||
EmptyShadeView oldView = mEmptyShadeView;
|
||||
EmptyShadeView view = (EmptyShadeView) LayoutInflater.from(mContext).inflate(
|
||||
R.layout.status_bar_no_notifications, this, false);
|
||||
view.setText(R.string.empty_shade_text);
|
||||
view.setOnClickListener(v -> {
|
||||
final boolean showHistory = mController.isHistoryEnabled();
|
||||
Intent intent = showHistory
|
||||
@@ -5359,6 +5389,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
mCentralSurfaces.startActivity(intent, true, true, Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
});
|
||||
setEmptyShadeView(view);
|
||||
updateEmptyShadeView(
|
||||
oldView == null ? R.string.empty_shade_text : oldView.getTextResource(),
|
||||
oldView == null ? 0 : oldView.getFooterTextResource(),
|
||||
oldView == null ? 0 : oldView.getFooterIconResource());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -81,6 +81,7 @@ import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.SysuiStatusBarStateController;
|
||||
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
|
||||
import com.android.systemui.statusbar.notification.LaunchAnimationParameters;
|
||||
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
||||
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
|
||||
import com.android.systemui.statusbar.notification.collection.NotifCollection;
|
||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||
@@ -89,6 +90,7 @@ import com.android.systemui.statusbar.notification.collection.PipelineDumpable;
|
||||
import com.android.systemui.statusbar.notification.collection.PipelineDumper;
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
|
||||
import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProvider;
|
||||
import com.android.systemui.statusbar.notification.collection.provider.VisibilityLocationProviderDelegator;
|
||||
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotifStackController;
|
||||
@@ -174,6 +176,8 @@ public class NotificationStackScrollLayoutController {
|
||||
private final StackStateLogger mStackStateLogger;
|
||||
private final NotificationStackScrollLogger mLogger;
|
||||
private final GroupExpansionManager mGroupExpansionManager;
|
||||
private final NotifPipelineFlags mNotifPipelineFlags;
|
||||
private final SeenNotificationsProvider mSeenNotificationsProvider;
|
||||
|
||||
private NotificationStackScrollLayout mView;
|
||||
private boolean mFadeNotificationsOnDismiss;
|
||||
@@ -639,12 +643,14 @@ public class NotificationStackScrollLayoutController {
|
||||
GroupExpansionManager groupManager,
|
||||
@SilentHeader SectionHeaderController silentHeaderController,
|
||||
NotifPipeline notifPipeline,
|
||||
NotifPipelineFlags notifPipelineFlags,
|
||||
NotifCollection notifCollection,
|
||||
LockscreenShadeTransitionController lockscreenShadeTransitionController,
|
||||
ShadeTransitionController shadeTransitionController,
|
||||
UiEventLogger uiEventLogger,
|
||||
NotificationRemoteInputManager remoteInputManager,
|
||||
VisibilityLocationProviderDelegator visibilityLocationProviderDelegator,
|
||||
SeenNotificationsProvider seenNotificationsProvider,
|
||||
ShadeController shadeController,
|
||||
InteractionJankMonitor jankMonitor,
|
||||
StackStateLogger stackLogger,
|
||||
@@ -683,10 +689,12 @@ public class NotificationStackScrollLayoutController {
|
||||
mGroupExpansionManager = groupManager;
|
||||
mSilentHeaderController = silentHeaderController;
|
||||
mNotifPipeline = notifPipeline;
|
||||
mNotifPipelineFlags = notifPipelineFlags;
|
||||
mNotifCollection = notifCollection;
|
||||
mUiEventLogger = uiEventLogger;
|
||||
mRemoteInputManager = remoteInputManager;
|
||||
mVisibilityLocationProviderDelegator = visibilityLocationProviderDelegator;
|
||||
mSeenNotificationsProvider = seenNotificationsProvider;
|
||||
mShadeController = shadeController;
|
||||
mFeatureFlags = featureFlags;
|
||||
mNotificationTargetsHelper = notificationTargetsHelper;
|
||||
@@ -1212,7 +1220,11 @@ public class NotificationStackScrollLayoutController {
|
||||
// For more details, see: b/228790482
|
||||
&& !isInTransitionToKeyguard();
|
||||
|
||||
mView.updateEmptyShadeView(shouldShow, mZenModeController.areNotificationsHiddenInShade());
|
||||
mView.updateEmptyShadeView(
|
||||
shouldShow,
|
||||
mZenModeController.areNotificationsHiddenInShade(),
|
||||
mNotifPipelineFlags.getShouldFilterUnseenNotifsOnKeyguard()
|
||||
&& mSeenNotificationsProvider.getHasFilteredOutSeenNotifications());
|
||||
|
||||
Trace.endSection();
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntryB
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
|
||||
import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
|
||||
import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProvider
|
||||
import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderImpl
|
||||
import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider
|
||||
import com.android.systemui.util.mockito.eq
|
||||
import com.android.systemui.util.mockito.mock
|
||||
@@ -102,6 +104,31 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun unseenFilterUpdatesSeenProviderWhenSuppressing() {
|
||||
whenever(notifPipelineFlags.shouldFilterUnseenNotifsOnKeyguard).thenReturn(true)
|
||||
|
||||
// GIVEN: Keyguard is not showing, and a notification is present
|
||||
keyguardRepository.setKeyguardShowing(false)
|
||||
runKeyguardCoordinatorTest {
|
||||
val fakeEntry = NotificationEntryBuilder().build()
|
||||
collectionListener.onEntryAdded(fakeEntry)
|
||||
|
||||
// WHEN: The keyguard is now showing
|
||||
keyguardRepository.setKeyguardShowing(true)
|
||||
testScheduler.runCurrent()
|
||||
|
||||
// THEN: The notification is recognized as "seen" and is filtered out.
|
||||
assertThat(unseenFilter.shouldFilterOut(fakeEntry, 0L)).isTrue()
|
||||
|
||||
// WHEN: The filter is cleaned up
|
||||
unseenFilter.onCleanup()
|
||||
|
||||
// THEN: The SeenNotificationProvider has been updated to reflect the suppression
|
||||
assertThat(seenNotificationsProvider.hasFilteredOutSeenNotifications).isTrue()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun unseenFilterAllowsNewNotif() {
|
||||
whenever(notifPipelineFlags.shouldFilterUnseenNotifsOnKeyguard).thenReturn(true)
|
||||
@@ -204,6 +231,7 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
|
||||
testBlock: suspend KeyguardCoordinatorTestScope.() -> Unit
|
||||
) {
|
||||
val testScope = TestScope(UnconfinedTestDispatcher())
|
||||
val seenNotificationsProvider = SeenNotificationsProviderImpl()
|
||||
val keyguardCoordinator =
|
||||
KeyguardCoordinator(
|
||||
keyguardNotifVisibilityProvider,
|
||||
@@ -211,18 +239,20 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
|
||||
notifPipelineFlags,
|
||||
testScope.backgroundScope,
|
||||
sectionHeaderVisibilityProvider,
|
||||
seenNotificationsProvider,
|
||||
statusBarStateController,
|
||||
)
|
||||
keyguardCoordinator.attach(notifPipeline)
|
||||
KeyguardCoordinatorTestScope(keyguardCoordinator, testScope).run {
|
||||
testScheduler.advanceUntilIdle()
|
||||
testScope.runTest(dispatchTimeoutMs = 1.seconds.inWholeMilliseconds) { testBlock() }
|
||||
testScope.runTest(dispatchTimeoutMs = 1.seconds.inWholeMilliseconds) {
|
||||
KeyguardCoordinatorTestScope(keyguardCoordinator, testScope, seenNotificationsProvider)
|
||||
.testBlock()
|
||||
}
|
||||
}
|
||||
|
||||
private inner class KeyguardCoordinatorTestScope(
|
||||
private val keyguardCoordinator: KeyguardCoordinator,
|
||||
private val scope: TestScope,
|
||||
val seenNotificationsProvider: SeenNotificationsProvider,
|
||||
) : CoroutineScope by scope {
|
||||
val testScheduler: TestCoroutineScheduler
|
||||
get() = scope.testScheduler
|
||||
|
||||
@@ -59,8 +59,10 @@ import com.android.systemui.statusbar.NotificationRemoteInputManager;
|
||||
import com.android.systemui.statusbar.RemoteInputController;
|
||||
import com.android.systemui.statusbar.SysuiStatusBarStateController;
|
||||
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
|
||||
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
||||
import com.android.systemui.statusbar.notification.collection.NotifCollection;
|
||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||
import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderImpl;
|
||||
import com.android.systemui.statusbar.notification.collection.provider.VisibilityLocationProviderDelegator;
|
||||
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
@@ -119,6 +121,7 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
|
||||
@Mock private GroupExpansionManager mGroupExpansionManager;
|
||||
@Mock private SectionHeaderController mSilentHeaderController;
|
||||
@Mock private NotifPipeline mNotifPipeline;
|
||||
@Mock private NotifPipelineFlags mNotifPipelineFlags;
|
||||
@Mock private NotifCollection mNotifCollection;
|
||||
@Mock private UiEventLogger mUiEventLogger;
|
||||
@Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
|
||||
@@ -170,12 +173,14 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
|
||||
mGroupExpansionManager,
|
||||
mSilentHeaderController,
|
||||
mNotifPipeline,
|
||||
mNotifPipelineFlags,
|
||||
mNotifCollection,
|
||||
mLockscreenShadeTransitionController,
|
||||
mShadeTransitionController,
|
||||
mUiEventLogger,
|
||||
mRemoteInputManager,
|
||||
mVisibilityLocationProviderDelegator,
|
||||
new SeenNotificationsProviderImpl(),
|
||||
mShadeController,
|
||||
mJankMonitor,
|
||||
mStackLogger,
|
||||
@@ -228,14 +233,16 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
|
||||
mController.updateShowEmptyShadeView();
|
||||
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
|
||||
/* visible= */ true,
|
||||
/* notifVisibleInShade= */ true);
|
||||
/* notifVisibleInShade= */ true,
|
||||
/* areSeenNotifsFiltered= */false);
|
||||
|
||||
setupShowEmptyShadeViewState(false);
|
||||
reset(mNotificationStackScrollLayout);
|
||||
mController.updateShowEmptyShadeView();
|
||||
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
|
||||
/* visible= */ false,
|
||||
/* notifVisibleInShade= */ true);
|
||||
/* notifVisibleInShade= */ true,
|
||||
/* areSeenNotifsFiltered= */false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -248,14 +255,16 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
|
||||
mController.updateShowEmptyShadeView();
|
||||
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
|
||||
/* visible= */ true,
|
||||
/* notifVisibleInShade= */ false);
|
||||
/* notifVisibleInShade= */ false,
|
||||
/* areSeenNotifsFiltered= */false);
|
||||
|
||||
setupShowEmptyShadeViewState(false);
|
||||
reset(mNotificationStackScrollLayout);
|
||||
mController.updateShowEmptyShadeView();
|
||||
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
|
||||
/* visible= */ false,
|
||||
/* notifVisibleInShade= */ false);
|
||||
/* notifVisibleInShade= */ false,
|
||||
/* areSeenNotifsFiltered= */false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -274,14 +283,16 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
|
||||
mController.updateShowEmptyShadeView();
|
||||
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
|
||||
/* visible= */ true,
|
||||
/* notifVisibleInShade= */ false);
|
||||
/* notifVisibleInShade= */ false,
|
||||
/* areSeenNotifsFiltered= */false);
|
||||
|
||||
mController.setQsFullScreen(true);
|
||||
reset(mNotificationStackScrollLayout);
|
||||
mController.updateShowEmptyShadeView();
|
||||
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
|
||||
/* visible= */ true,
|
||||
/* notifVisibleInShade= */ false);
|
||||
/* notifVisibleInShade= */ false,
|
||||
/* areSeenNotifsFiltered= */false);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -324,7 +324,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
|
||||
public void updateEmptyView_dndSuppressing() {
|
||||
when(mEmptyShadeView.willBeGone()).thenReturn(true);
|
||||
|
||||
mStackScroller.updateEmptyShadeView(true, true);
|
||||
mStackScroller.updateEmptyShadeView(true, true, false);
|
||||
|
||||
verify(mEmptyShadeView).setText(R.string.dnd_suppressing_shade_text);
|
||||
}
|
||||
@@ -334,7 +334,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
|
||||
mStackScroller.setEmptyShadeView(mEmptyShadeView);
|
||||
when(mEmptyShadeView.willBeGone()).thenReturn(true);
|
||||
|
||||
mStackScroller.updateEmptyShadeView(true, false);
|
||||
mStackScroller.updateEmptyShadeView(true, false, false);
|
||||
|
||||
verify(mEmptyShadeView).setText(R.string.empty_shade_text);
|
||||
}
|
||||
@@ -343,10 +343,10 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
|
||||
public void updateEmptyView_noNotificationsToDndSuppressing() {
|
||||
mStackScroller.setEmptyShadeView(mEmptyShadeView);
|
||||
when(mEmptyShadeView.willBeGone()).thenReturn(true);
|
||||
mStackScroller.updateEmptyShadeView(true, false);
|
||||
mStackScroller.updateEmptyShadeView(true, false, false);
|
||||
verify(mEmptyShadeView).setText(R.string.empty_shade_text);
|
||||
|
||||
mStackScroller.updateEmptyShadeView(true, true);
|
||||
mStackScroller.updateEmptyShadeView(true, true, false);
|
||||
verify(mEmptyShadeView).setText(R.string.dnd_suppressing_shade_text);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user