From a75676fdfb1befd1483381bbfecd213f315e3624 Mon Sep 17 00:00:00 2001 From: Jeff DeCew Date: Sun, 6 Feb 2022 13:36:23 +0000 Subject: [PATCH 1/2] New Pipeline: various migrations Test: manual Fixes: 218105121 Fixes: 218095046 Fixes: 218095049 Bug: 218105118 Bug: 218105357 Bug: 218099854 Change-Id: I79023e91d4346579491fb8c8eb228998cb166927 --- .../systemui/media/MediaCarouselController.kt | 22 ++++++----- .../media/dialog/MediaOutputController.java | 13 +++---- .../media/dialog/MediaOutputDialogFactory.kt | 6 +-- .../widget/PeopleSpaceWidgetManager.java | 21 ++++------ .../statusbar/NotificationListener.java | 4 +- .../NotificationEntryManager.java | 5 +++ .../collection/NotifCollection.java | 6 +++ .../notification/collection/NotifPipeline.kt | 4 ++ .../collection/ShadeListBuilder.java | 1 + .../VisualStabilityCoordinator.java | 11 +++--- .../legacy/VisualStabilityManager.java | 5 +++ .../CommonNotifCollection.java | 5 +++ .../provider/VisualStabilityProvider.kt | 27 +++++++++++++ .../dagger/NotificationsModule.java | 3 ++ .../people/PeopleHubNotificationListener.kt | 30 +++++--------- .../notification/row/FeedbackInfo.java | 3 -- .../policy/RemoteInputUriController.java | 16 ++++---- .../android/systemui/tv/TvSystemUIModule.java | 4 +- .../media/MediaCarouselControllerTest.kt | 8 ++-- .../dialog/MediaOutputControllerTest.java | 24 +++++------- .../widget/PeopleSpaceWidgetManagerTest.java | 39 ++++++++----------- .../VisualStabilityManagerTest.java | 3 ++ .../VisualStabilityCoordinatorTest.java | 3 ++ 23 files changed, 149 insertions(+), 114 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProvider.kt diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt index f893f363b4c81..ecaa142f8a095 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt @@ -23,7 +23,8 @@ import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.FalsingManager import com.android.systemui.qs.PageIndicator import com.android.systemui.shared.system.SysUiStatsLog -import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager +import com.android.systemui.statusbar.notification.collection.provider.OnReorderingAllowedListener +import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.util.Utils import com.android.systemui.util.animation.UniqueObjectHostView @@ -48,7 +49,7 @@ private val DEBUG = Log.isLoggable(TAG, Log.DEBUG) class MediaCarouselController @Inject constructor( private val context: Context, private val mediaControlPanelFactory: Provider, - private val visualStabilityManager: VisualStabilityManager, + private val visualStabilityProvider: VisualStabilityProvider, private val mediaHostStatesManager: MediaHostStatesManager, private val activityStarter: ActivityStarter, private val systemClock: SystemClock, @@ -121,7 +122,7 @@ class MediaCarouselController @Inject constructor( private lateinit var settingsButton: View private val mediaContent: ViewGroup private val pageIndicator: PageIndicator - private val visualStabilityCallback: VisualStabilityManager.Callback + private val visualStabilityCallback: OnReorderingAllowedListener private var needsReordering: Boolean = false private var keysNeedRemoval = mutableSetOf() private var bgColor = getBackgroundColor() @@ -172,6 +173,9 @@ class MediaCarouselController @Inject constructor( */ lateinit var updateUserVisibility: () -> Unit + private val isReorderingAllowed: Boolean + get() = visualStabilityProvider.isReorderingAllowed + init { dumpManager.registerDumpable(TAG, this) mediaFrame = inflateMediaCarousel() @@ -184,8 +188,7 @@ class MediaCarouselController @Inject constructor( inflateSettingsButton() mediaContent = mediaCarousel.requireViewById(R.id.media_carousel) configurationController.addCallback(configListener) - // TODO (b/162832756): remove visual stability manager when migrating to new pipeline - visualStabilityCallback = VisualStabilityManager.Callback { + visualStabilityCallback = OnReorderingAllowedListener { if (needsReordering) { needsReordering = false reorderAllPlayers(previousVisiblePlayerKey = null) @@ -203,8 +206,7 @@ class MediaCarouselController @Inject constructor( // Let's reset our scroll position mediaCarouselScrollHandler.scrollToStart() } - visualStabilityManager.addReorderingAllowedCallback(visualStabilityCallback, - true /* persistent */) + visualStabilityProvider.addPersistentReorderingAllowedListener(visualStabilityCallback) mediaManager.addListener(object : MediaDataManager.Listener { override fun onMediaDataLoaded( key: String, @@ -266,7 +268,7 @@ class MediaCarouselController @Inject constructor( // This view isn't playing, let's remove this! This happens e.g when // dismissing/timing out a view. We still have the data around because // resumption could be on, but we should save the resources and release this. - if (visualStabilityManager.isReorderingAllowed) { + if (isReorderingAllowed) { onMediaDataRemoved(key) } else { keysNeedRemoval.add(key) @@ -336,7 +338,7 @@ class MediaCarouselController @Inject constructor( override fun onSmartspaceMediaDataRemoved(key: String, immediately: Boolean) { if (DEBUG) Log.d(TAG, "My Smartspace media removal request is received") - if (immediately || visualStabilityManager.isReorderingAllowed) { + if (immediately || isReorderingAllowed) { onMediaDataRemoved(key) } else { keysNeedRemoval.add(key) @@ -438,7 +440,7 @@ class MediaCarouselController @Inject constructor( } else { existingPlayer.bindPlayer(data, key) MediaPlayerData.addMediaPlayer(key, data, existingPlayer, systemClock) - if (visualStabilityManager.isReorderingAllowed || shouldScrollToActivePlayer) { + if (isReorderingAllowed || shouldScrollToActivePlayer) { reorderAllPlayers(curVisibleMediaKey) } else { needsReordering = true diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java index 83d581fb7897a..2caecf2aec912 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java @@ -58,8 +58,8 @@ import com.android.settingslib.utils.ThreadUtils; import com.android.systemui.R; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.plugins.ActivityStarter; -import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.SystemUIDialogManager; @@ -90,7 +90,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback { private final List mGroupMediaDevices = new CopyOnWriteArrayList<>(); private final boolean mAboveStatusbar; private final boolean mVolumeAdjustmentForRemoteGroupSessions; - private final NotificationEntryManager mNotificationEntryManager; + private final CommonNotifCollection mNotifCollection; @VisibleForTesting final List mMediaDevices = new CopyOnWriteArrayList<>(); @@ -107,7 +107,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback { public MediaOutputController(@NonNull Context context, String packageName, boolean aboveStatusbar, MediaSessionManager mediaSessionManager, LocalBluetoothManager lbm, ShadeController shadeController, ActivityStarter starter, - NotificationEntryManager notificationEntryManager, UiEventLogger uiEventLogger, + CommonNotifCollection notifCollection, UiEventLogger uiEventLogger, DialogLaunchAnimator dialogLaunchAnimator, SystemUIDialogManager dialogManager) { mContext = context; mPackageName = packageName; @@ -116,7 +116,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback { mShadeController = shadeController; mActivityStarter = starter; mAboveStatusbar = aboveStatusbar; - mNotificationEntryManager = notificationEntryManager; + mNotifCollection = notifCollection; InfoMediaManager imm = new InfoMediaManager(mContext, packageName, null, lbm); mLocalMediaManager = new LocalMediaManager(mContext, lbm, imm, packageName); mMetricLogger = new MediaOutputMetricLogger(mContext, mPackageName); @@ -287,8 +287,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback { if (TextUtils.isEmpty(mPackageName)) { return null; } - for (NotificationEntry entry - : mNotificationEntryManager.getActiveNotificationsForCurrentUser()) { + for (NotificationEntry entry : mNotifCollection.getAllNotifs()) { final Notification notification = entry.getSbn().getNotification(); if (notification.isMediaNotification() && TextUtils.equals(entry.getSbn().getPackageName(), mPackageName)) { @@ -523,7 +522,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback { // We show the output group dialog from the output dialog. MediaOutputController controller = new MediaOutputController(mContext, mPackageName, mAboveStatusbar, mMediaSessionManager, mLocalBluetoothManager, mShadeController, - mActivityStarter, mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator, + mActivityStarter, mNotifCollection, mUiEventLogger, mDialogLaunchAnimator, mDialogManager); MediaOutputGroupDialog dialog = new MediaOutputGroupDialog(mContext, mAboveStatusbar, controller, mDialogManager); diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt index a7bc85256fcda..e1e7fa3ebbe0e 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt @@ -23,7 +23,7 @@ import com.android.internal.logging.UiEventLogger import com.android.settingslib.bluetooth.LocalBluetoothManager import com.android.systemui.animation.DialogLaunchAnimator import com.android.systemui.plugins.ActivityStarter -import com.android.systemui.statusbar.notification.NotificationEntryManager +import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection import com.android.systemui.statusbar.phone.ShadeController import com.android.systemui.statusbar.phone.SystemUIDialogManager import javax.inject.Inject @@ -37,7 +37,7 @@ class MediaOutputDialogFactory @Inject constructor( private val lbm: LocalBluetoothManager?, private val shadeController: ShadeController, private val starter: ActivityStarter, - private val notificationEntryManager: NotificationEntryManager, + private val notifCollection: CommonNotifCollection, private val uiEventLogger: UiEventLogger, private val dialogLaunchAnimator: DialogLaunchAnimator, private val dialogManager: SystemUIDialogManager @@ -52,7 +52,7 @@ class MediaOutputDialogFactory @Inject constructor( mediaOutputDialog?.dismiss() val controller = MediaOutputController(context, packageName, aboveStatusBar, - mediaSessionManager, lbm, shadeController, starter, notificationEntryManager, + mediaSessionManager, lbm, shadeController, starter, notifCollection, uiEventLogger, dialogLaunchAnimator, dialogManager) val dialog = MediaOutputDialog(context, aboveStatusBar, controller, uiEventLogger, dialogManager) diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java index 82a5aa04a0734..f6e1cd49eb402 100644 --- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java +++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java @@ -95,12 +95,13 @@ import com.android.systemui.people.PeopleTileViewHelper; import com.android.systemui.people.SharedPreferencesHelper; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationListener.NotificationHandler; -import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; import com.android.wm.shell.bubbles.Bubbles; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -129,7 +130,7 @@ public class PeopleSpaceWidgetManager { private IPeopleManager mIPeopleManager; private SharedPreferences mSharedPrefs; private PeopleManager mPeopleManager; - private NotificationEntryManager mNotificationEntryManager; + private CommonNotifCollection mNotifCollection; private PackageManager mPackageManager; private INotificationManager mINotificationManager; private Optional mBubblesOptional; @@ -156,7 +157,7 @@ public class PeopleSpaceWidgetManager { @Inject public PeopleSpaceWidgetManager(Context context, LauncherApps launcherApps, - NotificationEntryManager notificationEntryManager, + CommonNotifCollection notifCollection, PackageManager packageManager, Optional bubblesOptional, UserManager userManager, NotificationManager notificationManager, BroadcastDispatcher broadcastDispatcher, @Background Executor bgExecutor) { @@ -168,7 +169,7 @@ public class PeopleSpaceWidgetManager { mLauncherApps = launcherApps; mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(mContext); mPeopleManager = context.getSystemService(PeopleManager.class); - mNotificationEntryManager = notificationEntryManager; + mNotifCollection = notifCollection; mPackageManager = packageManager; mINotificationManager = INotificationManager.Stub.asInterface( ServiceManager.getService(Context.NOTIFICATION_SERVICE)); @@ -235,7 +236,7 @@ public class PeopleSpaceWidgetManager { PeopleSpaceWidgetManager(Context context, AppWidgetManager appWidgetManager, IPeopleManager iPeopleManager, PeopleManager peopleManager, LauncherApps launcherApps, - NotificationEntryManager notificationEntryManager, PackageManager packageManager, + CommonNotifCollection notifCollection, PackageManager packageManager, Optional bubblesOptional, UserManager userManager, BackupManager backupManager, INotificationManager iNotificationManager, NotificationManager notificationManager, @Background Executor executor) { @@ -244,7 +245,7 @@ public class PeopleSpaceWidgetManager { mIPeopleManager = iPeopleManager; mPeopleManager = peopleManager; mLauncherApps = launcherApps; - mNotificationEntryManager = notificationEntryManager; + mNotifCollection = notifCollection; mPackageManager = packageManager; mBubblesOptional = bubblesOptional; mUserManager = userManager; @@ -519,13 +520,7 @@ public class PeopleSpaceWidgetManager { /** Returns active and pending notifications grouped by {@link PeopleTileKey}. */ public Map> getGroupedConversationNotifications() { - List notifications = - new ArrayList<>(mNotificationEntryManager.getVisibleNotifications()); - Iterable pendingNotifications = - mNotificationEntryManager.getPendingNotificationsIterator(); - for (NotificationEntry entry : pendingNotifications) { - notifications.add(entry); - } + Collection notifications = mNotifCollection.getAllNotifs(); if (DEBUG) Log.d(TAG, "Number of total notifications: " + notifications.size()); Map> groupedNotifications = notifications diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java index d6125ce7aa65c..e19fd7a44394a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java @@ -17,7 +17,6 @@ package com.android.systemui.statusbar; import static com.android.systemui.statusbar.RemoteInputController.processForRemoteInput; -import static com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON; import android.annotation.NonNull; import android.annotation.SuppressLint; @@ -32,6 +31,7 @@ import android.util.Log; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.statusbar.dagger.StatusBarModule; +import com.android.systemui.statusbar.notification.collection.NotifCollection; import com.android.systemui.statusbar.phone.NotificationListenerWithPlugins; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.util.time.SystemClock; @@ -155,7 +155,7 @@ public class NotificationListener extends NotificationListenerWithPlugins { @Override public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) { - onNotificationRemoved(sbn, rankingMap, UNDEFINED_DISMISS_REASON); + onNotificationRemoved(sbn, rankingMap, NotifCollection.REASON_UNKNOWN); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java index ad9f12ec3bc09..f97b936605f68 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java @@ -1043,6 +1043,11 @@ public class NotificationEntryManager implements mNotifCollectionListeners.add(listener); } + @Override + public void removeCollectionListener(@NonNull NotifCollectionListener listener) { + mNotifCollectionListeners.remove(listener); + } + /* * End annexation * ----- diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java index 2a2cc81c32232..9be032dc1240a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java @@ -213,6 +213,12 @@ public class NotifCollection implements Dumpable { mNotifCollectionListeners.add(listener); } + /** @see NotifPipeline#removeCollectionListener(NotifCollectionListener) */ + void removeCollectionListener(NotifCollectionListener listener) { + Assert.isMainThread(); + mNotifCollectionListeners.remove(listener); + } + /** @see NotifPipeline#addNotificationLifetimeExtender(NotifLifetimeExtender) */ void addNotificationLifetimeExtender(NotifLifetimeExtender extender) { Assert.isMainThread(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt index 5ada7a82f8fea..2009b522482ed 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt @@ -94,6 +94,10 @@ class NotifPipeline @Inject constructor( mNotifCollection.addCollectionListener(listener) } + override fun removeCollectionListener(listener: NotifCollectionListener) { + mNotifCollection.removeCollectionListener(listener) + } + /** * Returns the NotificationEntry associated with [key]. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java index b328ae8cd0bb2..c850a94dcd75b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java @@ -147,6 +147,7 @@ public class ShadeListBuilder implements Dumpable { */ public void attach(NotifCollection collection) { Assert.isMainThread(); + collection.addCollectionListener(mInteractionTracker); collection.setBuildListener(mReadyForBuildListener); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java index fcc2b266dce21..3aa3549a7c273 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java @@ -27,11 +27,11 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.plugins.statusbar.StatusBarStateController; -import com.android.systemui.statusbar.NotificationViewHierarchyManager; import com.android.systemui.statusbar.notification.collection.ListEntry; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifStabilityManager; +import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider; import com.android.systemui.statusbar.notification.collection.render.NotifPanelEventSource; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.util.concurrency.DelayableExecutor; @@ -49,11 +49,6 @@ import javax.inject.Inject; * Ensures that notifications are visually stable if the user is looking at the notifications. * Group and section changes are re-allowed when the notification entries are no longer being * viewed. - * - * Previously this was implemented in the view-layer {@link NotificationViewHierarchyManager} by - * {@link com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager}. - * This is now integrated in the data-layer via - * {@link com.android.systemui.statusbar.notification.collection.ShadeListBuilder}. */ // TODO(b/204468557): Move to @CoordinatorScope @SysUISingleton @@ -63,6 +58,7 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable, private final HeadsUpManager mHeadsUpManager; private final NotifPanelEventSource mNotifPanelEventSource; private final StatusBarStateController mStatusBarStateController; + private final VisualStabilityProvider mVisualStabilityProvider; private final WakefulnessLifecycle mWakefulnessLifecycle; private boolean mScreenOn; @@ -93,8 +89,10 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable, HeadsUpManager headsUpManager, NotifPanelEventSource notifPanelEventSource, StatusBarStateController statusBarStateController, + VisualStabilityProvider visualStabilityProvider, WakefulnessLifecycle wakefulnessLifecycle) { mHeadsUpManager = headsUpManager; + mVisualStabilityProvider = visualStabilityProvider; mWakefulnessLifecycle = wakefulnessLifecycle; mStatusBarStateController = statusBarStateController; mDelayableExecutor = delayableExecutor; @@ -178,6 +176,7 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable, || mIsSuppressingEntryReorder))) { mNotifStabilityManager.invalidateList(); } + mVisualStabilityProvider.setReorderingAllowed(mReorderingAllowed); } private boolean isSuppressingSectionChange() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/VisualStabilityManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/VisualStabilityManager.java index 6e47c7bdf9272..e921ea181f2e3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/VisualStabilityManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/VisualStabilityManager.java @@ -31,6 +31,7 @@ import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.VisibilityLocationProvider; import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider; import com.android.systemui.statusbar.notification.dagger.NotificationsModule; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; @@ -52,6 +53,7 @@ public class VisualStabilityManager implements OnHeadsUpChangedListener, Dumpabl private final ArrayList mGroupChangesAllowedCallbacks = new ArrayList<>(); private final ArraySet mPersistentGroupCallbacks = new ArraySet<>(); private final Handler mHandler; + private final VisualStabilityProvider mVisualStabilityProvider; private boolean mPanelExpanded; private boolean mScreenOn; @@ -70,11 +72,13 @@ public class VisualStabilityManager implements OnHeadsUpChangedListener, Dumpabl */ public VisualStabilityManager( NotificationEntryManager notificationEntryManager, + VisualStabilityProvider visualStabilityProvider, @Main Handler handler, StatusBarStateController statusBarStateController, WakefulnessLifecycle wakefulnessLifecycle, DumpManager dumpManager) { + mVisualStabilityProvider = visualStabilityProvider; mHandler = handler; dumpManager.registerDumpable(this); @@ -181,6 +185,7 @@ public class VisualStabilityManager implements OnHeadsUpChangedListener, Dumpabl if (changedToTrue) { notifyChangeAllowed(mReorderingAllowedCallbacks, mPersistentReorderingCallbacks); } + mVisualStabilityProvider.setReorderingAllowed(reorderingAllowed); boolean groupChangesAllowed = (!mScreenOn || !mPanelExpanded) && !mPulsing; changedToTrue = groupChangesAllowed && !mGroupChangedAllowed; mGroupChangedAllowed = groupChangesAllowed; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/CommonNotifCollection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/CommonNotifCollection.java index beaa1ba52ddf1..4ff6a64e0df86 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/CommonNotifCollection.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/CommonNotifCollection.java @@ -40,6 +40,11 @@ public interface CommonNotifCollection { */ void addCollectionListener(@NonNull NotifCollectionListener listener); + /** + * Unregisters a listener previously added with {@link #addCollectionListener} + */ + void removeCollectionListener(@NonNull NotifCollectionListener listener); + /** * Returns the list of all known notifications, i.e. the notifications that are currently posted * to the phone. In general, this tracks closely to the list maintained by NotificationManager, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProvider.kt new file mode 100644 index 0000000000000..3f866fe63f1de --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProvider.kt @@ -0,0 +1,27 @@ +package com.android.systemui.statusbar.notification.collection.provider + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.util.ListenerSet +import javax.inject.Inject + +@SysUISingleton +class VisualStabilityProvider @Inject constructor() { + private val listeners = ListenerSet() + + var isReorderingAllowed = true + set(value) { + if (field != value) { + field = value + if (value) { + listeners.forEach(OnReorderingAllowedListener::onReorderingAllowed) + } + } + } + + fun addPersistentReorderingAllowedListener(listener: OnReorderingAllowedListener) = + listeners.addIfAbsent(listener) +} + +fun interface OnReorderingAllowedListener { + fun onReorderingAllowed() +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java index 45a9092068e43..fedc858f407c5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java @@ -62,6 +62,7 @@ import com.android.systemui.statusbar.notification.collection.legacy.VisualStabi 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.VisualStabilityProvider; import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager; import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManagerImpl; import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; @@ -200,12 +201,14 @@ public interface NotificationsModule { @Provides static VisualStabilityManager provideVisualStabilityManager( NotificationEntryManager notificationEntryManager, + VisualStabilityProvider visualStabilityProvider, Handler handler, StatusBarStateController statusBarStateController, WakefulnessLifecycle wakefulnessLifecycle, DumpManager dumpManager) { return new VisualStabilityManager( notificationEntryManager, + visualStabilityProvider, handler, statusBarStateController, wakefulnessLifecycle, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt index cd9ba4e690e92..6062941d44a6e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt @@ -31,7 +31,6 @@ import android.util.SparseArray import android.view.View import android.view.ViewGroup import android.widget.ImageView -import com.android.internal.statusbar.NotificationVisibility import com.android.internal.widget.MessagingGroup import com.android.settingslib.notification.ConversationIconFactory import com.android.systemui.R @@ -41,9 +40,9 @@ import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.plugins.NotificationPersonExtractorPlugin import com.android.systemui.statusbar.NotificationListener import com.android.systemui.statusbar.NotificationLockscreenUserManager -import com.android.systemui.statusbar.notification.NotificationEntryListener -import com.android.systemui.statusbar.notification.NotificationEntryManager import com.android.systemui.statusbar.notification.collection.NotificationEntry +import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection +import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_NON_PERSON import com.android.systemui.statusbar.policy.ExtensionController import java.util.ArrayDeque @@ -89,7 +88,7 @@ class NotificationPersonExtractorPluginBoundary @Inject constructor( @SysUISingleton class PeopleHubDataSourceImpl @Inject constructor( - private val notificationEntryManager: NotificationEntryManager, + private val notifCollection: CommonNotifCollection, private val extractor: NotificationPersonExtractor, private val userManager: UserManager, launcherApps: LauncherApps, @@ -119,19 +118,11 @@ class PeopleHubDataSourceImpl @Inject constructor( ) } - private val notificationEntryListener = object : NotificationEntryListener { - override fun onEntryInflated(entry: NotificationEntry) = addVisibleEntry(entry) - - override fun onEntryReinflated(entry: NotificationEntry) = addVisibleEntry(entry) - - override fun onPostEntryUpdated(entry: NotificationEntry) = addVisibleEntry(entry) - - override fun onEntryRemoved( - entry: NotificationEntry, - visibility: NotificationVisibility?, - removedByUser: Boolean, - reason: Int - ) = removeVisibleEntry(entry, reason) + private val notifCollectionListener = object : NotifCollectionListener { + override fun onEntryAdded(entry: NotificationEntry) = addVisibleEntry(entry) + override fun onEntryUpdated(entry: NotificationEntry) = addVisibleEntry(entry) + override fun onEntryRemoved(entry: NotificationEntry, reason: Int) = + removeVisibleEntry(entry, reason) } private fun removeVisibleEntry(entry: NotificationEntry, reason: Int) { @@ -179,7 +170,7 @@ class PeopleHubDataSourceImpl @Inject constructor( currentProfiles: SparseArray? ) = updateUi() }) - notificationEntryManager.addNotificationEntryListener(notificationEntryListener) + notifCollection.addCollectionListener(notifCollectionListener) } else { getPeopleHubModelForCurrentUser()?.let(listener::onDataChanged) } @@ -189,8 +180,7 @@ class PeopleHubDataSourceImpl @Inject constructor( if (dataListeners.isEmpty()) { userChangeSubscription?.unsubscribe() userChangeSubscription = null - notificationEntryManager - .removeNotificationEntryListener(notificationEntryListener) + notifCollection.removeCollectionListener(notifCollectionListener) } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java index 4893490b3e5c7..2b782b6e3917a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java @@ -46,7 +46,6 @@ import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.statusbar.notification.AssistantFeedbackController; -import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.util.Compile; @@ -62,7 +61,6 @@ public class FeedbackInfo extends LinearLayout implements NotificationGuts.GutsC private String mPkg; private NotificationEntry mEntry; - private NotificationEntryManager mNotificationEntryManager; private IStatusBarService mStatusBarService; private AssistantFeedbackController mFeedbackController; private NotificationGutsManager mNotificationGutsManager; @@ -86,7 +84,6 @@ public class FeedbackInfo extends LinearLayout implements NotificationGuts.GutsC mRanking = entry.getRanking(); mFeedbackController = controller; mAppName = mPkg; - mNotificationEntryManager = Dependency.get(NotificationEntryManager.class); mStatusBarService = Dependency.get(IStatusBarService.class); mNotificationGutsManager = Dependency.get(NotificationGutsManager.class); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputUriController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputUriController.java index 03b6122102c2f..554dbfb411dab 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputUriController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputUriController.java @@ -21,12 +21,13 @@ import android.os.RemoteException; import android.service.notification.StatusBarNotification; import android.util.Log; +import androidx.annotation.NonNull; + import com.android.internal.statusbar.IStatusBarService; -import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.dagger.SysUISingleton; -import com.android.systemui.statusbar.notification.NotificationEntryListener; -import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; +import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; import javax.inject.Inject; @@ -49,8 +50,8 @@ public class RemoteInputUriController { * that RemoteInput URI grants are cleaned up when the notification entry is removed from * the shade. */ - public void attach(NotificationEntryManager manager) { - manager.addNotificationEntryListener(mInlineUriListener); + public void attach(CommonNotifCollection manager) { + manager.addCollectionListener(mInlineUriListener); } /** @@ -70,10 +71,9 @@ public class RemoteInputUriController { * Ensures that inline URI permissions are cleared when notification entries are removed from * the shade. */ - private final NotificationEntryListener mInlineUriListener = new NotificationEntryListener() { + private final NotifCollectionListener mInlineUriListener = new NotifCollectionListener() { @Override - public void onEntryRemoved(NotificationEntry entry, NotificationVisibility visibility, - boolean removedByUser, int reason) { + public void onEntryRemoved(@NonNull NotificationEntry entry, int reason) { try { mStatusBarManagerService.clearInlineReplyUriPermissions(entry.getKey()); } catch (RemoteException ex) { diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java index 65518d6b3e47f..66fc9ac15857b 100644 --- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java @@ -50,7 +50,7 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.notification.NotificationEntryManager; -import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy; +import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; import com.android.systemui.statusbar.phone.DozeServiceHost; import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; import com.android.systemui.statusbar.phone.KeyguardBypassController; @@ -166,7 +166,7 @@ public abstract class TvSystemUIModule { HeadsUpManagerLogger headsUpManagerLogger, StatusBarStateController statusBarStateController, KeyguardBypassController bypassController, - NotificationGroupManagerLegacy groupManager, + GroupMembershipManager groupManager, ConfigurationController configurationController) { return new HeadsUpManagerPhone( context, diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt index d2be1f428a577..dcbe0ab96dac3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt @@ -25,7 +25,7 @@ import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.FalsingManager -import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager +import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.util.concurrency.DelayableExecutor import com.android.systemui.util.time.FakeSystemClock @@ -36,8 +36,8 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.MockitoAnnotations -import org.mockito.Mockito.`when` as whenever import javax.inject.Provider +import org.mockito.Mockito.`when` as whenever private val DATA = MediaData( userId = -1, @@ -66,7 +66,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { @Mock lateinit var mediaControlPanelFactory: Provider @Mock lateinit var panel: MediaControlPanel - @Mock lateinit var visualStabilityManager: VisualStabilityManager + @Mock lateinit var visualStabilityProvider: VisualStabilityProvider @Mock lateinit var mediaHostStatesManager: MediaHostStatesManager @Mock lateinit var activityStarter: ActivityStarter @Mock @Main private lateinit var executor: DelayableExecutor @@ -87,7 +87,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { mediaCarouselController = MediaCarouselController( context, mediaControlPanelFactory, - visualStabilityManager, + visualStabilityProvider, mediaHostStatesManager, activityStarter, clock, diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java index a84a8037d26df..05769875ae111 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java @@ -52,8 +52,8 @@ import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.plugins.ActivityStarter; -import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.SystemUIDialogManager; @@ -91,8 +91,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { private RoutingSessionInfo mRemoteSessionInfo = mock(RoutingSessionInfo.class); private ShadeController mShadeController = mock(ShadeController.class); private ActivityStarter mStarter = mock(ActivityStarter.class); - private NotificationEntryManager mNotificationEntryManager = - mock(NotificationEntryManager.class); + private CommonNotifCollection mNotifCollection = mock(CommonNotifCollection.class); private final UiEventLogger mUiEventLogger = mock(UiEventLogger.class); private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class); private final SystemUIDialogManager mDialogManager = mock(SystemUIDialogManager.class); @@ -118,7 +117,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { mMediaOutputController = new MediaOutputController(mSpyContext, TEST_PACKAGE_NAME, false, mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter, - mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator, mDialogManager); + mNotifCollection, mUiEventLogger, mDialogLaunchAnimator, mDialogManager); mLocalMediaManager = spy(mMediaOutputController.mLocalMediaManager); mMediaOutputController.mLocalMediaManager = mLocalMediaManager; MediaDescription.Builder builder = new MediaDescription.Builder(); @@ -162,7 +161,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { public void start_withoutPackageName_verifyMediaControllerInit() { mMediaOutputController = new MediaOutputController(mSpyContext, null, false, mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter, - mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator, mDialogManager); + mNotifCollection, mUiEventLogger, mDialogLaunchAnimator, mDialogManager); mMediaOutputController.start(mCb); @@ -183,7 +182,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { public void stop_withoutPackageName_verifyMediaControllerDeinit() { mMediaOutputController = new MediaOutputController(mSpyContext, null, false, mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter, - mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator, mDialogManager); + mNotifCollection, mUiEventLogger, mDialogLaunchAnimator, mDialogManager); mMediaOutputController.start(mCb); @@ -454,7 +453,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { public void getNotificationLargeIcon_withoutPackageName_returnsNull() { mMediaOutputController = new MediaOutputController(mSpyContext, null, false, mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter, - mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator, mDialogManager); + mNotifCollection, mUiEventLogger, mDialogLaunchAnimator, mDialogManager); assertThat(mMediaOutputController.getNotificationIcon()).isNull(); } @@ -467,8 +466,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { final Notification notification = mock(Notification.class); entryList.add(entry); - when(mNotificationEntryManager.getActiveNotificationsForCurrentUser()) - .thenReturn(entryList); + when(mNotifCollection.getAllNotifs()).thenReturn(entryList); when(entry.getSbn()).thenReturn(sbn); when(sbn.getNotification()).thenReturn(notification); when(sbn.getPackageName()).thenReturn(TEST_PACKAGE_NAME); @@ -487,15 +485,14 @@ public class MediaOutputControllerTest extends SysuiTestCase { final Icon icon = mock(Icon.class); entryList.add(entry); - when(mNotificationEntryManager.getActiveNotificationsForCurrentUser()) - .thenReturn(entryList); + when(mNotifCollection.getAllNotifs()).thenReturn(entryList); when(entry.getSbn()).thenReturn(sbn); when(sbn.getNotification()).thenReturn(notification); when(sbn.getPackageName()).thenReturn(TEST_PACKAGE_NAME); when(notification.isMediaNotification()).thenReturn(true); when(notification.getLargeIcon()).thenReturn(icon); - assertThat(mMediaOutputController.getNotificationIcon() instanceof IconCompat).isTrue(); + assertThat(mMediaOutputController.getNotificationIcon()).isInstanceOf(IconCompat.class); } @Test @@ -507,8 +504,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { final Icon icon = mock(Icon.class); entryList.add(entry); - when(mNotificationEntryManager.getActiveNotificationsForCurrentUser()) - .thenReturn(entryList); + when(mNotifCollection.getAllNotifs()).thenReturn(entryList); when(entry.getSbn()).thenReturn(sbn); when(sbn.getNotification()).thenReturn(notification); when(sbn.getPackageName()).thenReturn(TEST_PACKAGE_NAME); diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java index 24c189a853277..e0f27de1a6de6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java @@ -109,11 +109,11 @@ import com.android.systemui.people.SharedPreferencesHelper; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationListener.NotificationHandler; import com.android.systemui.statusbar.SbnBuilder; -import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NoManSimulator; import com.android.systemui.statusbar.notification.collection.NoManSimulator.NotifEvent; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; +import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; import com.android.wm.shell.bubbles.Bubbles; @@ -239,7 +239,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase { @Mock private LauncherApps mLauncherApps; @Mock - private NotificationEntryManager mNotificationEntryManager; + private CommonNotifCollection mNotifCollection; @Mock private PackageManager mPackageManager; @Mock @@ -269,9 +269,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase { public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mLauncherApps = mock(LauncherApps.class); - mDependency.injectTestDependency(NotificationEntryManager.class, mNotificationEntryManager); mManager = new PeopleSpaceWidgetManager(mContext, mAppWidgetManager, mIPeopleManager, - mPeopleManager, mLauncherApps, mNotificationEntryManager, mPackageManager, + mPeopleManager, mLauncherApps, mNotifCollection, mPackageManager, Optional.of(mBubbles), mUserManager, mBackupManager, mINotificationManager, mNotificationManager, mFakeExecutor); mManager.attach(mListenerService); @@ -633,7 +632,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase { .setShortcutInfo(mShortcutInfo) .setId(1); NotificationEntry entry = builder.build(); - when(mNotificationEntryManager.getVisibleNotifications()).thenReturn(List.of(entry)); + when(mNotifCollection.getAllNotifs()).thenReturn(List.of(entry)); NotifEvent notif1 = mNoMan.postNotif(builder); mClock.advanceTime(MIN_LINGER_DURATION); @@ -692,7 +691,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase { .setShortcutInfo(mShortcutInfo) .setId(1); NotificationEntry entry = builder.build(); - when(mNotificationEntryManager.getVisibleNotifications()).thenReturn(List.of(entry)); + when(mNotifCollection.getAllNotifs()).thenReturn(List.of(entry)); NotifEvent notif1 = mNoMan.postNotif(builder); mClock.advanceTime(MIN_LINGER_DURATION); @@ -716,7 +715,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase { .setShortcutInfo(mShortcutInfo) .setId(1); NotificationEntry entry = builder.build(); - when(mNotificationEntryManager.getVisibleNotifications()).thenReturn(List.of(entry)); + when(mNotifCollection.getAllNotifs()).thenReturn(List.of(entry)); NotifEvent notif1 = mNoMan.postNotif(builder); mClock.advanceTime(MIN_LINGER_DURATION); @@ -740,7 +739,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase { .setShortcutInfo(mShortcutInfo) .setId(1); NotificationEntry entry = builder.build(); - when(mNotificationEntryManager.getVisibleNotifications()).thenReturn(List.of(entry)); + when(mNotifCollection.getAllNotifs()).thenReturn(List.of(entry)); NotifEvent notif1 = mNoMan.postNotif(builder); mClock.advanceTime(MIN_LINGER_DURATION); @@ -771,12 +770,12 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase { .setId(1); NotificationEntry entry = builder.build(); - when(mNotificationEntryManager.getVisibleNotifications()).thenReturn(List.of(entry)); + when(mNotifCollection.getAllNotifs()).thenReturn(List.of(entry)); NotifEvent notif1 = mNoMan.postNotif(builder); mClock.advanceTime(MIN_LINGER_DURATION); - when(mNotificationEntryManager.getVisibleNotifications()).thenReturn(List.of()); + when(mNotifCollection.getAllNotifs()).thenReturn(List.of()); NotifEvent notif1b = mNoMan.retractNotif(notif1.sbn.cloneLight(), 0); mClock.advanceTime(MIN_LINGER_DURATION); @@ -814,7 +813,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase { .setSbn(sbn) .setId(1); NotificationEntry entry = builder.build(); - when(mNotificationEntryManager.getVisibleNotifications()).thenReturn(List.of(entry)); + when(mNotifCollection.getAllNotifs()).thenReturn(List.of(entry)); NotifEvent notif1 = mNoMan.postNotif(builder); mClock.advanceTime(MIN_LINGER_DURATION); @@ -858,7 +857,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase { .setShortcutInfo(mShortcutInfo) .setId(1); NotificationEntry entry = builder.build(); - when(mNotificationEntryManager.getVisibleNotifications()).thenReturn(List.of(entry)); + when(mNotifCollection.getAllNotifs()).thenReturn(List.of(entry)); NotifEvent notif1 = mNoMan.postNotif(builder); @@ -891,7 +890,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase { .setShortcutInfo(mShortcutInfo) .setId(1); NotificationEntry entry = builder.build(); - when(mNotificationEntryManager.getVisibleNotifications()).thenReturn(List.of(entry)); + when(mNotifCollection.getAllNotifs()).thenReturn(List.of(entry)); NotifEvent notif1 = mNoMan.postNotif(builder); mClock.advanceTime(MIN_LINGER_DURATION); @@ -922,7 +921,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase { .setShortcutInfo(mShortcutInfo) .setId(1); NotificationEntry entry = builder.build(); - when(mNotificationEntryManager.getVisibleNotifications()).thenReturn(List.of(entry)); + when(mNotifCollection.getAllNotifs()).thenReturn(List.of(entry)); NotifEvent notif1 = mNoMan.postNotif(builder); mClock.advanceTime(MIN_LINGER_DURATION); @@ -1215,8 +1214,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase { .setPackageName(TEST_PACKAGE_A) .setUserHandle(new UserHandle(0)) .build(); - when(mNotificationEntryManager.getVisibleNotifications()) - .thenReturn(List.of(mNotificationEntry)); + when(mNotifCollection.getAllNotifs()).thenReturn(List.of(mNotificationEntry)); PeopleSpaceTile actual = mManager.augmentTileFromNotificationEntryManager(tile, @@ -1224,8 +1222,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase { assertThat(actual.getNotificationContent().toString()).isEqualTo(NOTIFICATION_CONTENT_1); - verify(mNotificationEntryManager, times(1)) - .getVisibleNotifications(); + verify(mNotifCollection, times(1)).getAllNotifs(); } @Test @@ -1237,8 +1234,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase { .setPackageName(TEST_PACKAGE_A) .setUserHandle(new UserHandle(0)) .build(); - when(mNotificationEntryManager.getVisibleNotifications()) - .thenReturn(List.of(mNotificationEntry)); + when(mNotifCollection.getAllNotifs()).thenReturn(List.of(mNotificationEntry)); PeopleSpaceTile actual = mManager.augmentTileFromNotificationEntryManager(tile, @@ -1246,8 +1242,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase { assertThat(TextUtils.isEmpty(actual.getNotificationContent())).isTrue(); - verify(mNotificationEntryManager, times(1)) - .getVisibleNotifications(); + verify(mNotifCollection, times(1)).getAllNotifs(); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java index a737ce5a2ae57..58abbf2ddef70 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java @@ -38,6 +38,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager; +import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import org.junit.Before; @@ -53,6 +54,7 @@ public class VisualStabilityManagerTest extends SysuiTestCase { private TestableLooper mTestableLooper; private VisualStabilityManager mVisualStabilityManager; + private VisualStabilityProvider mVisualStabilityProvider = mock(VisualStabilityProvider.class); private VisualStabilityManager.Callback mCallback = mock(VisualStabilityManager.Callback.class); private VisibilityLocationProvider mLocationProvider = mock(VisibilityLocationProvider.class); private ExpandableNotificationRow mRow = mock(ExpandableNotificationRow.class); @@ -69,6 +71,7 @@ public class VisualStabilityManagerTest extends SysuiTestCase { mTestableLooper = TestableLooper.get(this); mVisualStabilityManager = new VisualStabilityManager( mock(NotificationEntryManager.class), + mVisualStabilityProvider, new Handler(mTestableLooper.getLooper()), statusBarStateController, wakefulnessLifecycle, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java index 17b3b1ce2c3ee..ee111715e5ea9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java @@ -40,6 +40,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifStabilityManager; import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable; +import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider; import com.android.systemui.statusbar.notification.collection.render.NotifPanelEventSource; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.util.concurrency.FakeExecutor; @@ -67,6 +68,7 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { @Mock private Pluggable.PluggableListener mInvalidateListener; @Mock private HeadsUpManager mHeadsUpManager; @Mock private NotifPanelEventSource mNotifPanelEventSource; + @Mock private VisualStabilityProvider mVisualStabilityProvider; @Captor private ArgumentCaptor mWakefulnessObserverCaptor; @Captor private ArgumentCaptor mSBStateListenerCaptor; @@ -92,6 +94,7 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { mHeadsUpManager, mNotifPanelEventSource, mStatusBarStateController, + mVisualStabilityProvider, mWakefulnessLifecycle); mCoordinator.attach(mNotifPipeline); From 3747c15a65148a9579bf3773457afb48e5e1f575 Mon Sep 17 00:00:00 2001 From: Jeff DeCew Date: Mon, 7 Feb 2022 16:31:11 +0000 Subject: [PATCH 2/2] New Pipeline: Fix some feature flagging * Calling addKeyguardNotificationSuppressor was supposed to be only when the old pipeline was enabled, but it was still being used on the new pipeline, so I've guarded the calls. This makes it easier to remove the old pipeline cleanly. Test: manual Bug: 218105118 Change-Id: I681dfeaf6ca352f3feb287064581b746e130c701 --- .../notification/collection/NotifPipeline.kt | 4 ++++ .../coordinator/BubbleCoordinator.java | 6 +----- .../coordinator/CommunalCoordinator.java | 6 ++++-- .../SmartspaceDedupingCoordinator.kt | 8 +++++--- .../coordinator/ViewConfigCoordinator.kt | 17 ++++++----------- .../coordinator/CommunalCoordinatorTest.java | 9 ++++++--- 6 files changed, 26 insertions(+), 24 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt index 2009b522482ed..e3ee8139d71c4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.notification.collection import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.statusbar.notification.NotifPipelineFlags import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderEntryListener import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderGroupListener import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderListListener @@ -75,6 +76,7 @@ import javax.inject.Inject */ @SysUISingleton class NotifPipeline @Inject constructor( + notifPipelineFlags: NotifPipelineFlags, private val mNotifCollection: NotifCollection, private val mShadeListBuilder: ShadeListBuilder, private val mRenderStageManager: RenderStageManager @@ -105,6 +107,8 @@ class NotifPipeline @Inject constructor( return mNotifCollection.getEntry(key) } + val isNewPipelineEnabled: Boolean = notifPipelineFlags.isNewPipelineEnabled() + /** * Registers a lifetime extender. Lifetime extenders can cause notifications that have been * dismissed or retracted by system server to be temporarily retained in the collection. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java index 85c0064e79832..b923fdfe6be80 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java @@ -16,7 +16,6 @@ package com.android.systemui.statusbar.notification.collection.coordinator; -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.NotificationEntry; @@ -58,7 +57,6 @@ import javax.inject.Inject; public class BubbleCoordinator implements Coordinator { private static final String TAG = "BubbleCoordinator"; - private final NotifPipelineFlags mNotifPipelineFlags; private final Optional mBubblesManagerOptional; private final Optional mBubblesOptional; private final NotifCollection mNotifCollection; @@ -68,11 +66,9 @@ public class BubbleCoordinator implements Coordinator { @Inject public BubbleCoordinator( - NotifPipelineFlags notifPipelineFlags, Optional bubblesManagerOptional, Optional bubblesOptional, NotifCollection notifCollection) { - mNotifPipelineFlags = notifPipelineFlags; mBubblesManagerOptional = bubblesManagerOptional; mBubblesOptional = bubblesOptional; mNotifCollection = notifCollection; @@ -131,7 +127,7 @@ public class BubbleCoordinator implements Coordinator { DismissedByUserStats dismissedByUserStats, int reason ) { - if (!mNotifPipelineFlags.isNewPipelineEnabled()) { + if (!mNotifPipeline.isNewPipelineEnabled()) { // The `entry` will be from whichever pipeline is active, so if the old pipeline is // running, make sure that we use the new pipeline's entry (if it still exists). NotificationEntry newPipelineEntry = mNotifPipeline.getEntry(entry.getKey()); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinator.java index bd011c3847cee..5396b86382257 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinator.java @@ -74,7 +74,9 @@ public class CommunalCoordinator implements Coordinator { public void attach(@NonNull NotifPipeline pipeline) { pipeline.addPreGroupFilter(mFilter); mCommunalStateController.addCallback(mStateCallback); - mNotificationLockscreenUserManager.addKeyguardNotificationSuppressor( - entry -> mCommunalStateController.getCommunalViewShowing()); + if (!pipeline.isNewPipelineEnabled()) { + mNotificationLockscreenUserManager.addKeyguardNotificationSuppressor( + entry -> mCommunalStateController.getCommunalViewShowing()); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinator.kt index 519d75ff07d06..48f00ac4bf551 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinator.kt @@ -65,9 +65,11 @@ class SmartspaceDedupingCoordinator @Inject constructor( statusBarStateController.addCallback(statusBarStateListener) smartspaceController.addListener(this::onNewSmartspaceTargets) - // TODO (b/173126564): Remove this once the old pipeline is no longer necessary - notificationLockscreenUserManager.addKeyguardNotificationSuppressor { entry -> - isDupedWithSmartspaceContent(entry) + if (!pipeline.isNewPipelineEnabled) { + // TODO (b/173126564): Remove this once the old pipeline is no longer necessary + notificationLockscreenUserManager.addKeyguardNotificationSuppressor { entry -> + isDupedWithSmartspaceContent(entry) + } } recordStatusBarState(statusBarStateController.state) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt index 832df4d56be6d..08b2483520168 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt @@ -21,7 +21,6 @@ import com.android.internal.widget.MessagingMessage import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl -import com.android.systemui.statusbar.notification.NotifPipelineFlags import com.android.systemui.statusbar.notification.collection.NotifPipeline import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope import com.android.systemui.statusbar.notification.row.NotificationGutsManager @@ -35,9 +34,8 @@ import javax.inject.Inject */ @CoordinatorScope class ViewConfigCoordinator @Inject internal constructor( - configurationController: ConfigurationController, - lockscreenUserManager: NotificationLockscreenUserManagerImpl, - notifPipelineFlags: NotifPipelineFlags, + private val mConfigurationController: ConfigurationController, + private val mLockscreenUserManager: NotificationLockscreenUserManagerImpl, private val mGutsManager: NotificationGutsManager, private val mKeyguardUpdateMonitor: KeyguardUpdateMonitor ) : Coordinator, UserChangedListener, ConfigurationController.ConfigurationListener { @@ -46,15 +44,12 @@ class ViewConfigCoordinator @Inject internal constructor( private var mDispatchUiModeChangeOnUserSwitched = false private var mPipeline: NotifPipeline? = null - init { - if (notifPipelineFlags.isNewPipelineEnabled()) { - lockscreenUserManager.addUserChangedListener(this) - configurationController.addCallback(this) - } - } - override fun attach(pipeline: NotifPipeline) { mPipeline = pipeline + if (pipeline.isNewPipelineEnabled) { + mLockscreenUserManager.addUserChangedListener(this) + mConfigurationController.addCallback(this) + } } override fun onDensityOrFontScaleChanged() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinatorTest.java index f4452bc248b15..1f52b9cc41952 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinatorTest.java @@ -16,9 +16,12 @@ package com.android.systemui.statusbar.notification.collection.coordinator; +import static com.google.common.truth.Truth.assertThat; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import android.test.suitebuilder.annotation.SmallTest; @@ -82,12 +85,13 @@ public class CommunalCoordinatorTest extends SysuiTestCase { final NotifFilter filter = filterCaptor.getValue(); // Verify that notifications are not filtered out by default. - assert (!filter.shouldFilterOut(mNotificationEntry, 0)); + assertThat(filter.shouldFilterOut(mNotificationEntry, 0)).isFalse(); filter.setInvalidationListener(mFilterListener); // Verify that notifications are filtered out when communal is showing and that the filter // pipeline is notified. + when(mCommunalStateController.getCommunalViewShowing()).thenReturn(true); stateCallback.onCommunalViewShowingChanged(); // Make sure callback depends on executor to run. verify(mFilterListener, never()).onPluggableInvalidated(any()); @@ -97,7 +101,6 @@ public class CommunalCoordinatorTest extends SysuiTestCase { verify(mFilterListener).onPluggableInvalidated(any()); verify(mNotificationEntryManager).updateNotifications(any()); - assert (filter.shouldFilterOut(mNotificationEntry, 0)); - + assertThat(filter.shouldFilterOut(mNotificationEntry, 0)).isTrue(); } }