summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Steve Elliott <steell@google.com> 2022-07-21 12:56:26 -0400
committer Steve Elliott <steell@google.com> 2022-08-12 16:46:31 +0000
commit2fa47f38ddfb7f0ba759d1bf90efbe23cfdc2877 (patch)
treea30f65b1db4f7730f56afda7137bab0bc4806bb2
parentf5a7752bf27bb78e6ba0070ac429ccd41b966573 (diff)
Remove dead code from NotifEntryManager
All removed code is unused; since all changes are relegated to NotificationEntryManager.java, if this CL still builds, it is proof that the code in question was not referenced anywhere (assuming no reflection). Bug: 200269355 Test: atest SystemUITests Change-Id: If24a9a92c6af5c2edd4fe1b628bb720a6a12a311 Merged-In: If24a9a92c6af5c2edd4fe1b628bb720a6a12a311
-rw-r--r--packages/SystemUI/src/com/android/systemui/Dependency.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java43
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationLifetimeExtender.java65
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java247
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java860
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationFilter.java144
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt227
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/BindEventManagerImpl.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LegacyNotificationRanker.kt34
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LegacyNotificationRankerStub.java66
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LowPriorityInflationHelper.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java274
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/VisualStabilityManager.java217
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java33
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpController.java185
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinder.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java58
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java34
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt216
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java717
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java38
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java684
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java268
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java293
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt509
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java59
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java37
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java24
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java679
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java494
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerLegacyTest.java406
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java14
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java4
48 files changed, 60 insertions, 7014 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 5c84ff38d761..614a87fc758c 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -87,7 +87,6 @@ import com.android.systemui.statusbar.events.PrivacyDotViewController;
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationEntryManager.KeyguardEnvironment;
-import com.android.systemui.statusbar.notification.NotificationFilter;
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
@@ -102,7 +101,6 @@ import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
import com.android.systemui.statusbar.phone.ManagedProfileController;
-import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper;
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider;
import com.android.systemui.statusbar.phone.StatusBarIconController;
@@ -313,7 +311,6 @@ public class Dependency {
@Inject Lazy<AccessibilityFloatingMenuController> mAccessibilityFloatingMenuController;
@Inject Lazy<StatusBarStateController> mStatusBarStateController;
@Inject Lazy<NotificationLockscreenUserManager> mNotificationLockscreenUserManager;
- @Inject Lazy<NotificationGroupAlertTransferHelper> mNotificationGroupAlertTransferHelper;
@Inject Lazy<NotificationGroupManagerLegacy> mNotificationGroupManager;
@Inject Lazy<VisualStabilityManager> mVisualStabilityManager;
@Inject Lazy<NotificationGutsManager> mNotificationGutsManager;
@@ -322,7 +319,6 @@ public class Dependency {
@Inject Lazy<SmartReplyConstants> mSmartReplyConstants;
@Inject Lazy<NotificationListener> mNotificationListener;
@Inject Lazy<NotificationLogger> mNotificationLogger;
- @Inject Lazy<NotificationFilter> mNotificationFilter;
@Inject Lazy<KeyguardDismissUtil> mKeyguardDismissUtil;
@Inject Lazy<SmartReplyController> mSmartReplyController;
@Inject Lazy<RemoteInputQuickSettingsDisabler> mRemoteInputQuickSettingsDisabler;
@@ -529,8 +525,6 @@ public class Dependency {
mNotificationLockscreenUserManager::get);
mProviders.put(VisualStabilityManager.class, mVisualStabilityManager::get);
mProviders.put(NotificationGroupManagerLegacy.class, mNotificationGroupManager::get);
- mProviders.put(NotificationGroupAlertTransferHelper.class,
- mNotificationGroupAlertTransferHelper::get);
mProviders.put(NotificationMediaManager.class, mNotificationMediaManager::get);
mProviders.put(NotificationGutsManager.class, mNotificationGutsManager::get);
mProviders.put(NotificationRemoteInputManager.class,
@@ -538,7 +532,6 @@ public class Dependency {
mProviders.put(SmartReplyConstants.class, mSmartReplyConstants::get);
mProviders.put(NotificationListener.class, mNotificationListener::get);
mProviders.put(NotificationLogger.class, mNotificationLogger::get);
- mProviders.put(NotificationFilter.class, mNotificationFilter::get);
mProviders.put(KeyguardDismissUtil.class, mKeyguardDismissUtil::get);
mProviders.put(SmartReplyController.class, mSmartReplyController::get);
mProviders.put(RemoteInputQuickSettingsDisabler.class,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java
index 07455a02b2cf..15c75ffb8c13 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java
@@ -37,7 +37,7 @@ import java.util.stream.Stream;
* remove notifications that appear on screen for a period of time and dismiss themselves at the
* appropriate time. These include heads up notifications and ambient pulses.
*/
-public abstract class AlertingNotificationManager implements NotificationLifetimeExtender {
+public abstract class AlertingNotificationManager {
private static final String TAG = "AlertNotifManager";
protected final Clock mClock = new Clock();
protected final ArrayMap<String, AlertEntry> mAlertEntries = new ArrayMap<>();
@@ -47,14 +47,6 @@ public abstract class AlertingNotificationManager implements NotificationLifetim
mLogger = logger;
}
- /**
- * This is the list of entries that have already been removed from the
- * NotificationManagerService side, but we keep it to prevent the UI from looking weird and
- * will remove when possible. See {@link NotificationLifetimeExtender}
- */
- protected final ArraySet<NotificationEntry> mExtendedLifetimeAlertEntries = new ArraySet<>();
-
- protected NotificationSafeToRemoveCallback mNotificationLifetimeFinishedCallback;
protected int mMinimumDisplayTime;
protected int mAutoDismissNotificationDecay;
@VisibleForTesting
@@ -210,12 +202,6 @@ public abstract class AlertingNotificationManager implements NotificationLifetim
onAlertEntryRemoved(alertEntry);
entry.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
alertEntry.reset();
- if (mExtendedLifetimeAlertEntries.contains(entry)) {
- if (mNotificationLifetimeFinishedCallback != null) {
- mNotificationLifetimeFinishedCallback.onSafeToRemove(key);
- }
- mExtendedLifetimeAlertEntries.remove(entry);
- }
}
/**
@@ -244,19 +230,6 @@ public abstract class AlertingNotificationManager implements NotificationLifetim
|| alertEntry.mEntry.isRowDismissed();
}
- ///////////////////////////////////////////////////////////////////////////////////////////////
- // NotificationLifetimeExtender Methods
-
- @Override
- public void setCallback(NotificationSafeToRemoveCallback callback) {
- mNotificationLifetimeFinishedCallback = callback;
- }
-
- @Override
- public boolean shouldExtendLifetime(NotificationEntry entry) {
- return !canRemoveImmediately(entry.getKey());
- }
-
/**
* @param key
* @return true if the entry is pinned
@@ -281,20 +254,6 @@ public abstract class AlertingNotificationManager implements NotificationLifetim
return 0;
}
- @Override
- public void setShouldManageLifetime(NotificationEntry entry, boolean shouldExtend) {
- if (shouldExtend) {
- mExtendedLifetimeAlertEntries.add(entry);
- // We need to make sure that entries are stopping to alert eventually, let's remove
- // this as soon as possible.
- AlertEntry alertEntry = mAlertEntries.get(entry.getKey());
- alertEntry.removeAsSoonAsPossible();
- } else {
- mExtendedLifetimeAlertEntries.remove(entry);
- }
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////
-
protected class AlertEntry implements Comparable<AlertEntry> {
@Nullable public NotificationEntry mEntry;
public long mPostTime;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLifetimeExtender.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLifetimeExtender.java
deleted file mode 100644
index 48e2923c97d9..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLifetimeExtender.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.android.systemui.statusbar;
-
-import androidx.annotation.NonNull;
-
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-
-/**
- * Interface for anything that may need to keep notifications managed even after
- * {@link NotificationListener} removes it. The lifetime extender is in charge of performing the
- * callback when the notification is then safe to remove.
- */
-public interface NotificationLifetimeExtender {
-
- /**
- * Set the handler to callback to when the notification is safe to remove.
- *
- * @param callback the handler to callback
- */
- void setCallback(@NonNull NotificationSafeToRemoveCallback callback);
-
- /**
- * Determines whether or not the extender needs the notification kept after removal.
- *
- * @param entry the entry containing the notification to check
- * @return true if the notification lifetime should be extended
- */
- boolean shouldExtendLifetime(@NonNull NotificationEntry entry);
-
- /**
- * It's possible that a notification was canceled before it ever became visible. This callback
- * gives lifetime extenders a chance to make sure it shows up. For example if a foreground
- * service is canceled too quickly but we still want to make sure a FGS notification shows.
- * @param pendingEntry the canceled (but pending) entry
- * @return true if the notification lifetime should be extended
- */
- default boolean shouldExtendLifetimeForPendingNotification(
- @NonNull NotificationEntry pendingEntry) {
- return false;
- }
-
- /**
- * Sets whether or not the lifetime should be managed by the extender. In practice, if
- * shouldManage is true, this is where the extender starts managing the entry internally and is
- * now responsible for calling {@link NotificationSafeToRemoveCallback#onSafeToRemove(String)}
- * when the entry is safe to remove. If shouldManage is false, the extender no longer needs to
- * worry about it (either because we will be removing it anyway or the entry is no longer
- * removed due to an update).
- *
- * @param entry the entry that needs an extended lifetime
- * @param shouldManage true if the extender should manage the entry now, false otherwise
- */
- void setShouldManageLifetime(@NonNull NotificationEntry entry, boolean shouldManage);
-
- /**
- * The callback for when the notification is now safe to remove (i.e. its lifetime has ended).
- */
- interface NotificationSafeToRemoveCallback {
- /**
- * Called when the lifetime extender determines it's safe to remove.
- *
- * @param key key of the entry that is now safe to remove
- */
- void onSafeToRemove(String key);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index 78b3b0a65351..d74d408ae59e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -24,7 +24,6 @@ import android.app.RemoteInput;
import android.content.Context;
import android.content.Intent;
import android.content.pm.UserInfo;
-import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -32,7 +31,6 @@ import android.os.SystemProperties;
import android.os.UserManager;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
-import android.util.ArraySet;
import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.Pair;
@@ -47,12 +45,10 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
-import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.dagger.CentralSurfacesDependenciesModule;
@@ -75,7 +71,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
-import java.util.Set;
import java.util.function.Consumer;
import dagger.Lazy;
@@ -100,8 +95,6 @@ public class NotificationRemoteInputManager implements Dumpable {
private final NotificationLockscreenUserManager mLockscreenUserManager;
private final SmartReplyController mSmartReplyController;
private final NotificationVisibilityProvider mVisibilityProvider;
- private final NotificationEntryManager mEntryManager;
- private final Handler mMainHandler;
private final ActionClickLogger mLogger;
private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
@@ -110,7 +103,6 @@ public class NotificationRemoteInputManager implements Dumpable {
protected final NotifPipelineFlags mNotifPipelineFlags;
private final UserManager mUserManager;
private final KeyguardManager mKeyguardManager;
- private final RemoteInputNotificationRebuilder mRebuilder;
private final StatusBarStateController mStatusBarStateController;
private final RemoteInputUriController mRemoteInputUriController;
private final NotificationClickNotifier mClickNotifier;
@@ -265,10 +257,8 @@ public class NotificationRemoteInputManager implements Dumpable {
SmartReplyController smartReplyController,
NotificationVisibilityProvider visibilityProvider,
NotificationEntryManager notificationEntryManager,
- RemoteInputNotificationRebuilder rebuilder,
Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
StatusBarStateController statusBarStateController,
- @Main Handler mainHandler,
RemoteInputUriController remoteInputUriController,
NotificationClickNotifier clickNotifier,
ActionClickLogger logger,
@@ -278,14 +268,11 @@ public class NotificationRemoteInputManager implements Dumpable {
mLockscreenUserManager = lockscreenUserManager;
mSmartReplyController = smartReplyController;
mVisibilityProvider = visibilityProvider;
- mEntryManager = notificationEntryManager;
mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
- mMainHandler = mainHandler;
mLogger = logger;
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
- mRebuilder = rebuilder;
mKeyguardManager = context.getSystemService(KeyguardManager.class);
mStatusBarStateController = statusBarStateController;
mRemoteInputUriController = remoteInputUriController;
@@ -788,238 +775,4 @@ public class NotificationRemoteInputManager implements Dumpable {
/** Called when the RemoteInputController is attached to the manager */
void setRemoteInputController(@NonNull RemoteInputController remoteInputController);
}
-
- @VisibleForTesting
- protected class LegacyRemoteInputLifetimeExtender implements RemoteInputListener, Dumpable {
-
- /**
- * How long to wait before auto-dismissing a notification that was kept for remote input,
- * and has now sent a remote input. We auto-dismiss, because the app may not see a reason to
- * cancel these given that they technically don't exist anymore. We wait a bit in case the
- * app issues an update.
- */
- private static final int REMOTE_INPUT_KEPT_ENTRY_AUTO_CANCEL_DELAY = 200;
-
- /**
- * Notifications that are already removed but are kept around because we want to show the
- * remote input history. See {@link RemoteInputHistoryExtender} and
- * {@link SmartReplyHistoryExtender}.
- */
- protected final ArraySet<String> mKeysKeptForRemoteInputHistory = new ArraySet<>();
-
- /**
- * Notifications that are already removed but are kept around because the remote input is
- * actively being used (i.e. user is typing in it). See {@link RemoteInputActiveExtender}.
- */
- protected final ArraySet<NotificationEntry> mEntriesKeptForRemoteInputActive =
- new ArraySet<>();
-
- protected NotificationLifetimeExtender.NotificationSafeToRemoveCallback
- mNotificationLifetimeFinishedCallback;
-
- protected final ArrayList<NotificationLifetimeExtender> mLifetimeExtenders =
- new ArrayList<>();
- private RemoteInputController mRemoteInputController;
-
- LegacyRemoteInputLifetimeExtender() {
- addLifetimeExtenders();
- }
-
- /**
- * Adds all the notification lifetime extenders. Each extender represents a reason for the
- * NotificationRemoteInputManager to keep a notification lifetime extended.
- */
- protected void addLifetimeExtenders() {
- mLifetimeExtenders.add(new RemoteInputHistoryExtender());
- mLifetimeExtenders.add(new SmartReplyHistoryExtender());
- mLifetimeExtenders.add(new RemoteInputActiveExtender());
- }
-
- @Override
- public void setRemoteInputController(@NonNull RemoteInputController remoteInputController) {
- mRemoteInputController= remoteInputController;
- }
-
- @Override
- public void onRemoteInputSent(@NonNull NotificationEntry entry) {
- if (FORCE_REMOTE_INPUT_HISTORY
- && isNotificationKeptForRemoteInputHistory(entry.getKey())) {
- mNotificationLifetimeFinishedCallback.onSafeToRemove(entry.getKey());
- } else if (mEntriesKeptForRemoteInputActive.contains(entry)) {
- // We're currently holding onto this notification, but from the apps point of
- // view it is already canceled, so we'll need to cancel it on the apps behalf
- // after sending - unless the app posts an update in the mean time, so wait a
- // bit.
- mMainHandler.postDelayed(() -> {
- if (mEntriesKeptForRemoteInputActive.remove(entry)) {
- mNotificationLifetimeFinishedCallback.onSafeToRemove(entry.getKey());
- }
- }, REMOTE_INPUT_KEPT_ENTRY_AUTO_CANCEL_DELAY);
- }
- }
-
- @Override
- public void onPanelCollapsed() {
- for (int i = 0; i < mEntriesKeptForRemoteInputActive.size(); i++) {
- NotificationEntry entry = mEntriesKeptForRemoteInputActive.valueAt(i);
- if (mRemoteInputController != null) {
- mRemoteInputController.removeRemoteInput(entry, null);
- }
- if (mNotificationLifetimeFinishedCallback != null) {
- mNotificationLifetimeFinishedCallback.onSafeToRemove(entry.getKey());
- }
- }
- mEntriesKeptForRemoteInputActive.clear();
- }
-
- @Override
- public boolean isNotificationKeptForRemoteInputHistory(@NonNull String key) {
- return mKeysKeptForRemoteInputHistory.contains(key);
- }
-
- @Override
- public void releaseNotificationIfKeptForRemoteInputHistory(
- @NonNull NotificationEntry entry) {
- final String key = entry.getKey();
- if (isNotificationKeptForRemoteInputHistory(key)) {
- mMainHandler.postDelayed(() -> {
- if (isNotificationKeptForRemoteInputHistory(key)) {
- mNotificationLifetimeFinishedCallback.onSafeToRemove(key);
- }
- }, REMOTE_INPUT_KEPT_ENTRY_AUTO_CANCEL_DELAY);
- }
- }
-
- @VisibleForTesting
- public Set<NotificationEntry> getEntriesKeptForRemoteInputActive() {
- return mEntriesKeptForRemoteInputActive;
- }
-
- @Override
- public void dump(@NonNull PrintWriter pw,
- @NonNull String[] args) {
- pw.println("LegacyRemoteInputLifetimeExtender:");
- pw.print(" mKeysKeptForRemoteInputHistory: ");
- pw.println(mKeysKeptForRemoteInputHistory);
- pw.print(" mEntriesKeptForRemoteInputActive: ");
- pw.println(mEntriesKeptForRemoteInputActive);
- }
-
- /**
- * NotificationRemoteInputManager has multiple reasons to keep notification lifetime
- * extended so we implement multiple NotificationLifetimeExtenders
- */
- protected abstract class RemoteInputExtender implements NotificationLifetimeExtender {
- @Override
- public void setCallback(NotificationSafeToRemoveCallback callback) {
- if (mNotificationLifetimeFinishedCallback == null) {
- mNotificationLifetimeFinishedCallback = callback;
- }
- }
- }
-
- /**
- * Notification is kept alive as it was cancelled in response to a remote input interaction.
- * This allows us to show what you replied and allows you to continue typing into it.
- */
- protected class RemoteInputHistoryExtender extends RemoteInputExtender {
- @Override
- public boolean shouldExtendLifetime(@NonNull NotificationEntry entry) {
- return shouldKeepForRemoteInputHistory(entry);
- }
-
- @Override
- public void setShouldManageLifetime(NotificationEntry entry,
- boolean shouldExtend) {
- if (shouldExtend) {
- StatusBarNotification newSbn = mRebuilder.rebuildForRemoteInputReply(entry);
- entry.onRemoteInputInserted();
-
- if (newSbn == null) {
- return;
- }
-
- mEntryManager.updateNotification(newSbn, null);
-
- // Ensure the entry hasn't already been removed. This can happen if there is an
- // inflation exception while updating the remote history
- if (entry.isRemoved()) {
- return;
- }
-
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Keeping notification around after sending remote input "
- + entry.getKey());
- }
-
- mKeysKeptForRemoteInputHistory.add(entry.getKey());
- } else {
- mKeysKeptForRemoteInputHistory.remove(entry.getKey());
- }
- }
- }
-
- /**
- * Notification is kept alive for smart reply history. Similar to REMOTE_INPUT_HISTORY but
- * with {@link SmartReplyController} specific logic
- */
- protected class SmartReplyHistoryExtender extends RemoteInputExtender {
- @Override
- public boolean shouldExtendLifetime(@NonNull NotificationEntry entry) {
- return shouldKeepForSmartReplyHistory(entry);
- }
-
- @Override
- public void setShouldManageLifetime(NotificationEntry entry,
- boolean shouldExtend) {
- if (shouldExtend) {
- StatusBarNotification newSbn = mRebuilder.rebuildForCanceledSmartReplies(entry);
-
- if (newSbn == null) {
- return;
- }
-
- mEntryManager.updateNotification(newSbn, null);
-
- if (entry.isRemoved()) {
- return;
- }
-
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Keeping notification around after sending smart reply "
- + entry.getKey());
- }
-
- mKeysKeptForRemoteInputHistory.add(entry.getKey());
- } else {
- mKeysKeptForRemoteInputHistory.remove(entry.getKey());
- mSmartReplyController.stopSending(entry);
- }
- }
- }
-
- /**
- * Notification is kept alive because the user is still using the remote input
- */
- protected class RemoteInputActiveExtender extends RemoteInputExtender {
- @Override
- public boolean shouldExtendLifetime(@NonNull NotificationEntry entry) {
- return isRemoteInputActive(entry);
- }
-
- @Override
- public void setShouldManageLifetime(NotificationEntry entry,
- boolean shouldExtend) {
- if (shouldExtend) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Keeping notification around while remote input active "
- + entry.getKey());
- }
- mEntriesKeptForRemoteInputActive.add(entry);
- } else {
- mEntriesKeptForRemoteInputActive.remove(entry);
- }
- }
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
index 0951e821cdc2..8752f92145db 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
@@ -115,10 +115,8 @@ public interface CentralSurfacesDependenciesModule {
smartReplyController,
visibilityProvider,
notificationEntryManager,
- rebuilder,
centralSurfacesOptionalLazy,
statusBarStateController,
- mainHandler,
remoteInputUriController,
clickNotifier,
actionClickLogger,
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 7583a98df308..e2f87b6f4ffe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -15,66 +15,22 @@
*/
package com.android.systemui.statusbar.notification;
-import static android.service.notification.NotificationListenerService.REASON_ERROR;
-
-import static com.android.systemui.statusbar.notification.collection.NotifCollection.REASON_UNKNOWN;
-import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationCallback;
-
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.Trace;
-import android.os.UserHandle;
import android.service.notification.NotificationListenerService;
-import android.service.notification.NotificationListenerService.Ranking;
-import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.StatusBarNotification;
import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.Log;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.statusbar.IStatusBarService;
-import com.android.internal.statusbar.NotificationVisibility;
-import com.android.systemui.Dumpable;
-import com.android.systemui.dagger.qualifiers.Background;
-import com.android.systemui.dump.DumpManager;
-import com.android.systemui.statusbar.NotificationLifetimeExtender;
-import com.android.systemui.statusbar.NotificationListener;
-import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
-import com.android.systemui.statusbar.NotificationRemoteInputManager;
-import com.android.systemui.statusbar.NotificationRemoveInterceptor;
-import com.android.systemui.statusbar.NotificationUiAdjustment;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
-import com.android.systemui.statusbar.notification.collection.legacy.LegacyNotificationRanker;
-import com.android.systemui.statusbar.notification.collection.legacy.LegacyNotificationRankerStub;
-import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
-import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
-import com.android.systemui.statusbar.notification.logging.NotificationLogger;
-import com.android.systemui.util.Assert;
-import com.android.systemui.util.Compile;
-import com.android.systemui.util.leak.LeakDetector;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Executor;
-
-import dagger.Lazy;
/**
* NotificationEntryManager is responsible for the adding, removing, and updating of
@@ -90,33 +46,10 @@ import dagger.Lazy;
* inflated, an entry moves into the active state, where it _could_ potentially be shown to the
* user. After an entry makes its way into the active state, we sort and filter the entire set to
* repopulate the visible set.
- *
- * There are a few different things that other classes may be interested in, and most of them
- * involve the current set of notifications. Here's a brief overview of things you may want to know:
- * @see #getVisibleNotifications() for the visible set
- * @see #getActiveNotificationUnfiltered(String) to check if a key exists
- * @see #getPendingNotificationsIterator() for an iterator over the pending notifications
- * @see #getPendingOrActiveNotif(String) to find a notification exists for that key in any list
- * @see #getActiveNotificationsForCurrentUser() to see every notification that the current user owns
*/
-public class NotificationEntryManager implements
- CommonNotifCollection,
- Dumpable,
- VisualStabilityManager.Callback {
+public class NotificationEntryManager implements VisualStabilityManager.Callback {
private final NotificationEntryManagerLogger mLogger;
- private final NotificationGroupManagerLegacy mGroupManager;
- private final NotifPipelineFlags mNotifPipelineFlags;
- private final Lazy<NotificationRowBinder> mNotificationRowBinderLazy;
- private final Lazy<NotificationRemoteInputManager> mRemoteInputManagerLazy;
- private final LeakDetector mLeakDetector;
- private final IStatusBarService mStatusBarService;
- private final DumpManager mDumpManager;
- private final Executor mBgExecutor;
-
- private final Set<NotificationEntry> mAllNotifications = new ArraySet<>();
- private final Set<NotificationEntry> mReadOnlyAllNotifications =
- Collections.unmodifiableSet(mAllNotifications);
/** Pending notifications are ones awaiting inflation */
@VisibleForTesting
@@ -129,96 +62,14 @@ public class NotificationEntryManager implements
/** This is the list of "active notifications for this user in this context" */
@VisibleForTesting
protected final ArrayList<NotificationEntry> mSortedAndFiltered = new ArrayList<>();
- private final List<NotificationEntry> mReadOnlyNotifications =
- Collections.unmodifiableList(mSortedAndFiltered);
-
- private final Map<NotificationEntry, NotificationLifetimeExtender> mRetainedNotifications =
- new ArrayMap<>();
-
private final List<NotifCollectionListener> mNotifCollectionListeners = new ArrayList<>();
-
- private LegacyNotificationRanker mRanker = new LegacyNotificationRankerStub();
- private RankingMap mLatestRankingMap;
-
- @VisibleForTesting
- final ArrayList<NotificationLifetimeExtender> mNotificationLifetimeExtenders
- = new ArrayList<>();
private final List<NotificationEntryListener> mNotificationEntryListeners = new ArrayList<>();
- private final List<NotificationRemoveInterceptor> mRemoveInterceptors = new ArrayList<>();
/**
* Injected constructor. See {@link NotificationsModule}.
*/
- public NotificationEntryManager(
- NotificationEntryManagerLogger logger,
- NotificationGroupManagerLegacy groupManager,
- NotifPipelineFlags notifPipelineFlags,
- Lazy<NotificationRowBinder> notificationRowBinderLazy,
- Lazy<NotificationRemoteInputManager> notificationRemoteInputManagerLazy,
- LeakDetector leakDetector,
- IStatusBarService statusBarService,
- DumpManager dumpManager,
- @Background Executor bgExecutor
- ) {
+ public NotificationEntryManager(NotificationEntryManagerLogger logger) {
mLogger = logger;
- mGroupManager = groupManager;
- mNotifPipelineFlags = notifPipelineFlags;
- mNotificationRowBinderLazy = notificationRowBinderLazy;
- mRemoteInputManagerLazy = notificationRemoteInputManagerLazy;
- mLeakDetector = leakDetector;
- mStatusBarService = statusBarService;
- mDumpManager = dumpManager;
- mBgExecutor = bgExecutor;
- }
-
- /** Once called, the NEM will start processing notification events from system server. */
- public void initialize(
- NotificationListener notificationListener,
- LegacyNotificationRanker ranker) {
- mRanker = ranker;
- notificationListener.addNotificationHandler(mNotifListener);
- mDumpManager.registerDumpable(this);
- }
-
- @Override
- public void dump(PrintWriter pw, String[] args) {
- pw.println("NotificationEntryManager state:");
- pw.println(" mAllNotifications=");
- if (mAllNotifications.size() == 0) {
- pw.println("null");
- } else {
- int i = 0;
- for (NotificationEntry entry : mAllNotifications) {
- dumpEntry(pw, " ", i, entry);
- i++;
- }
- }
- pw.print(" mPendingNotifications=");
- if (mPendingNotifications.size() == 0) {
- pw.println("null");
- } else {
- for (NotificationEntry entry : mPendingNotifications.values()) {
- pw.println(entry.getSbn());
- }
- }
- pw.println(" Remove interceptors registered:");
- for (NotificationRemoveInterceptor interceptor : mRemoveInterceptors) {
- pw.println(" " + interceptor.getClass().getSimpleName());
- }
- pw.println(" Lifetime extenders registered:");
- for (NotificationLifetimeExtender extender : mNotificationLifetimeExtenders) {
- pw.println(" " + extender.getClass().getSimpleName());
- }
- pw.println(" Lifetime-extended notifications:");
- if (mRetainedNotifications.isEmpty()) {
- pw.println(" None");
- } else {
- for (Map.Entry<NotificationEntry, NotificationLifetimeExtender> entry
- : mRetainedNotifications.entrySet()) {
- pw.println(" " + entry.getKey().getSbn() + " retained by "
- + entry.getValue().getClass().getName());
- }
- }
}
/** Adds a {@link NotificationEntryListener}. */
@@ -234,501 +85,12 @@ public class NotificationEntryManager implements
mNotificationEntryListeners.remove(listener);
}
- /** Add a {@link NotificationRemoveInterceptor}. */
- public void addNotificationRemoveInterceptor(NotificationRemoveInterceptor interceptor) {
- mRemoveInterceptors.add(interceptor);
- }
-
- /** Remove a {@link NotificationRemoveInterceptor} */
- public void removeNotificationRemoveInterceptor(NotificationRemoveInterceptor interceptor) {
- mRemoveInterceptors.remove(interceptor);
- }
-
- /** Adds multiple {@link NotificationLifetimeExtender}s. */
- public void addNotificationLifetimeExtenders(List<NotificationLifetimeExtender> extenders) {
- for (NotificationLifetimeExtender extender : extenders) {
- addNotificationLifetimeExtender(extender);
- }
- }
-
- /** Adds a {@link NotificationLifetimeExtender}. */
- public void addNotificationLifetimeExtender(NotificationLifetimeExtender extender) {
- mNotificationLifetimeExtenders.add(extender);
- extender.setCallback(key -> removeNotification(key, mLatestRankingMap,
- UNDEFINED_DISMISS_REASON));
- }
-
@Override
public void onChangeAllowed() {
updateNotifications("reordering is now allowed");
}
/**
- * User requests a notification to be removed.
- *
- * @param n the notification to remove.
- * @param reason why it is being removed e.g. {@link NotificationListenerService#REASON_CANCEL},
- * or 0 if unknown.
- */
- public void performRemoveNotification(
- StatusBarNotification n,
- @NonNull DismissedByUserStats stats,
- int reason
- ) {
- removeNotificationInternal(
- n.getKey(),
- null,
- stats.notificationVisibility,
- false /* forceRemove */,
- stats,
- reason);
- }
-
- private NotificationVisibility obtainVisibility(String key) {
- NotificationEntry e = mActiveNotifications.get(key);
- final int rank;
- if (e != null) {
- rank = e.getRanking().getRank();
- } else {
- rank = 0;
- }
-
- final int count = mActiveNotifications.size();
- NotificationVisibility.NotificationLocation location =
- NotificationLogger.getNotificationLocation(getActiveNotificationUnfiltered(key));
- return NotificationVisibility.obtain(key, rank, count, true, location);
- }
-
- private void abortExistingInflation(String key, String reason) {
- if (mPendingNotifications.containsKey(key)) {
- NotificationEntry entry = mPendingNotifications.get(key);
- entry.abortTask();
- mPendingNotifications.remove(key);
- mLogger.logInflationAborted(key, "pending", reason);
- }
- NotificationEntry addedEntry = getActiveNotificationUnfiltered(key);
- if (addedEntry != null) {
- addedEntry.abortTask();
- mLogger.logInflationAborted(key, "active", reason);
- }
- }
-
- /**
- * Cancel this notification and tell the StatusBarManagerService / NotificationManagerService
- * about the failure.
- *
- * WARNING: this will call back into us. Don't hold any locks.
- */
- private void handleInflationException(StatusBarNotification n, Exception e) {
- removeNotificationInternal(
- n.getKey(),
- null,
- null,
- true /* forceRemove */,
- null /* dismissedByUserStats */,
- REASON_ERROR);
- for (NotificationEntryListener listener : mNotificationEntryListeners) {
- listener.onInflationError(n, e);
- }
- }
-
- private final InflationCallback mInflationCallback = new InflationCallback() {
- @Override
- public void handleInflationException(NotificationEntry entry, Exception e) {
- Trace.beginSection("NotificationEntryManager.handleInflationException");
- NotificationEntryManager.this.handleInflationException(entry.getSbn(), e);
- Trace.endSection();
- }
-
- @Override
- public void onAsyncInflationFinished(NotificationEntry entry) {
- Trace.beginSection("NotificationEntryManager.onAsyncInflationFinished");
- mPendingNotifications.remove(entry.getKey());
- // If there was an async task started after the removal, we don't want to add it back to
- // the list, otherwise we might get leaks.
- if (!entry.isRowRemoved()) {
- boolean isNew = getActiveNotificationUnfiltered(entry.getKey()) == null;
- mLogger.logNotifInflated(entry.getKey(), isNew);
- if (isNew) {
- for (NotificationEntryListener listener : mNotificationEntryListeners) {
- listener.onEntryInflated(entry);
- }
- addActiveNotification(entry);
- updateNotifications("onAsyncInflationFinished");
- for (NotificationEntryListener listener : mNotificationEntryListeners) {
- listener.onNotificationAdded(entry);
- }
- } else {
- for (NotificationEntryListener listener : mNotificationEntryListeners) {
- listener.onEntryReinflated(entry);
- }
- }
- }
- Trace.endSection();
- }
- };
-
- private final NotificationHandler mNotifListener = new NotificationHandler() {
- @Override
- public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
- final boolean isUpdateToInflatedNotif = mActiveNotifications.containsKey(sbn.getKey());
- if (isUpdateToInflatedNotif) {
- updateNotification(sbn, rankingMap);
- } else {
- addNotification(sbn, rankingMap);
- }
- }
-
- @Override
- public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) {
- removeNotification(sbn.getKey(), rankingMap, UNDEFINED_DISMISS_REASON);
- }
-
- @Override
- public void onNotificationRemoved(
- StatusBarNotification sbn,
- RankingMap rankingMap,
- int reason) {
- removeNotification(sbn.getKey(), rankingMap, reason);
- }
-
- @Override
- public void onNotificationRankingUpdate(RankingMap rankingMap) {
- updateNotificationRanking(rankingMap);
- }
-
- @Override
- public void onNotificationsInitialized() {
- }
-
- @Override
- public void onNotificationChannelModified(
- String pkgName,
- UserHandle user,
- NotificationChannel channel,
- int modificationType) {
- notifyChannelModified(pkgName, user, channel, modificationType);
- }
- };
-
- /**
- * Equivalent to the old NotificationData#add
- * @param entry - an entry which is prepared for display
- */
- private void addActiveNotification(NotificationEntry entry) {
- Assert.isMainThread();
-
- mActiveNotifications.put(entry.getKey(), entry);
- mGroupManager.onEntryAdded(entry);
- updateRankingAndSort(mRanker.getRankingMap(), "addEntryInternalInternal");
- }
-
- /**
- * Available so that tests can directly manipulate the list of active notifications easily
- *
- * @param entry the entry to add directly to the visible notification map
- */
- @VisibleForTesting
- public void addActiveNotificationForTest(NotificationEntry entry) {
- mActiveNotifications.put(entry.getKey(), entry);
- mGroupManager.onEntryAdded(entry);
-
- reapplyFilterAndSort("addVisibleNotification");
- }
-
- @VisibleForTesting
- protected void removeNotification(String key, RankingMap ranking, int reason) {
- removeNotificationInternal(
- key,
- ranking,
- obtainVisibility(key),
- false /* forceRemove */,
- null /* dismissedByUserStats */,
- reason);
- }
-
- /**
- * Internally remove a notification because system server has reported the notification
- * should be removed OR the user has manually dismissed the notification
- * @param dismissedByUserStats non-null if the user manually dismissed the notification
- */
- private void removeNotificationInternal(
- String key,
- @Nullable RankingMap ranking,
- @Nullable NotificationVisibility visibility,
- boolean forceRemove,
- DismissedByUserStats dismissedByUserStats,
- int reason) {
- Trace.beginSection("NotificationEntryManager.removeNotificationInternal");
-
- final NotificationEntry entry = getActiveNotificationUnfiltered(key);
-
- for (NotificationRemoveInterceptor interceptor : mRemoveInterceptors) {
- if (interceptor.onNotificationRemoveRequested(key, entry, reason)) {
- // Remove intercepted; log and skip
- mLogger.logRemovalIntercepted(key);
- Trace.endSection();
- return;
- }
- }
-
- boolean lifetimeExtended = false;
-
- // Notification was canceled before it got inflated
- if (entry == null) {
- NotificationEntry pendingEntry = mPendingNotifications.get(key);
- if (pendingEntry != null) {
- for (NotificationLifetimeExtender extender : mNotificationLifetimeExtenders) {
- if (extender.shouldExtendLifetimeForPendingNotification(pendingEntry)) {
- extendLifetime(pendingEntry, extender);
- lifetimeExtended = true;
- mLogger.logLifetimeExtended(key, extender.getClass().getName(), "pending");
- }
- }
- if (!lifetimeExtended) {
- // At this point, we are guaranteed the notification will be removed
- abortExistingInflation(key, "removeNotification");
- // Fix for b/201097913: NotifCollectionListener#onEntryRemoved specifies that
- // #onEntryRemoved should be called when a notification is cancelled,
- // regardless of whether the notification was pending or active.
- // Note that mNotificationEntryListeners are NOT notified of #onEntryRemoved
- // because for that interface, #onEntryRemoved should only be called for
- // active entries, NOT pending ones.
- for (NotifCollectionListener listener : mNotifCollectionListeners) {
- listener.onEntryRemoved(pendingEntry, REASON_UNKNOWN);
- }
- for (NotifCollectionListener listener : mNotifCollectionListeners) {
- listener.onEntryCleanUp(pendingEntry);
- }
- mAllNotifications.remove(pendingEntry);
- mLeakDetector.trackGarbage(pendingEntry);
- }
- }
- } else {
- // If a manager needs to keep the notification around for whatever reason, we
- // keep the notification
- boolean entryDismissed = entry.isRowDismissed();
- if (!forceRemove && !entryDismissed) {
- for (NotificationLifetimeExtender extender : mNotificationLifetimeExtenders) {
- if (extender.shouldExtendLifetime(entry)) {
- mLatestRankingMap = ranking;
- extendLifetime(entry, extender);
- lifetimeExtended = true;
- mLogger.logLifetimeExtended(key, extender.getClass().getName(), "active");
- break;
- }
- }
- }
-
- if (!lifetimeExtended) {
- // At this point, we are guaranteed the notification will be removed
- abortExistingInflation(key, "removeNotification");
- mAllNotifications.remove(entry);
-
- // Ensure any managers keeping the lifetime extended stop managing the entry
- cancelLifetimeExtension(entry);
-
- if (entry.rowExists()) {
- entry.removeRow();
- }
-
- // Let's remove the children if this was a summary
- handleGroupSummaryRemoved(key);
- removeVisibleNotification(key);
- updateNotifications("removeNotificationInternal");
- final boolean removedByUser = dismissedByUserStats != null;
-
- mLogger.logNotifRemoved(entry.getKey(), removedByUser);
- if (removedByUser && visibility != null) {
- sendNotificationRemovalToServer(entry.getSbn(), dismissedByUserStats);
- }
- for (NotificationEntryListener listener : mNotificationEntryListeners) {
- listener.onEntryRemoved(entry, visibility, removedByUser, reason);
- }
- for (NotifCollectionListener listener : mNotifCollectionListeners) {
- // NEM doesn't have a good knowledge of reasons so defaulting to unknown.
- listener.onEntryRemoved(entry, REASON_UNKNOWN);
- }
- for (NotifCollectionListener listener : mNotifCollectionListeners) {
- listener.onEntryCleanUp(entry);
- }
- mLeakDetector.trackGarbage(entry);
- }
- }
- Trace.endSection();
- }
-
- private void sendNotificationRemovalToServer(
- StatusBarNotification notification,
- DismissedByUserStats dismissedByUserStats) {
- mBgExecutor.execute(() -> {
- try {
- mStatusBarService.onNotificationClear(
- notification.getPackageName(),
- notification.getUser().getIdentifier(),
- notification.getKey(),
- dismissedByUserStats.dismissalSurface,
- dismissedByUserStats.dismissalSentiment,
- dismissedByUserStats.notificationVisibility);
- } catch (RemoteException ex) {
- // system process is dead if we're here.
- }
- });
- }
-
- /**
- * Ensures that the group children are cancelled immediately when the group summary is cancelled
- * instead of waiting for the notification manager to send all cancels. Otherwise this could
- * lead to flickers.
- *
- * This also ensures that the animation looks nice and only consists of a single disappear
- * animation instead of multiple.
- * @param key the key of the notification was removed
- *
- */
- private void handleGroupSummaryRemoved(String key) {
- NotificationEntry entry = getActiveNotificationUnfiltered(key);
- if (entry != null && entry.rowExists() && entry.isSummaryWithChildren()) {
- if (entry.getSbn().getOverrideGroupKey() != null && !entry.isRowDismissed()) {
- // We don't want to remove children for autobundled notifications as they are not
- // always cancelled. We only remove them if they were dismissed by the user.
- return;
- }
- List<NotificationEntry> childEntries = entry.getAttachedNotifChildren();
- if (childEntries == null) {
- return;
- }
- for (int i = 0; i < childEntries.size(); i++) {
- NotificationEntry childEntry = childEntries.get(i);
- boolean isForeground = (entry.getSbn().getNotification().flags
- & Notification.FLAG_FOREGROUND_SERVICE) != 0;
- boolean keepForReply =
- mRemoteInputManagerLazy.get().shouldKeepForRemoteInputHistory(childEntry)
- || mRemoteInputManagerLazy.get().shouldKeepForSmartReplyHistory(childEntry);
- if (isForeground || keepForReply) {
- // the child is a foreground service notification which we can't remove or it's
- // a child we're keeping around for reply!
- continue;
- }
- childEntry.setKeepInParent(true);
- // we need to set this state earlier as otherwise we might generate some weird
- // animations
- childEntry.removeRow();
- }
- }
- }
-
- private void addNotificationInternal(
- StatusBarNotification notification,
- RankingMap rankingMap) throws InflationException {
- Trace.beginSection("NotificationEntryManager.addNotificationInternal");
- String key = notification.getKey();
- if (DEBUG) {
- Log.d(TAG, "addNotification key=" + key);
- }
-
- updateRankingAndSort(rankingMap, "addNotificationInternal");
-
- Ranking ranking = new Ranking();
- rankingMap.getRanking(key, ranking);
-
- NotificationEntry entry = mPendingNotifications.get(key);
- if (entry != null) {
- entry.setSbn(notification);
- entry.setRanking(ranking);
- } else {
- entry = new NotificationEntry(
- notification,
- ranking,
- SystemClock.uptimeMillis());
- mAllNotifications.add(entry);
- mLeakDetector.trackInstance(entry);
-
- for (NotifCollectionListener listener : mNotifCollectionListeners) {
- listener.onEntryInit(entry);
- }
- }
-
- for (NotifCollectionListener listener : mNotifCollectionListeners) {
- listener.onEntryBind(entry, notification);
- }
-
- mPendingNotifications.put(key, entry);
- mLogger.logNotifAdded(entry.getKey());
- for (NotificationEntryListener listener : mNotificationEntryListeners) {
- listener.onPendingEntryAdded(entry);
- }
- for (NotifCollectionListener listener : mNotifCollectionListeners) {
- listener.onEntryAdded(entry);
- }
- for (NotifCollectionListener listener : mNotifCollectionListeners) {
- listener.onRankingApplied();
- }
- Trace.endSection();
- }
-
- public void addNotification(StatusBarNotification notification, RankingMap ranking) {
- try {
- addNotificationInternal(notification, ranking);
- } catch (InflationException e) {
- handleInflationException(notification, e);
- }
- }
-
- private void updateNotificationInternal(StatusBarNotification notification,
- RankingMap ranking) throws InflationException {
- Trace.beginSection("NotificationEntryManager.updateNotificationInternal");
- if (DEBUG) Log.d(TAG, "updateNotification(" + notification + ")");
-
- final String key = notification.getKey();
- abortExistingInflation(key, "updateNotification");
- final NotificationEntry entry = getActiveNotificationUnfiltered(key);
- if (entry == null) {
- Trace.endSection();
- return;
- }
-
- // Notification is updated so it is essentially re-added and thus alive again. Don't need
- // to keep its lifetime extended.
- cancelLifetimeExtension(entry);
-
- updateRankingAndSort(ranking, "updateNotificationInternal");
- StatusBarNotification oldSbn = entry.getSbn();
- entry.setSbn(notification);
- for (NotifCollectionListener listener : mNotifCollectionListeners) {
- listener.onEntryBind(entry, notification);
- }
- mGroupManager.onEntryUpdated(entry, oldSbn);
-
- mLogger.logNotifUpdated(entry.getKey());
- for (NotificationEntryListener listener : mNotificationEntryListeners) {
- listener.onPreEntryUpdated(entry);
- }
- final boolean fromSystem = ranking != null;
- for (NotifCollectionListener listener : mNotifCollectionListeners) {
- listener.onEntryUpdated(entry, fromSystem);
- }
-
- updateNotifications("updateNotificationInternal");
-
- for (NotificationEntryListener listener : mNotificationEntryListeners) {
- listener.onPostEntryUpdated(entry);
- }
- for (NotifCollectionListener listener : mNotifCollectionListeners) {
- listener.onRankingApplied();
- }
- Trace.endSection();
- }
-
- public void updateNotification(StatusBarNotification notification, RankingMap ranking) {
- try {
- updateNotificationInternal(notification, ranking);
- } catch (InflationException e) {
- handleInflationException(notification, e);
- }
- }
-
- /**
* Update the notifications
* @param reason why the notifications are updating
*/
@@ -736,128 +98,6 @@ public class NotificationEntryManager implements
mLogger.logUseWhileNewPipelineActive("updateNotifications", reason);
}
- public void updateNotificationRanking(RankingMap rankingMap) {
- Trace.beginSection("NotificationEntryManager.updateNotificationRanking");
- List<NotificationEntry> entries = new ArrayList<>();
- entries.addAll(getVisibleNotifications());
- entries.addAll(mPendingNotifications.values());
-
- // Has a copy of the current UI adjustments.
- ArrayMap<String, NotificationUiAdjustment> oldAdjustments = new ArrayMap<>();
- ArrayMap<String, Integer> oldImportances = new ArrayMap<>();
- for (NotificationEntry entry : entries) {
- NotificationUiAdjustment adjustment =
- NotificationUiAdjustment.extractFromNotificationEntry(entry);
- oldAdjustments.put(entry.getKey(), adjustment);
- oldImportances.put(entry.getKey(), entry.getImportance());
- }
-
- // Populate notification entries from the new rankings.
- updateRankingAndSort(rankingMap, "updateNotificationRanking");
- updateRankingOfPendingNotifications(rankingMap);
-
- // By comparing the old and new UI adjustments, reinflate the view accordingly.
- for (NotificationEntry entry : entries) {
- mNotificationRowBinderLazy.get()
- .onNotificationRankingUpdated(
- entry,
- oldImportances.get(entry.getKey()),
- oldAdjustments.get(entry.getKey()),
- NotificationUiAdjustment.extractFromNotificationEntry(entry),
- mInflationCallback);
- }
-
- updateNotifications("updateNotificationRanking");
-
- for (NotificationEntryListener listener : mNotificationEntryListeners) {
- listener.onNotificationRankingUpdated(rankingMap);
- }
- for (NotifCollectionListener listener : mNotifCollectionListeners) {
- listener.onRankingUpdate(rankingMap);
- }
- for (NotifCollectionListener listener : mNotifCollectionListeners) {
- listener.onRankingApplied();
- }
- Trace.endSection();
- }
-
- void notifyChannelModified(
- String pkgName,
- UserHandle user,
- NotificationChannel channel,
- int modificationType) {
- for (NotifCollectionListener listener : mNotifCollectionListeners) {
- listener.onNotificationChannelModified(pkgName, user, channel, modificationType);
- }
- for (NotificationEntryListener listener : mNotificationEntryListeners) {
- listener.onNotificationChannelModified(pkgName, user, channel, modificationType);
- }
- }
-
- private void updateRankingOfPendingNotifications(@Nullable RankingMap rankingMap) {
- if (rankingMap == null) {
- return;
- }
- for (NotificationEntry pendingNotification : mPendingNotifications.values()) {
- Ranking ranking = new Ranking();
- if (rankingMap.getRanking(pendingNotification.getKey(), ranking)) {
- pendingNotification.setRanking(ranking);
- }
- }
- }
-
- /**
- * @return An iterator for all "pending" notifications. Pending notifications are newly-posted
- * notifications whose views have not yet been inflated. In general, the system pretends like
- * these don't exist, although there are a couple exceptions.
- */
- public Iterable<NotificationEntry> getPendingNotificationsIterator() {
- mNotifPipelineFlags.checkLegacyPipelineEnabled();
- return mPendingNotifications.values();
- }
-
- /**
- * Use this method to retrieve a notification entry that has been prepared for presentation.
- * Note that the notification may be filtered out and never shown to the user.
- *
- * @see #getVisibleNotifications() for the currently sorted and filtered list
- *
- * @return a {@link NotificationEntry} if it has been prepared, else null
- */
- public NotificationEntry getActiveNotificationUnfiltered(String key) {
- mNotifPipelineFlags.checkLegacyPipelineEnabled();
- return mActiveNotifications.get(key);
- }
-
- /**
- * Gets the pending or visible notification entry with the given key. Returns null if
- * notification doesn't exist.
- */
- public NotificationEntry getPendingOrActiveNotif(String key) {
- mNotifPipelineFlags.checkLegacyPipelineEnabled();
- NotificationEntry entry = mPendingNotifications.get(key);
- if (entry != null) {
- return entry;
- }
- return mActiveNotifications.get(key);
- }
-
- private void extendLifetime(NotificationEntry entry, NotificationLifetimeExtender extender) {
- NotificationLifetimeExtender activeExtender = mRetainedNotifications.get(entry);
- if (activeExtender != null && activeExtender != extender) {
- activeExtender.setShouldManageLifetime(entry, false);
- }
- mRetainedNotifications.put(entry, extender);
- extender.setShouldManageLifetime(entry, true);
- }
-
- private void cancelLifetimeExtension(NotificationEntry entry) {
- NotificationLifetimeExtender activeExtender = mRetainedNotifications.remove(entry);
- if (activeExtender != null) {
- activeExtender.setShouldManageLifetime(entry, false);
- }
- }
-
/*
* -----
* Annexed from NotificationData below:
@@ -865,59 +105,11 @@ public class NotificationEntryManager implements
* we'll try to keep the behavior the same and can simplify these interfaces in another pass
*/
- /** Internalization of NotificationData#remove */
- private void removeVisibleNotification(String key) {
- // no need to synchronize if we're on the main thread dawg
- Assert.isMainThread();
-
- NotificationEntry removed = mActiveNotifications.remove(key);
-
- if (removed == null) return;
- mGroupManager.onEntryRemoved(removed);
- }
-
- /** @return list of active notifications filtered for the current user */
- public List<NotificationEntry> getActiveNotificationsForCurrentUser() {
- Trace.beginSection("NotificationEntryManager.getActiveNotificationsForCurrentUser");
- Assert.isMainThread();
- ArrayList<NotificationEntry> filtered = new ArrayList<>();
-
- final int len = mActiveNotifications.size();
- for (int i = 0; i < len; i++) {
- NotificationEntry entry = mActiveNotifications.valueAt(i);
- if (!mRanker.isNotificationForCurrentProfiles(entry)) {
- continue;
- }
- filtered.add(entry);
- }
- Trace.endSection();
- return filtered;
- }
-
- //TODO: Get rid of this in favor of NotificationUpdateHandler#updateNotificationRanking
- /**
- * @param rankingMap the {@link RankingMap} to apply to the current notification list
- * @param reason the reason for calling this method, which will be logged
- */
- public void updateRanking(RankingMap rankingMap, String reason) {
- Trace.beginSection("NotificationEntryManager.updateRanking");
- updateRankingAndSort(rankingMap, reason);
- for (NotifCollectionListener listener : mNotifCollectionListeners) {
- listener.onRankingApplied();
- }
- Trace.endSection();
- }
-
/** Resorts / filters the current notification set with the current RankingMap */
public void reapplyFilterAndSort(String reason) {
mLogger.logUseWhileNewPipelineActive("reapplyFilterAndSort", reason);
}
- /** Calls to NotificationRankingManager and updates mSortedAndFiltered */
- private void updateRankingAndSort(RankingMap rankingMap, String reason) {
- mLogger.logUseWhileNewPipelineActive("updateRankingAndSort", reason);
- }
-
/** dump the current active notification list. Called from CentralSurfaces */
public void dump(PrintWriter pw, String indent) {
pw.println("NotificationEntryManager (Legacy)");
@@ -955,55 +147,10 @@ public class NotificationEntryManager implements
pw.println(" notification=" + n.getNotification());
}
- /**
- * This is the answer to the question "what notifications should the user be seeing right now?"
- * These are sorted and filtered, and directly inform the notification shade what to show
- *
- * @return A read-only list of the currently active notifications
- */
- public List<NotificationEntry> getVisibleNotifications() {
- mNotifPipelineFlags.checkLegacyPipelineEnabled();
- return mReadOnlyNotifications;
- }
-
- /**
- * Returns a collections containing ALL notifications we know about, including ones that are
- * hidden or for other users. See {@link CommonNotifCollection#getAllNotifs()}.
- */
- @NonNull
- @Override
- public Collection<NotificationEntry> getAllNotifs() {
- mNotifPipelineFlags.checkLegacyPipelineEnabled();
- return mReadOnlyAllNotifications;
- }
-
- @Nullable
- @Override
- public NotificationEntry getEntry(@NonNull String key) {
- mNotifPipelineFlags.checkLegacyPipelineEnabled();
- return getPendingOrActiveNotif(key);
- }
-
- /** @return A count of the active notifications */
- public int getActiveNotificationsCount() {
- mNotifPipelineFlags.checkLegacyPipelineEnabled();
- return mReadOnlyNotifications.size();
- }
-
- /**
- * @return {@code true} if there is at least one notification that should be visible right now
- */
- public boolean hasActiveNotifications() {
- mNotifPipelineFlags.checkLegacyPipelineEnabled();
- return mReadOnlyNotifications.size() != 0;
- }
-
- @Override
public void addCollectionListener(@NonNull NotifCollectionListener listener) {
mNotifCollectionListeners.add(listener);
}
- @Override
public void removeCollectionListener(@NonNull NotifCollectionListener listener) {
mNotifCollectionListeners.remove(listener);
}
@@ -1024,9 +171,6 @@ public class NotificationEntryManager implements
boolean isNotificationForCurrentProfiles(StatusBarNotification sbn);
}
- private static final String TAG = "NotificationEntryMgr";
- private static final boolean DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG);
-
/**
* Used when a notification is removed and it doesn't have a reason that maps to one of the
* reasons defined in NotificationListenerService
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationFilter.java
deleted file mode 100644
index 54f13808cdad..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationFilter.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2018 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;
-
-import static com.android.systemui.media.MediaDataManagerKt.isMediaNotification;
-
-import android.Manifest;
-import android.app.AppGlobals;
-import android.app.Notification;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.os.RemoteException;
-import android.service.notification.StatusBarNotification;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.ForegroundServiceController;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.media.MediaFeatureFlag;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.notification.NotificationEntryManager.KeyguardEnvironment;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.provider.DebugModeFilterProvider;
-
-import javax.inject.Inject;
-
-/** Component which manages the various reasons a notification might be filtered out.*/
-// TODO: delete NotificationFilter.java after migrating to new NotifPipeline b/145659174.
-// Notification filtering is taken care of across the different Coordinators (mostly
-// KeyguardCoordinator.java)
-@SysUISingleton
-public class NotificationFilter {
-
- private final DebugModeFilterProvider mDebugNotificationFilter;
- private final StatusBarStateController mStatusBarStateController;
- private final KeyguardEnvironment mKeyguardEnvironment;
- private final ForegroundServiceController mForegroundServiceController;
- private final NotificationLockscreenUserManager mUserManager;
- private final Boolean mIsMediaFlagEnabled;
-
- @Inject
- public NotificationFilter(
- DebugModeFilterProvider debugNotificationFilter,
- StatusBarStateController statusBarStateController,
- KeyguardEnvironment keyguardEnvironment,
- ForegroundServiceController foregroundServiceController,
- NotificationLockscreenUserManager userManager,
- MediaFeatureFlag mediaFeatureFlag) {
- mDebugNotificationFilter = debugNotificationFilter;
- mStatusBarStateController = statusBarStateController;
- mKeyguardEnvironment = keyguardEnvironment;
- mForegroundServiceController = foregroundServiceController;
- mUserManager = userManager;
- mIsMediaFlagEnabled = mediaFeatureFlag.getEnabled();
- }
-
- /**
- * @return true if the provided notification should NOT be shown right now.
- */
- public boolean shouldFilterOut(NotificationEntry entry) {
- final StatusBarNotification sbn = entry.getSbn();
- if (mDebugNotificationFilter.shouldFilterOut(entry)) {
- return true;
- }
-
- if (!(mKeyguardEnvironment.isDeviceProvisioned()
- || showNotificationEvenIfUnprovisioned(sbn))) {
- return true;
- }
-
- if (!mKeyguardEnvironment.isNotificationForCurrentProfiles(sbn)) {
- return true;
- }
-
- if (mUserManager.isLockscreenPublicMode(sbn.getUserId())
- && (sbn.getNotification().visibility == Notification.VISIBILITY_SECRET
- || mUserManager.shouldHideNotifications(sbn.getUserId())
- || mUserManager.shouldHideNotifications(sbn.getKey()))) {
- return true;
- }
-
- if (mStatusBarStateController.isDozing() && entry.shouldSuppressAmbient()) {
- return true;
- }
-
- if (!mStatusBarStateController.isDozing() && entry.shouldSuppressNotificationList()) {
- return true;
- }
-
- if (entry.getRanking().isSuspended()) {
- return true;
- }
-
- if (mForegroundServiceController.isDisclosureNotification(sbn)
- && !mForegroundServiceController.isDisclosureNeededForUser(sbn.getUserId())) {
- // this is a foreground-service disclosure for a user that does not need to show one
- return true;
- }
-
- if (mIsMediaFlagEnabled && isMediaNotification(sbn)) {
- return true;
- }
- return false;
- }
-
- // Q: What kinds of notifications should show during setup?
- // A: Almost none! Only things coming from packages with permission
- // android.permission.NOTIFICATION_DURING_SETUP that also have special "kind" tags marking them
- // as relevant for setup (see below).
- private static boolean showNotificationEvenIfUnprovisioned(StatusBarNotification sbn) {
- return showNotificationEvenIfUnprovisioned(AppGlobals.getPackageManager(), sbn);
- }
-
- @VisibleForTesting
- static boolean showNotificationEvenIfUnprovisioned(IPackageManager packageManager,
- StatusBarNotification sbn) {
- return checkUidPermission(packageManager, Manifest.permission.NOTIFICATION_DURING_SETUP,
- sbn.getUid()) == PackageManager.PERMISSION_GRANTED
- && sbn.getNotification().extras.getBoolean(Notification.EXTRA_ALLOW_DURING_SETUP);
- }
-
- private static int checkUidPermission(IPackageManager packageManager, String permission,
- int uid) {
- try {
- return packageManager.checkUidPermission(permission, uid);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index b6392f705c49..585d871bad4e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -61,11 +61,11 @@ import com.android.internal.util.ArrayUtils;
import com.android.internal.util.ContrastColorUtil;
import com.android.systemui.statusbar.InflationTask;
import com.android.systemui.statusbar.notification.collection.NotifCollection.CancellationReason;
-import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifDismissInterceptor;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender;
+import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.notification.icon.IconPack;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController;
@@ -421,7 +421,7 @@ public final class NotificationEntry extends ListEntry {
* Get the children that are actually attached to this notification's row.
*
* TODO: Seems like most callers here should probably be using
- * {@link NotificationGroupManagerLegacy#getChildren}
+ * {@link GroupMembershipManager#getChildren(ListEntry)}
*/
public @Nullable List<NotificationEntry> getAttachedNotifChildren() {
if (row == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt
deleted file mode 100644
index a92cff886b53..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright (C) 2019 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
-
-import android.app.Notification
-import android.app.NotificationManager.IMPORTANCE_HIGH
-import android.app.NotificationManager.IMPORTANCE_MIN
-import android.service.notification.NotificationListenerService.Ranking
-import android.service.notification.NotificationListenerService.RankingMap
-import android.service.notification.StatusBarNotification
-import com.android.systemui.statusbar.NotificationMediaManager
-import com.android.systemui.statusbar.notification.NotificationEntryManager.KeyguardEnvironment
-import com.android.systemui.statusbar.notification.NotificationEntryManagerLogger
-import com.android.systemui.statusbar.notification.NotificationFilter
-import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
-import com.android.systemui.statusbar.notification.collection.legacy.LegacyNotificationRanker
-import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy
-import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider
-import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
-import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_NON_PERSON
-import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING
-import com.android.systemui.statusbar.notification.stack.BUCKET_FOREGROUND_SERVICE
-import com.android.systemui.statusbar.notification.stack.BUCKET_PEOPLE
-import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT
-import com.android.systemui.statusbar.notification.stack.PriorityBucket
-import com.android.systemui.statusbar.policy.HeadsUpManager
-import dagger.Lazy
-import java.util.Objects
-import javax.inject.Inject
-
-private const val TAG = "NotifRankingManager"
-
-/**
- * NotificationRankingManager is responsible for holding on to the most recent [RankingMap], and
- * updating SystemUI's set of [NotificationEntry]s with their own ranking. It also sorts and filters
- * a set of entries (but retains none of them). We also set buckets on the entries here since
- * bucketing is tied closely to sorting.
- *
- * For the curious: this class is one iteration closer to null of what used to be called
- * NotificationData.java.
- */
-open class NotificationRankingManager @Inject constructor(
- private val mediaManagerLazy: Lazy<NotificationMediaManager>,
- private val groupManager: NotificationGroupManagerLegacy,
- private val headsUpManager: HeadsUpManager,
- private val notifFilter: NotificationFilter,
- private val logger: NotificationEntryManagerLogger,
- private val sectionsFeatureManager: NotificationSectionsFeatureManager,
- private val peopleNotificationIdentifier: PeopleNotificationIdentifier,
- private val highPriorityProvider: HighPriorityProvider,
- private val keyguardEnvironment: KeyguardEnvironment
-) : LegacyNotificationRanker {
-
- override var rankingMap: RankingMap? = null
- protected set
- private val mediaManager by lazy {
- mediaManagerLazy.get()
- }
- private val usePeopleFiltering: Boolean
- get() = sectionsFeatureManager.isFilteringEnabled()
- private val rankingComparator: Comparator<NotificationEntry> = Comparator { a, b ->
- val na = a.sbn
- val nb = b.sbn
- val aRank = a.ranking.rank
- val bRank = b.ranking.rank
-
- val aIsFsn = a.isColorizedForegroundService()
- val bIsFsn = b.isColorizedForegroundService()
-
- val aCall = a.isImportantCall()
- val bCall = b.isImportantCall()
-
- val aPersonType = a.getPeopleNotificationType()
- val bPersonType = b.getPeopleNotificationType()
-
- val aMedia = a.isImportantMedia()
- val bMedia = b.isImportantMedia()
-
- val aSystemMax = a.isSystemMax()
- val bSystemMax = b.isSystemMax()
-
- val aHeadsUp = a.isRowHeadsUp
- val bHeadsUp = b.isRowHeadsUp
-
- val aIsHighPriority = a.isHighPriority()
- val bIsHighPriority = b.isHighPriority()
- when {
- aHeadsUp != bHeadsUp -> if (aHeadsUp) -1 else 1
- // Provide consistent ranking with headsUpManager
- aHeadsUp -> headsUpManager.compare(a, b)
- aIsFsn != bIsFsn -> if (aIsFsn) -1 else 1
- aCall != bCall -> if (aCall) -1 else 1
- usePeopleFiltering && aPersonType != bPersonType ->
- peopleNotificationIdentifier.compareTo(aPersonType, bPersonType)
- // Upsort current media notification.
- aMedia != bMedia -> if (aMedia) -1 else 1
- // Upsort PRIORITY_MAX system notifications
- aSystemMax != bSystemMax -> if (aSystemMax) -1 else 1
- aIsHighPriority != bIsHighPriority ->
- -1 * aIsHighPriority.compareTo(bIsHighPriority)
- aRank != bRank -> aRank - bRank
- else -> nb.notification.`when`.compareTo(na.notification.`when`)
- }
- }
-
- override fun updateRanking(
- newRankingMap: RankingMap?,
- entries: Collection<NotificationEntry>,
- reason: String
- ): List<NotificationEntry> {
- // TODO: may not be ideal to guard on null here, but this code is implementing exactly what
- // NotificationData used to do
- if (newRankingMap != null) {
- rankingMap = newRankingMap
- updateRankingForEntries(entries)
- }
- return synchronized(this) {
- filterAndSortLocked(entries, reason)
- }
- }
-
- override fun isNotificationForCurrentProfiles(
- entry: NotificationEntry
- ): Boolean {
- return keyguardEnvironment.isNotificationForCurrentProfiles(entry.sbn)
- }
-
- /** Uses the [rankingComparator] to sort notifications which aren't filtered */
- private fun filterAndSortLocked(
- entries: Collection<NotificationEntry>,
- reason: String
- ): List<NotificationEntry> {
- logger.logFilterAndSort(reason)
- val filtered = entries.asSequence()
- .filterNot(this::filter)
- .sortedWith(rankingComparator)
- .toList()
- entries.forEach { it.bucket = getBucketForEntry(it) }
- return filtered
- }
-
- private fun filter(entry: NotificationEntry): Boolean {
- val filtered = notifFilter.shouldFilterOut(entry)
- if (filtered) {
- // notification is removed from the list, so we reset its initialization time
- entry.resetInitializationTime()
- }
- return filtered
- }
-
- @PriorityBucket
- private fun getBucketForEntry(entry: NotificationEntry): Int {
- val isImportantCall = entry.isImportantCall()
- val isHeadsUp = entry.isRowHeadsUp
- val isMedia = entry.isImportantMedia()
- val isSystemMax = entry.isSystemMax()
- return when {
- entry.isColorizedForegroundService() || isImportantCall -> BUCKET_FOREGROUND_SERVICE
- usePeopleFiltering && entry.isConversation() -> BUCKET_PEOPLE
- isHeadsUp || isMedia || isSystemMax || entry.isHighPriority() -> BUCKET_ALERTING
- else -> BUCKET_SILENT
- }
- }
-
- private fun updateRankingForEntries(entries: Iterable<NotificationEntry>) {
- rankingMap?.let { rankingMap ->
- synchronized(entries) {
- for (entry in entries) {
- val newRanking = Ranking()
- if (!rankingMap.getRanking(entry.key, newRanking)) {
- continue
- }
- entry.ranking = newRanking
-
- val newOverrideGroupKey = newRanking.overrideGroupKey
- if (!Objects.equals(entry.sbn.overrideGroupKey, newOverrideGroupKey)) {
- val oldGroupKey = entry.sbn.groupKey
- val oldIsGroup = entry.sbn.isGroup
- val oldIsGroupSummary = entry.sbn.notification.isGroupSummary
- entry.sbn.overrideGroupKey = newOverrideGroupKey
- groupManager.onEntryUpdated(entry, oldGroupKey, oldIsGroup,
- oldIsGroupSummary)
- }
- }
- }
- }
- }
-
- private fun NotificationEntry.isImportantMedia() =
- key == mediaManager.mediaNotificationKey && importance > IMPORTANCE_MIN
-
- private fun NotificationEntry.isConversation() = getPeopleNotificationType() != TYPE_NON_PERSON
-
- private fun NotificationEntry.getPeopleNotificationType() =
- peopleNotificationIdentifier.getPeopleNotificationType(this)
-
- private fun NotificationEntry.isHighPriority() =
- highPriorityProvider.isHighPriority(this)
-}
-
-// Convenience functions
-private fun NotificationEntry.isSystemMax() =
- importance >= IMPORTANCE_HIGH && sbn.isSystemNotification()
-
-private fun StatusBarNotification.isSystemNotification() =
- "android" == packageName || "com.android.systemui" == packageName
-
-private fun NotificationEntry.isImportantCall() =
- sbn.notification.isStyle(Notification.CallStyle::class.java) && importance > IMPORTANCE_MIN
-
-private fun NotificationEntry.isColorizedForegroundService() = sbn.notification.run {
- isForegroundService && isColorized && importance > IMPORTANCE_MIN
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/BindEventManagerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/BindEventManagerImpl.kt
index 9d5b859ef29c..496266f8831e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/BindEventManagerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/BindEventManagerImpl.kt
@@ -17,8 +17,6 @@
package com.android.systemui.statusbar.notification.collection.inflation
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.inflation.BindEventManager.Listener
import javax.inject.Inject
@@ -31,12 +29,4 @@ class BindEventManagerImpl @Inject constructor() : BindEventManager() {
/** Emit the [Listener.onViewBound] event to all registered listeners. */
fun notifyViewBound(entry: NotificationEntry) =
listeners.forEach { listener -> listener.onViewBound(entry) }
-
- /** Initialize this for the legacy pipeline. */
- fun attachToLegacyPipeline(notificationEntryManager: NotificationEntryManager) {
- notificationEntryManager.addNotificationEntryListener(object : NotificationEntryListener {
- override fun onEntryInflated(entry: NotificationEntry) = notifyViewBound(entry)
- override fun onEntryReinflated(entry: NotificationEntry) = notifyViewBound(entry)
- })
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LegacyNotificationRanker.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LegacyNotificationRanker.kt
deleted file mode 100644
index 49bc48efda00..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LegacyNotificationRanker.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2021 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.legacy
-
-import android.service.notification.NotificationListenerService
-import com.android.systemui.statusbar.notification.collection.NotificationEntry
-
-interface LegacyNotificationRanker {
- val rankingMap: NotificationListenerService.RankingMap?
-
- fun updateRanking(
- newRankingMap: NotificationListenerService.RankingMap?,
- entries: Collection<NotificationEntry>,
- reason: String
- ): List<NotificationEntry>
-
- fun isNotificationForCurrentProfiles(
- entry: NotificationEntry
- ): Boolean
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LegacyNotificationRankerStub.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LegacyNotificationRankerStub.java
deleted file mode 100644
index 12353f80c0d1..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LegacyNotificationRankerStub.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2021 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.legacy;
-
-import android.service.notification.NotificationListenerService.Ranking;
-import android.service.notification.NotificationListenerService.RankingMap;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * Stub implementation that we use until we get passed the "real" one in the form of
- * {@link com.android.systemui.statusbar.notification.collection.NotificationRankingManager}
- */
-public class LegacyNotificationRankerStub implements LegacyNotificationRanker {
- private RankingMap mRankingMap = new RankingMap(new Ranking[] {});
-
- @NonNull
- @Override
- public List<NotificationEntry> updateRanking(
- @Nullable RankingMap newRankingMap,
- @NonNull Collection<NotificationEntry> entries,
- @NonNull String reason) {
- if (newRankingMap != null) {
- mRankingMap = newRankingMap;
- }
- List<NotificationEntry> ranked = new ArrayList<>(entries);
- ranked.sort(mEntryComparator);
- return ranked;
- }
-
- @Nullable
- @Override
- public RankingMap getRankingMap() {
- return mRankingMap;
- }
-
- private final Comparator<NotificationEntry> mEntryComparator = Comparator.comparingLong(
- o -> o.getSbn().getNotification().when);
-
- @Override
- public boolean isNotificationForCurrentProfiles(@NonNull NotificationEntry entry) {
- return true;
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LowPriorityInflationHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LowPriorityInflationHelper.java
index ae4f2bbc0453..89445a5c6467 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LowPriorityInflationHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LowPriorityInflationHelper.java
@@ -19,9 +19,6 @@ package com.android.systemui.statusbar.notification.collection.legacy;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.notification.row.RowContentBindParams;
-import com.android.systemui.statusbar.notification.row.RowContentBindStage;
import javax.inject.Inject;
@@ -32,44 +29,17 @@ import javax.inject.Inject;
@SysUISingleton
public class LowPriorityInflationHelper {
private final NotificationGroupManagerLegacy mGroupManager;
- private final RowContentBindStage mRowContentBindStage;
private final NotifPipelineFlags mNotifPipelineFlags;
@Inject
LowPriorityInflationHelper(
NotificationGroupManagerLegacy groupManager,
- RowContentBindStage rowContentBindStage,
NotifPipelineFlags notifPipelineFlags) {
mGroupManager = groupManager;
- mRowContentBindStage = rowContentBindStage;
mNotifPipelineFlags = notifPipelineFlags;
}
/**
- * Check if we inflated the wrong version of the view and if we need to reinflate the
- * content views to be their low priority version or not.
- *
- * Whether we inflate the low priority view or not depends on the notification being visually
- * part of a group. Since group membership is determined AFTER inflation, we're forced to check
- * again at a later point in the pipeline to see if we inflated the wrong view and reinflate
- * the correct one here.
- *
- * TODO: The group manager should run before inflation so that we don't deal with this
- */
- public void recheckLowPriorityViewAndInflate(
- NotificationEntry entry,
- ExpandableNotificationRow row) {
- mNotifPipelineFlags.checkLegacyPipelineEnabled();
- RowContentBindParams params = mRowContentBindStage.getStageParams(entry);
- final boolean shouldBeLowPriority = shouldUseLowPriorityView(entry);
- if (!row.isRemoved() && row.isLowPriority() != shouldBeLowPriority) {
- params.setUseLowPriority(shouldBeLowPriority);
- mRowContentBindStage.requestRebind(entry,
- en -> row.setIsLowPriority(shouldBeLowPriority));
- }
- }
-
- /**
* Whether the notification should inflate a low priority version of its content views.
*/
public boolean shouldUseLowPriorityView(NotificationEntry entry) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java
index b8da9a83da3f..d41f6fe7bdde 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java
@@ -33,13 +33,9 @@ import com.android.systemui.dump.DumpManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.notification.collection.ListEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
-import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
+import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager.OnGroupExpansionChangeListener;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.util.Compile;
import com.android.wm.shell.bubbles.Bubbles;
@@ -47,7 +43,6 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
@@ -65,12 +60,7 @@ import dagger.Lazy;
* 2. Tracking group expansion states
*/
@SysUISingleton
-public class NotificationGroupManagerLegacy implements
- OnHeadsUpChangedListener,
- StateListener,
- GroupMembershipManager,
- GroupExpansionManager,
- Dumpable {
+public class NotificationGroupManagerLegacy implements StateListener, Dumpable {
private static final String TAG = "LegacyNotifGroupManager";
private static final boolean DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG);
@@ -81,14 +71,10 @@ public class NotificationGroupManagerLegacy implements
*/
private static final long POST_BATCH_MAX_AGE = 5000;
private final HashMap<String, NotificationGroup> mGroupMap = new HashMap<>();
- private final ArraySet<OnGroupExpansionChangeListener> mExpansionChangeListeners =
- new ArraySet<>();
private final Lazy<PeopleNotificationIdentifier> mPeopleNotificationIdentifier;
private final Optional<Bubbles> mBubblesOptional;
private final GroupEventDispatcher mEventDispatcher = new GroupEventDispatcher(mGroupMap::get);
- private int mBarState = -1;
- private HashMap<String, StatusBarNotification> mIsolatedEntries = new HashMap<>();
- private HeadsUpManager mHeadsUpManager;
+ private final HashMap<String, StatusBarNotification> mIsolatedEntries = new HashMap<>();
private boolean mIsUpdatingUnchangedGroup;
@Inject
@@ -111,47 +97,8 @@ public class NotificationGroupManagerLegacy implements
mEventDispatcher.registerGroupChangeListener(listener);
}
- @Override
- public void registerGroupExpansionChangeListener(OnGroupExpansionChangeListener listener) {
- mExpansionChangeListeners.add(listener);
- }
-
- @Override
- public boolean isGroupExpanded(NotificationEntry entry) {
- NotificationGroup group = mGroupMap.get(getGroupKey(entry.getSbn()));
- if (group == null) {
- return false;
- }
- return group.expanded;
- }
-
- /**
- * @return if the group that this notification is associated with logically is expanded
- */
- public boolean isLogicalGroupExpanded(StatusBarNotification sbn) {
- NotificationGroup group = mGroupMap.get(sbn.getGroupKey());
- if (group == null) {
- return false;
- }
- return group.expanded;
- }
-
- @Override
- public void setGroupExpanded(NotificationEntry entry, boolean expanded) {
- NotificationGroup group = mGroupMap.get(getGroupKey(entry.getSbn()));
- if (group == null) {
- return;
- }
- setGroupExpanded(group, expanded);
- }
-
private void setGroupExpanded(NotificationGroup group, boolean expanded) {
group.expanded = expanded;
- if (group.summary != null) {
- for (OnGroupExpansionChangeListener listener : mExpansionChangeListeners) {
- listener.onGroupExpansionChange(group.summary.getRow(), expanded);
- }
- }
}
/**
@@ -212,19 +159,6 @@ public class NotificationGroupManagerLegacy implements
}
}
- /**
- * Notify the group manager that a new entry was added
- */
- public void onEntryAdded(final NotificationEntry added) {
- if (SPEW) {
- Log.d(TAG, "onEntryAdded: entry=" + logKey(added));
- }
- mEventDispatcher.openBufferScope();
- updateIsolation(added);
- onEntryAddedInternal(added);
- mEventDispatcher.closeBufferScope();
- }
-
private void onEntryAddedInternal(final NotificationEntry added) {
if (added.isRowRemoved()) {
added.setDebugThrowable(new Throwable());
@@ -499,106 +433,13 @@ public class NotificationGroupManagerLegacy implements
return result;
}
- /**
- * Update an entry's group information
- * @param entry notification entry to update
- * @param oldNotification previous notification info before this update
- */
- public void onEntryUpdated(NotificationEntry entry, StatusBarNotification oldNotification) {
- if (SPEW) {
- Log.d(TAG, "onEntryUpdated: entry=" + logKey(entry));
- }
- onEntryUpdated(entry, oldNotification.getGroupKey(), oldNotification.isGroup(),
- oldNotification.getNotification().isGroupSummary());
- }
-
- /**
- * Updates an entry's group information
- * @param entry notification entry to update
- * @param oldGroupKey the notification's previous group key before this update
- * @param oldIsGroup whether this notification was a group before this update
- * @param oldIsGroupSummary whether this notification was a group summary before this update
- */
- public void onEntryUpdated(NotificationEntry entry, String oldGroupKey, boolean oldIsGroup,
- boolean oldIsGroupSummary) {
- String newGroupKey = entry.getSbn().getGroupKey();
- boolean groupKeysChanged = !oldGroupKey.equals(newGroupKey);
- boolean wasGroupChild = isGroupChild(entry.getKey(), oldIsGroup, oldIsGroupSummary);
- boolean isGroupChild = isGroupChild(entry.getSbn());
- mEventDispatcher.openBufferScope();
- mIsUpdatingUnchangedGroup = !groupKeysChanged && wasGroupChild == isGroupChild;
- if (mGroupMap.get(getGroupKey(entry.getKey(), oldGroupKey)) != null) {
- onEntryRemovedInternal(entry, oldGroupKey, oldIsGroup, oldIsGroupSummary);
- }
- onEntryAddedInternal(entry);
- mIsUpdatingUnchangedGroup = false;
- if (isIsolated(entry.getSbn().getKey())) {
- mIsolatedEntries.put(entry.getKey(), entry.getSbn());
- if (groupKeysChanged) {
- updateSuppression(mGroupMap.get(oldGroupKey));
- }
- // Always update the suppression of the group from which you're isolated, in case
- // this entry was or now is the alertOverride for that group.
- updateSuppression(mGroupMap.get(newGroupKey));
- } else if (!wasGroupChild && isGroupChild) {
- onEntryBecomingChild(entry);
- }
- mEventDispatcher.closeBufferScope();
- }
-
- /**
- * Whether the given notification is the summary of a group that is being suppressed
- */
- public boolean isSummaryOfSuppressedGroup(StatusBarNotification sbn) {
- return sbn.getNotification().isGroupSummary() && isGroupSuppressed(getGroupKey(sbn));
- }
-
- /**
- * If the given notification is a summary, get the group for it.
- */
- public NotificationGroup getGroupForSummary(StatusBarNotification sbn) {
- if (sbn.getNotification().isGroupSummary()) {
- return mGroupMap.get(getGroupKey(sbn));
- }
- return null;
- }
-
- private boolean isOnlyChild(StatusBarNotification sbn) {
- return !sbn.getNotification().isGroupSummary()
- && getTotalNumberOfChildren(sbn) == 1;
- }
-
- @Override
- public boolean isOnlyChildInGroup(NotificationEntry entry) {
- final StatusBarNotification sbn = entry.getSbn();
- if (!isOnlyChild(sbn)) {
- return false;
- }
- NotificationEntry logicalGroupSummary = getLogicalGroupSummary(entry);
- return logicalGroupSummary != null && !logicalGroupSummary.getSbn().equals(sbn);
- }
-
- private int getTotalNumberOfChildren(StatusBarNotification sbn) {
- int isolatedChildren = getNumberOfIsolatedChildren(sbn.getGroupKey());
- NotificationGroup group = mGroupMap.get(sbn.getGroupKey());
- int realChildren = group != null ? group.children.size() : 0;
- return isolatedChildren + realChildren;
- }
-
- private boolean isGroupSuppressed(String groupKey) {
- NotificationGroup group = mGroupMap.get(groupKey);
- return group != null && group.suppressed;
- }
-
private void setStatusBarState(int newState) {
- mBarState = newState;
- if (mBarState == StatusBarState.KEYGUARD) {
+ if (newState == StatusBarState.KEYGUARD) {
collapseGroups();
}
}
- @Override
- public void collapseGroups() {
+ private void collapseGroups() {
// Because notifications can become isolated when the group becomes suppressed it can
// lead to concurrent modifications while looping. We need to make a copy.
ArrayList<NotificationGroup> groupCopy = new ArrayList<>(mGroupMap.values());
@@ -612,7 +453,6 @@ public class NotificationGroupManagerLegacy implements
}
}
- @Override
public boolean isChildInGroup(NotificationEntry entry) {
final StatusBarNotification sbn = entry.getSbn();
if (!isGroupChild(sbn)) {
@@ -631,67 +471,6 @@ public class NotificationGroupManagerLegacy implements
return true;
}
- @Override
- public boolean isGroupSummary(NotificationEntry entry) {
- final StatusBarNotification sbn = entry.getSbn();
- if (!isGroupSummary(sbn)) {
- return false;
- }
- NotificationGroup group = mGroupMap.get(getGroupKey(sbn));
- if (group == null || group.summary == null) {
- return false;
- }
- return !group.children.isEmpty() && Objects.equals(group.summary.getSbn(), sbn);
- }
-
- @Override
- public NotificationEntry getGroupSummary(NotificationEntry entry) {
- return getGroupSummary(getGroupKey(entry.getSbn()));
- }
-
- @Override
- public NotificationEntry getLogicalGroupSummary(NotificationEntry entry) {
- return getGroupSummary(entry.getSbn().getGroupKey());
- }
-
- @Nullable
- private NotificationEntry getGroupSummary(String groupKey) {
- NotificationGroup group = mGroupMap.get(groupKey);
- //TODO: see if this can become an Entry
- return group == null ? null
- : group.summary;
- }
-
- /**
- * Get the children that are logically in the summary's group, whether or not they are isolated.
- *
- * @param summary summary of a group
- * @return list of the children
- */
- public ArrayList<NotificationEntry> getLogicalChildren(StatusBarNotification summary) {
- NotificationGroup group = mGroupMap.get(summary.getGroupKey());
- if (group == null) {
- return null;
- }
- ArrayList<NotificationEntry> children = new ArrayList<>(group.children.values());
- for (StatusBarNotification sbn : mIsolatedEntries.values()) {
- if (sbn.getGroupKey().equals(summary.getGroupKey())) {
- children.add(mGroupMap.get(sbn.getKey()).summary);
- }
- }
- return children;
- }
-
- @Override
- public @Nullable List<NotificationEntry> getChildren(ListEntry listEntrySummary) {
- NotificationEntry summary = listEntrySummary.getRepresentativeEntry();
- NotificationGroup group = mGroupMap.get(summary.getSbn().getGroupKey());
- if (group == null) {
- return null;
- }
- return new ArrayList<>(group.children.values());
- }
-
/**
* If there is a {@link NotificationGroup} associated with the provided entry, this method
* will update the suppression of that group.
@@ -710,7 +489,7 @@ public class NotificationGroupManagerLegacy implements
* @param sbn notification to check
* @return the key of the notification
*/
- public String getGroupKey(StatusBarNotification sbn) {
+ private String getGroupKey(StatusBarNotification sbn) {
return getGroupKey(sbn.getKey(), sbn.getGroupKey());
}
@@ -721,37 +500,17 @@ public class NotificationGroupManagerLegacy implements
return groupKey;
}
- @Override
- public boolean toggleGroupExpansion(NotificationEntry entry) {
- NotificationGroup group = mGroupMap.get(getGroupKey(entry.getSbn()));
- if (group == null) {
- return false;
- }
- setGroupExpanded(group, !group.expanded);
- return group.expanded;
- }
-
private boolean isIsolated(String sbnKey) {
return mIsolatedEntries.containsKey(sbnKey);
}
/**
- * Is this notification the summary of a group?
- */
- public boolean isGroupSummary(StatusBarNotification sbn) {
- if (isIsolated(sbn.getKey())) {
- return true;
- }
- return sbn.getNotification().isGroupSummary();
- }
-
- /**
* Whether a notification is visually a group child.
*
* @param sbn notification to check
* @return true if it is visually a group child
*/
- public boolean isGroupChild(StatusBarNotification sbn) {
+ private boolean isGroupChild(StatusBarNotification sbn) {
return isGroupChild(sbn.getKey(), sbn.isGroup(), sbn.getNotification().isGroupSummary());
}
@@ -762,11 +521,6 @@ public class NotificationGroupManagerLegacy implements
return isGroup && !isGroupSummary;
}
- @Override
- public void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) {
- updateIsolation(entry);
- }
-
/**
* Whether a notification that is normally part of a group should be temporarily isolated from
* the group and put in their own group visually. This generally happens when the notification
@@ -783,9 +537,6 @@ public class NotificationGroupManagerLegacy implements
if (isImportantConversation(entry)) {
return true;
}
- if (mHeadsUpManager != null && !mHeadsUpManager.isAlerting(entry.getKey())) {
- return false;
- }
NotificationGroup notificationGroup = mGroupMap.get(sbn.getGroupKey());
return (sbn.getNotification().fullScreenIntent != null
|| notificationGroup == null
@@ -825,7 +576,7 @@ public class NotificationGroupManagerLegacy implements
/**
* Update the isolation of an entry, splitting it from the group.
*/
- public void updateIsolation(NotificationEntry entry) {
+ private void updateIsolation(NotificationEntry entry) {
// We need to buffer a few events because we do isolation changes in 3 steps:
// removeInternal, update mIsolatedEntries, addInternal. This means that often the
// alertOverride will update on the removal, however processing the event in that case can
@@ -866,13 +617,6 @@ public class NotificationGroupManagerLegacy implements
|| notificationGroup.summary.isGroupNotFullyVisible();
}
- /**
- * Directly set the heads up manager to avoid circular dependencies
- */
- public void setHeadsUpManager(HeadsUpManager headsUpManager) {
- mHeadsUpManager = headsUpManager;
- }
-
@Override
public void dump(PrintWriter pw, String[] args) {
pw.println("GroupManagerLegacy state:");
@@ -893,7 +637,7 @@ public class NotificationGroupManagerLegacy implements
}
/** Get the group key, reformatted for logging, for the (optional) group */
- public static String logGroupKey(NotificationGroup group) {
+ private static String logGroupKey(NotificationGroup group) {
if (group == null) {
return "null";
}
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 456bf5148f7c..bb8c0e0d3b77 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
@@ -16,84 +16,32 @@
package com.android.systemui.statusbar.notification.collection.legacy;
-import android.os.Handler;
-import android.os.SystemClock;
-import android.view.View;
-
-import androidx.collection.ArraySet;
-
-import com.android.systemui.Dumpable;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
-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;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
/**
* A manager that ensures that notifications are visually stable. It will suppress reorderings
* and reorder at the right time when they are out of view.
*/
-public class VisualStabilityManager implements OnHeadsUpChangedListener, Dumpable {
+public class VisualStabilityManager {
- private static final long TEMPORARY_REORDERING_ALLOWED_DURATION = 1000;
-
- private final ArrayList<Callback> mReorderingAllowedCallbacks = new ArrayList<>();
- private final ArraySet<Callback> mPersistentReorderingCallbacks = new ArraySet<>();
- private final ArrayList<Callback> mGroupChangesAllowedCallbacks = new ArrayList<>();
- private final ArraySet<Callback> mPersistentGroupCallbacks = new ArraySet<>();
- private final Handler mHandler;
private final VisualStabilityProvider mVisualStabilityProvider;
private boolean mPanelExpanded;
private boolean mScreenOn;
- private boolean mReorderingAllowed;
- private boolean mGroupChangedAllowed;
- private boolean mIsTemporaryReorderingAllowed;
- private long mTemporaryReorderingStart;
- private VisibilityLocationProvider mVisibilityLocationProvider;
- private ArraySet<View> mAllowedReorderViews = new ArraySet<>();
- private ArraySet<NotificationEntry> mLowPriorityReorderingViews = new ArraySet<>();
- private ArraySet<View> mAddedChildren = new ArraySet<>();
private boolean mPulsing;
/**
* Injected constructor. See {@link NotificationsModule}.
*/
public VisualStabilityManager(
- NotificationEntryManager notificationEntryManager,
VisualStabilityProvider visualStabilityProvider,
- @Main Handler handler,
StatusBarStateController statusBarStateController,
- WakefulnessLifecycle wakefulnessLifecycle,
- DumpManager dumpManager) {
+ WakefulnessLifecycle wakefulnessLifecycle) {
mVisualStabilityProvider = visualStabilityProvider;
- mHandler = handler;
- dumpManager.registerDumpable(this);
-
- if (notificationEntryManager != null) {
- notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
- @Override
- public void onPreEntryUpdated(NotificationEntry entry) {
- final boolean ambientStateHasChanged =
- entry.isAmbient() != entry.getRow().isLowPriority();
- if (ambientStateHasChanged) {
- // note: entries are removed in onReorderingFinished
- mLowPriorityReorderingViews.add(entry);
- }
- }
- });
- }
if (statusBarStateController != null) {
setPulsing(statusBarStateController.isPulsing());
@@ -116,40 +64,6 @@ public class VisualStabilityManager implements OnHeadsUpChangedListener, Dumpabl
}
/**
- * Add a callback to invoke when reordering is allowed again.
- *
- * @param callback the callback to add
- * @param persistent {@code true} if this callback should this callback be persisted, otherwise
- * it will be removed after a single invocation
- */
- public void addReorderingAllowedCallback(Callback callback, boolean persistent) {
- if (persistent) {
- mPersistentReorderingCallbacks.add(callback);
- }
- if (mReorderingAllowedCallbacks.contains(callback)) {
- return;
- }
- mReorderingAllowedCallbacks.add(callback);
- }
-
- /**
- * Add a callback to invoke when group changes are allowed again.
- *
- * @param callback the callback to add
- * @param persistent {@code true} if this callback should this callback be persisted, otherwise
- * it will be removed after a single invocation
- */
- public void addGroupChangesAllowedCallback(Callback callback, boolean persistent) {
- if (persistent) {
- mPersistentGroupCallbacks.add(callback);
- }
- if (mGroupChangesAllowedCallbacks.contains(callback)) {
- return;
- }
- mGroupChangesAllowedCallbacks.add(callback);
- }
-
- /**
* @param screenOn whether the screen is on
*/
private void setScreenOn(boolean screenOn) {
@@ -177,133 +91,8 @@ public class VisualStabilityManager implements OnHeadsUpChangedListener, Dumpabl
}
private void updateAllowedStates() {
- boolean reorderingAllowed =
- (!mScreenOn || !mPanelExpanded || mIsTemporaryReorderingAllowed) && !mPulsing;
- boolean changedToTrue = reorderingAllowed && !mReorderingAllowed;
- mReorderingAllowed = reorderingAllowed;
- if (changedToTrue) {
- notifyChangeAllowed(mReorderingAllowedCallbacks, mPersistentReorderingCallbacks);
- }
+ boolean reorderingAllowed = (!mScreenOn || !mPanelExpanded) && !mPulsing;
mVisualStabilityProvider.setReorderingAllowed(reorderingAllowed);
- boolean groupChangesAllowed = (!mScreenOn || !mPanelExpanded) && !mPulsing;
- changedToTrue = groupChangesAllowed && !mGroupChangedAllowed;
- mGroupChangedAllowed = groupChangesAllowed;
- if (changedToTrue) {
- notifyChangeAllowed(mGroupChangesAllowedCallbacks, mPersistentGroupCallbacks);
- }
- }
-
- private void notifyChangeAllowed(ArrayList<Callback> callbacks,
- ArraySet<Callback> persistentCallbacks) {
- for (int i = 0; i < callbacks.size(); i++) {
- Callback callback = callbacks.get(i);
- callback.onChangeAllowed();
- if (!persistentCallbacks.contains(callback)) {
- callbacks.remove(callback);
- i--;
- }
- }
- }
-
- /**
- * @return whether reordering is currently allowed in general.
- */
- public boolean isReorderingAllowed() {
- return mReorderingAllowed;
- }
-
- /**
- * @return whether changes in the grouping should be allowed right now.
- */
- public boolean areGroupChangesAllowed() {
- return mGroupChangedAllowed;
- }
-
- /**
- * @return whether a specific notification is allowed to reorder. Certain notifications are
- * allowed to reorder even if {@link #isReorderingAllowed()} returns false, like newly added
- * notifications or heads-up notifications that are out of view.
- */
- public boolean canReorderNotification(ExpandableNotificationRow row) {
- if (mReorderingAllowed) {
- return true;
- }
- if (mAddedChildren.contains(row)) {
- return true;
- }
- if (mLowPriorityReorderingViews.contains(row.getEntry())) {
- return true;
- }
- if (mAllowedReorderViews.contains(row)
- && !mVisibilityLocationProvider.isInVisibleLocation(row.getEntry())) {
- return true;
- }
- return false;
- }
-
- public void setVisibilityLocationProvider(
- VisibilityLocationProvider visibilityLocationProvider) {
- mVisibilityLocationProvider = visibilityLocationProvider;
- }
-
- /**
- * Notifications have been reordered, so reset all the allowed list of views that are allowed
- * to reorder.
- */
- public void onReorderingFinished() {
- mAllowedReorderViews.clear();
- mAddedChildren.clear();
- mLowPriorityReorderingViews.clear();
- }
-
- @Override
- public void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) {
- if (isHeadsUp) {
- // Heads up notifications should in general be allowed to reorder if they are out of
- // view and stay at the current location if they aren't.
- mAllowedReorderViews.add(entry.getRow());
- }
- }
-
- /**
- * Temporarily allows reordering of the entire shade for a period of 1000ms. Subsequent calls
- * to this method will extend the timer.
- */
- public void temporarilyAllowReordering() {
- mHandler.removeCallbacks(mOnTemporaryReorderingExpired);
- mHandler.postDelayed(mOnTemporaryReorderingExpired, TEMPORARY_REORDERING_ALLOWED_DURATION);
- if (!mIsTemporaryReorderingAllowed) {
- mTemporaryReorderingStart = SystemClock.elapsedRealtime();
- }
- mIsTemporaryReorderingAllowed = true;
- updateAllowedStates();
- }
-
- private final Runnable mOnTemporaryReorderingExpired = () -> {
- mIsTemporaryReorderingAllowed = false;
- updateAllowedStates();
- };
-
- /**
- * Notify the visual stability manager that a new view was added and should be allowed to
- * reorder next time.
- */
- public void notifyViewAddition(View view) {
- mAddedChildren.add(view);
- }
-
- @Override
- public void dump(PrintWriter pw, String[] args) {
- pw.println("VisualStabilityManager state:");
- pw.print(" mIsTemporaryReorderingAllowed="); pw.println(mIsTemporaryReorderingAllowed);
- pw.print(" mTemporaryReorderingStart="); pw.println(mTemporaryReorderingStart);
-
- long now = SystemClock.elapsedRealtime();
- pw.print(" Temporary reordering window has been open for ");
- pw.print(now - (mIsTemporaryReorderingAllowed ? mTemporaryReorderingStart : now));
- pw.println("ms");
-
- pw.println();
}
final WakefulnessLifecycle.Observer mWakefulnessObserver = new WakefulnessLifecycle.Observer() {
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 fac234c58850..eda2eeca0620 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
@@ -30,7 +30,6 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dagger.qualifiers.UiBackground;
-import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -53,7 +52,6 @@ import com.android.systemui.statusbar.notification.collection.coordinator.dagger
import com.android.systemui.statusbar.notification.collection.inflation.BindEventManager;
import com.android.systemui.statusbar.notification.collection.inflation.BindEventManagerImpl;
import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater;
-import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
import com.android.systemui.statusbar.notification.collection.inflation.OnUserInteractionCallbackImpl;
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
@@ -123,22 +121,13 @@ public interface NotificationsModule {
NotificationEntryManagerLogger logger,
NotificationGroupManagerLegacy groupManager,
NotifPipelineFlags notifPipelineFlags,
- Lazy<NotificationRowBinder> notificationRowBinderLazy,
Lazy<NotificationRemoteInputManager> notificationRemoteInputManagerLazy,
LeakDetector leakDetector,
IStatusBarService statusBarService,
- DumpManager dumpManager,
@Background Executor bgExecutor) {
return new NotificationEntryManager(
- logger,
- groupManager,
- notifPipelineFlags,
- notificationRowBinderLazy,
- notificationRemoteInputManagerLazy,
- leakDetector,
- statusBarService,
- dumpManager,
- bgExecutor);
+ logger
+ );
}
/** Provides an instance of {@link NotificationGutsManager} */
@@ -162,8 +151,7 @@ public interface NotificationsModule {
Optional<BubblesManager> bubblesManagerOptional,
UiEventLogger uiEventLogger,
OnUserInteractionCallback onUserInteractionCallback,
- ShadeController shadeController,
- DumpManager dumpManager) {
+ ShadeController shadeController) {
return new NotificationGutsManager(
context,
centralSurfacesOptionalLazy,
@@ -181,8 +169,8 @@ public interface NotificationsModule {
bubblesManagerOptional,
uiEventLogger,
onUserInteractionCallback,
- shadeController,
- dumpManager);
+ shadeController
+ );
}
/** Provides an instance of {@link NotifGutsViewManager} */
@@ -193,19 +181,14 @@ public interface NotificationsModule {
@SysUISingleton
@Provides
static VisualStabilityManager provideVisualStabilityManager(
- NotificationEntryManager notificationEntryManager,
VisualStabilityProvider visualStabilityProvider,
- @Main Handler handler,
StatusBarStateController statusBarStateController,
- WakefulnessLifecycle wakefulnessLifecycle,
- DumpManager dumpManager) {
+ WakefulnessLifecycle wakefulnessLifecycle) {
return new VisualStabilityManager(
- notificationEntryManager,
visualStabilityProvider,
- handler,
statusBarStateController,
- wakefulnessLifecycle,
- dumpManager);
+ wakefulnessLifecycle
+ );
}
/** Provides an instance of {@link NotificationLogger} */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpController.java
deleted file mode 100644
index 74fb3f7f9f66..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpController.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2020 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.interruption;
-
-import static com.android.systemui.statusbar.NotificationRemoteInputManager.FORCE_REMOTE_INPUT_HISTORY;
-
-import android.app.Notification;
-import android.service.notification.StatusBarNotification;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.NotificationListener;
-import com.android.systemui.statusbar.NotificationRemoteInputManager;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
-
-import javax.inject.Inject;
-
-/**
- * Controller class for old pipeline heads up logic. It listens to {@link NotificationEntryManager}
- * entry events and appropriately binds or unbinds the heads up view and promotes it to the top
- * of the screen.
- */
-@SysUISingleton
-public class HeadsUpController {
- private final HeadsUpViewBinder mHeadsUpViewBinder;
- private final NotificationInterruptStateProvider mInterruptStateProvider;
- private final NotificationRemoteInputManager mRemoteInputManager;
- private final VisualStabilityManager mVisualStabilityManager;
- private final StatusBarStateController mStatusBarStateController;
- private final NotificationListener mNotificationListener;
- private final HeadsUpManager mHeadsUpManager;
-
- @Inject
- HeadsUpController(
- HeadsUpViewBinder headsUpViewBinder,
- NotificationInterruptStateProvider notificationInterruptStateProvider,
- HeadsUpManager headsUpManager,
- NotificationRemoteInputManager remoteInputManager,
- StatusBarStateController statusBarStateController,
- VisualStabilityManager visualStabilityManager,
- NotificationListener notificationListener) {
- mHeadsUpViewBinder = headsUpViewBinder;
- mHeadsUpManager = headsUpManager;
- mInterruptStateProvider = notificationInterruptStateProvider;
- mRemoteInputManager = remoteInputManager;
- mStatusBarStateController = statusBarStateController;
- mVisualStabilityManager = visualStabilityManager;
- mNotificationListener = notificationListener;
- }
-
- /**
- * Attach this controller and add its listeners.
- */
- public void attach(
- NotificationEntryManager entryManager,
- HeadsUpManager headsUpManager) {
- entryManager.addCollectionListener(mCollectionListener);
- headsUpManager.addListener(mOnHeadsUpChangedListener);
- }
-
- private NotifCollectionListener mCollectionListener = new NotifCollectionListener() {
- @Override
- public void onEntryAdded(NotificationEntry entry) {
- if (mInterruptStateProvider.shouldHeadsUp(entry)) {
- mHeadsUpViewBinder.bindHeadsUpView(
- entry, HeadsUpController.this::showAlertingView);
- }
- }
-
- @Override
- public void onEntryUpdated(NotificationEntry entry) {
- updateHunState(entry);
- }
-
- @Override
- public void onEntryRemoved(NotificationEntry entry, int reason) {
- stopAlerting(entry);
- }
-
- @Override
- public void onEntryCleanUp(NotificationEntry entry) {
- mHeadsUpViewBinder.abortBindCallback(entry);
- }
- };
-
- /**
- * Adds the entry to the HUN manager and show it for the first time.
- */
- private void showAlertingView(NotificationEntry entry) {
- mHeadsUpManager.showNotification(entry);
- if (!mStatusBarStateController.isDozing()) {
- // Mark as seen immediately
- setNotificationShown(entry.getSbn());
- }
- }
-
- private void updateHunState(NotificationEntry entry) {
- boolean hunAgain = alertAgain(entry, entry.getSbn().getNotification());
- // includes check for whether this notification should be filtered:
- boolean shouldHeadsUp = mInterruptStateProvider.shouldHeadsUp(entry);
- final boolean wasHeadsUp = mHeadsUpManager.isAlerting(entry.getKey());
- if (wasHeadsUp) {
- if (shouldHeadsUp) {
- mHeadsUpManager.updateNotification(entry.getKey(), hunAgain);
- } else {
- // We don't want this to be interrupting anymore, let's remove it
- mHeadsUpManager.removeNotification(entry.getKey(), false /* removeImmediately */);
- }
- } else if (shouldHeadsUp && hunAgain) {
- mHeadsUpViewBinder.bindHeadsUpView(entry, mHeadsUpManager::showNotification);
- }
- }
-
- private void setNotificationShown(StatusBarNotification n) {
- try {
- mNotificationListener.setNotificationsShown(new String[]{n.getKey()});
- } catch (RuntimeException e) {
- Log.d(TAG, "failed setNotificationsShown: ", e);
- }
- }
-
- private void stopAlerting(NotificationEntry entry) {
- // Attempt to remove notifications from their HUN manager.
- // Though the remove itself may fail, it lets the manager know to remove as soon as
- // possible.
- String key = entry.getKey();
- if (mHeadsUpManager.isAlerting(key)) {
- // A cancel() in response to a remote input shouldn't be delayed, as it makes the
- // sending look longer than it takes.
- // Also we should not defer the removal if reordering isn't allowed since otherwise
- // some notifications can't disappear before the panel is closed.
- boolean ignoreEarliestRemovalTime =
- mRemoteInputManager.isSpinning(key)
- && !FORCE_REMOTE_INPUT_HISTORY
- || !mVisualStabilityManager.isReorderingAllowed();
- mHeadsUpManager.removeNotification(key, ignoreEarliestRemovalTime);
- }
- }
-
- /**
- * Checks whether an update for a notification warrants an alert for the user.
- *
- * @param oldEntry the entry for this notification.
- * @param newNotification the new notification for this entry.
- * @return whether this notification should alert the user.
- */
- public static boolean alertAgain(
- NotificationEntry oldEntry, Notification newNotification) {
- return oldEntry == null || !oldEntry.hasInterrupted()
- || (newNotification.flags & Notification.FLAG_ONLY_ALERT_ONCE) == 0;
- }
-
- private OnHeadsUpChangedListener mOnHeadsUpChangedListener = new OnHeadsUpChangedListener() {
- @Override
- public void onHeadsUpStateChanged(@NonNull NotificationEntry entry, boolean isHeadsUp) {
- if (!isHeadsUp && !entry.getRow().isRemoved()) {
- mHeadsUpViewBinder.unbindHeadsUpView(entry);
- }
- }
- };
-
- private static final String TAG = "HeadsUpBindController";
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinder.java
index 5ef2b9e55d9e..6f41425b506d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinder.java
@@ -41,8 +41,7 @@ import javax.inject.Inject;
* figuring out the right heads up inflation parameters and inflating/freeing the heads up
* content view.
*
- * TODO: This should be moved into {@link HeadsUpCoordinator} when the old pipeline is deprecated
- * (i.e. when {@link HeadsUpController} is removed).
+ * TODO: This should be moved into {@link HeadsUpCoordinator} when the old pipeline is deprecated.
*/
@SysUISingleton
public class HeadsUpViewBinder {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 3c018022085d..9ad906c83e10 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -94,7 +94,6 @@ import com.android.systemui.statusbar.notification.NotificationFadeAware;
import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorController;
import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.notification.logging.NotificationCounters;
@@ -904,21 +903,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
return mChildrenContainer == null ? null : mChildrenContainer.getAttachedChildren();
}
- /**
- * Apply the order given in the list to the children.
- *
- * @param childOrder the new list order
- * @param visualStabilityManager
- * @param callback the callback to invoked in case it is not allowed
- * @return whether the list order has changed
- */
- public boolean applyChildOrder(List<ExpandableNotificationRow> childOrder,
- VisualStabilityManager visualStabilityManager,
- VisualStabilityManager.Callback callback) {
- return mChildrenContainer != null && mChildrenContainer.applyChildOrder(childOrder,
- visualStabilityManager, callback);
- }
-
/** Updates states of all children. */
public void updateChildrenStates(AmbientState ambientState) {
if (mIsSummaryWithChildren) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index c4ff2599c2ce..7b0b0ce3a691 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -55,7 +55,6 @@ import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.settings.UserContextProvider;
import com.android.systemui.shade.ShadeController;
-import com.android.systemui.statusbar.NotificationLifetimeExtender;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.StatusBarState;
@@ -81,8 +80,7 @@ import dagger.Lazy;
* Handles various NotificationGuts related tasks, such as binding guts to a row, opening and
* closing guts, and keeping track of the currently exposed notification guts.
*/
-public class NotificationGutsManager implements Dumpable, NotificationLifetimeExtender,
- NotifGutsViewManager {
+public class NotificationGutsManager implements NotifGutsViewManager {
private static final String TAG = "NotificationGutsManager";
// Must match constant in Settings. Used to highlight preferences when linking to Settings.
@@ -107,13 +105,10 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
// which notification is currently being longpress-examined by the user
private NotificationGuts mNotificationGutsExposed;
private NotificationMenuRowPlugin.MenuItem mGutsMenuItem;
- private NotificationSafeToRemoveCallback mNotificationLifetimeFinishedCallback;
private NotificationPresenter mPresenter;
private NotificationActivityStarter mNotificationActivityStarter;
private NotificationListContainer mListContainer;
private OnSettingsClickListener mOnSettingsClickListener;
- @VisibleForTesting
- protected String mKeyToRemoveOnGutsClosed;
private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
private final Handler mMainHandler;
@@ -148,8 +143,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
Optional<BubblesManager> bubblesManagerOptional,
UiEventLogger uiEventLogger,
OnUserInteractionCallback onUserInteractionCallback,
- ShadeController shadeController,
- DumpManager dumpManager) {
+ ShadeController shadeController) {
mContext = context;
mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
mMainHandler = mainHandler;
@@ -167,8 +161,6 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
mUiEventLogger = uiEventLogger;
mOnUserInteractionCallback = onUserInteractionCallback;
mShadeController = shadeController;
-
- dumpManager.registerDumpable(this);
}
public void setUpWithPresenter(NotificationPresenter presenter,
@@ -266,12 +258,6 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
mGutsListener.onGutsClose(entry);
}
String key = entry.getKey();
- if (key.equals(mKeyToRemoveOnGutsClosed)) {
- mKeyToRemoveOnGutsClosed = null;
- if (mNotificationLifetimeFinishedCallback != null) {
- mNotificationLifetimeFinishedCallback.onSafeToRemove(key);
- }
- }
});
View gutsView = item.getGutsView();
@@ -658,46 +644,6 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
return true;
}
- @Override
- public void setCallback(NotificationSafeToRemoveCallback callback) {
- mNotificationLifetimeFinishedCallback = callback;
- }
-
- @Override
- public boolean shouldExtendLifetime(NotificationEntry entry) {
- return entry != null
- &&(mNotificationGutsExposed != null
- && entry.getGuts() != null
- && mNotificationGutsExposed == entry.getGuts()
- && !mNotificationGutsExposed.isLeavebehind());
- }
-
- @Override
- public void setShouldManageLifetime(NotificationEntry entry, boolean shouldExtend) {
- if (shouldExtend) {
- mKeyToRemoveOnGutsClosed = entry.getKey();
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Keeping notification because it's showing guts. " + entry.getKey());
- }
- } else {
- if (mKeyToRemoveOnGutsClosed != null
- && mKeyToRemoveOnGutsClosed.equals(entry.getKey())) {
- mKeyToRemoveOnGutsClosed = null;
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Notification that was kept for guts was updated. "
- + entry.getKey());
- }
- }
- }
- }
-
- @Override
- public void dump(PrintWriter pw, String[] args) {
- pw.println("NotificationGutsManager state:");
- pw.print(" mKeyToRemoveOnGutsClosed (legacy): ");
- pw.println(mKeyToRemoveOnGutsClosed);
- }
-
/**
* @param gutsListener the listener for open and close guts events
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index a76f0827fc18..d77e03fd043d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -43,7 +43,6 @@ import com.android.systemui.statusbar.NotificationGroupingUtil;
import com.android.systemui.statusbar.notification.FeedbackIcon;
import com.android.systemui.statusbar.notification.NotificationFadeAware;
import com.android.systemui.statusbar.notification.NotificationUtils;
-import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
import com.android.systemui.statusbar.notification.row.HybridGroupManager;
@@ -462,39 +461,6 @@ public class NotificationChildrenContainer extends ViewGroup
return mAttachedChildren;
}
- /**
- * Apply the order given in the list to the children.
- *
- * @param childOrder the new list order
- * @param visualStabilityManager
- * @param callback
- * @return whether the list order has changed
- */
- public boolean applyChildOrder(List<ExpandableNotificationRow> childOrder,
- VisualStabilityManager visualStabilityManager,
- VisualStabilityManager.Callback callback) {
- if (childOrder == null) {
- return false;
- }
- boolean result = false;
- for (int i = 0; i < mAttachedChildren.size() && i < childOrder.size(); i++) {
- ExpandableNotificationRow child = mAttachedChildren.get(i);
- ExpandableNotificationRow desiredChild = childOrder.get(i);
- if (child != desiredChild) {
- if (visualStabilityManager.canReorderNotification(desiredChild)) {
- mAttachedChildren.remove(desiredChild);
- mAttachedChildren.add(i, desiredChild);
- result = true;
- } else {
- visualStabilityManager.addReorderingAllowedCallback(callback,
- false /* persistent */);
- }
- }
- }
- updateExpansionStates();
- return result;
- }
-
/** To be called any time the rows have been updated */
public void updateExpansionStates() {
if (mChildrenExpanded || mUserLocked) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
index 54e26c34522d..91a28139c775 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
@@ -20,9 +20,6 @@ import android.util.Log
import android.view.View
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.media.KeyguardMediaController
-import com.android.systemui.plugins.statusbar.StatusBarStateController
-import com.android.systemui.statusbar.StatusBarState
-import com.android.systemui.statusbar.notification.NotifPipelineFlags
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
import com.android.systemui.statusbar.notification.collection.render.MediaContainerController
import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController
@@ -33,32 +30,20 @@ import com.android.systemui.statusbar.notification.dagger.PeopleHeader
import com.android.systemui.statusbar.notification.dagger.SilentHeader
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
-import com.android.systemui.statusbar.notification.row.StackScrollerDecorView
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider
import com.android.systemui.statusbar.policy.ConfigurationController
-import com.android.systemui.util.children
import com.android.systemui.util.foldToSparseArray
-import com.android.systemui.util.takeUntil
-import com.android.systemui.util.traceSection
import javax.inject.Inject
/**
- * Manages the boundaries of the notification sections (incoming, conversations, high priority, and
- * low priority).
- *
- * In the legacy notification pipeline, this is responsible for correctly positioning all section
- * headers after the [NotificationStackScrollLayout] has had notifications added/removed/changed. In
- * the new pipeline, this is handled as part of the [ShadeViewManager].
+ * Manages section headers in the NSSL.
*
* TODO: Move remaining sections logic from NSSL into this class.
*/
class NotificationSectionsManager @Inject internal constructor(
- private val statusBarStateController: StatusBarStateController,
private val configurationController: ConfigurationController,
private val keyguardMediaController: KeyguardMediaController,
private val sectionsFeatureManager: NotificationSectionsFeatureManager,
- private val logger: NotificationSectionsLogger,
- private val notifPipelineFlags: NotifPipelineFlags,
private val mediaContainerController: MediaContainerController,
@IncomingHeader private val incomingHeaderController: SectionHeaderController,
@PeopleHeader private val peopleHeaderController: SectionHeaderController,
@@ -139,205 +124,6 @@ class NotificationSectionsManager @Inject internal constructor(
else -> null
}
- private fun logShadeChild(i: Int, child: View) {
- when {
- child === incomingHeaderView -> logger.logIncomingHeader(i)
- child === mediaControlsView -> logger.logMediaControls(i)
- child === peopleHeaderView -> logger.logConversationsHeader(i)
- child === alertingHeaderView -> logger.logAlertingHeader(i)
- child === silentHeaderView -> logger.logSilentHeader(i)
- child !is ExpandableNotificationRow -> logger.logOther(i, child.javaClass)
- else -> {
- val isHeadsUp = child.isHeadsUp
- when (child.entry.bucket) {
- BUCKET_HEADS_UP -> logger.logHeadsUp(i, isHeadsUp)
- BUCKET_PEOPLE -> logger.logConversation(i, isHeadsUp)
- BUCKET_ALERTING -> logger.logAlerting(i, isHeadsUp)
- BUCKET_SILENT -> logger.logSilent(i, isHeadsUp)
- }
- }
- }
- }
- private fun logShadeContents() = traceSection("NotifSectionsManager.logShadeContents") {
- parent.children.forEachIndexed(::logShadeChild)
- }
-
- private val isUsingMultipleSections: Boolean
- get() = sectionsFeatureManager.getNumberOfBuckets() > 1
-
- @VisibleForTesting
- fun updateSectionBoundaries() = updateSectionBoundaries("test")
-
- private interface SectionUpdateState<out T : ExpandableView> {
- val header: T
- var currentPosition: Int?
- var targetPosition: Int?
- fun adjustViewPosition()
- }
-
- private fun <T : ExpandableView> expandableViewHeaderState(header: T): SectionUpdateState<T> =
- object : SectionUpdateState<T> {
- override val header = header
- override var currentPosition: Int? = null
- override var targetPosition: Int? = null
-
- override fun adjustViewPosition() {
- notifPipelineFlags.checkLegacyPipelineEnabled()
- val target = targetPosition
- val current = currentPosition
- if (target == null) {
- if (current != null) {
- parent.removeView(header)
- }
- } else {
- if (current == null) {
- // If the header is animating away, it will still have a parent, so
- // detach it first
- // TODO: We should really cancel the active animations here. This will
- // happen automatically when the view's intro animation starts, but
- // it's a fragile link.
- header.removeFromTransientContainer()
- parent.addView(header, target)
- } else {
- parent.changeViewPosition(header, target)
- }
- }
- }
- }
-
- private fun <T : StackScrollerDecorView> decorViewHeaderState(
- header: T
- ): SectionUpdateState<T> {
- notifPipelineFlags.checkLegacyPipelineEnabled()
- val inner = expandableViewHeaderState(header)
- return object : SectionUpdateState<T> by inner {
- override fun adjustViewPosition() {
- inner.adjustViewPosition()
- if (targetPosition != null && currentPosition == null) {
- header.isContentVisible = true
- }
- }
- }
- }
-
- /**
- * Should be called whenever notifs are added, removed, or updated. Updates section boundary
- * bookkeeping and adds/moves/removes section headers if appropriate.
- */
- fun updateSectionBoundaries(reason: String) = traceSection("NotifSectionsManager.update") {
- notifPipelineFlags.checkLegacyPipelineEnabled()
- if (!isUsingMultipleSections) {
- return@traceSection
- }
- logger.logStartSectionUpdate(reason)
-
- // The overall strategy here is to iterate over the current children of mParent, looking
- // for where the sections headers are currently positioned, and where each section begins.
- // Then, once we find the start of a new section, we track that position as the "target" for
- // the section header, adjusted for the case where existing headers are in front of that
- // target, but won't be once they are moved / removed after the pass has completed.
-
- val showHeaders = statusBarStateController.state != StatusBarState.KEYGUARD
- val usingMediaControls = sectionsFeatureManager.isMediaControlsEnabled()
-
- val mediaState = mediaControlsView?.let(::expandableViewHeaderState)
- val incomingState = incomingHeaderView?.let(::decorViewHeaderState)
- val peopleState = peopleHeaderView?.let(::decorViewHeaderState)
- val alertingState = alertingHeaderView?.let(::decorViewHeaderState)
- val gentleState = silentHeaderView?.let(::decorViewHeaderState)
-
- fun getSectionState(view: View): SectionUpdateState<ExpandableView>? = when {
- view === mediaControlsView -> mediaState
- view === incomingHeaderView -> incomingState
- view === peopleHeaderView -> peopleState
- view === alertingHeaderView -> alertingState
- view === silentHeaderView -> gentleState
- else -> null
- }
-
- val headersOrdered = sequenceOf(
- mediaState, incomingState, peopleState, alertingState, gentleState
- ).filterNotNull()
-
- var peopleNotifsPresent = false
- var nextBucket: Int? = null
- var inIncomingSection = false
-
- // Iterating backwards allows for easier construction of the Incoming section, as opposed
- // to backtracking when a discontinuity in the sections is discovered.
- // Iterating to -1 in order to support the case where a header is at the very top of the
- // shade.
- for (i in parent.childCount - 1 downTo -1) {
- val child: View? = parent.getChildAt(i)
-
- child?.let {
- logShadeChild(i, child)
- // If this child is a header, update the tracked positions
- getSectionState(child)?.let { state ->
- state.currentPosition = i
- // If headers that should appear above this one in the shade already have a
- // target index, then we need to decrement them in order to account for this one
- // being either removed, or moved below them.
- headersOrdered.takeUntil { it === state }
- .forEach { it.targetPosition = it.targetPosition?.minus(1) }
- }
- }
-
- val row = (child as? ExpandableNotificationRow)
- ?.takeUnless { it.visibility == View.GONE }
-
- // Is there a section discontinuity? This usually occurs due to HUNs
- inIncomingSection = inIncomingSection || nextBucket?.let { next ->
- row?.entry?.bucket?.let { curr -> next < curr }
- } == true
-
- if (inIncomingSection) {
- // Update the bucket to reflect that it's being placed in the Incoming section
- row?.entry?.bucket = BUCKET_HEADS_UP
- }
-
- // Insert a header in front of the next row, if there's a boundary between it and this
- // row, or if it is the topmost row.
- val isSectionBoundary = nextBucket != null &&
- (child == null || row != null && nextBucket != row.entry.bucket)
- if (isSectionBoundary && showHeaders) {
- when (nextBucket) {
- BUCKET_SILENT -> gentleState?.targetPosition = i + 1
- }
- }
-
- row ?: continue
-
- // Check if there are any people notifications
- peopleNotifsPresent = peopleNotifsPresent || row.entry.bucket == BUCKET_PEOPLE
- nextBucket = row.entry.bucket
- }
-
- mediaState?.targetPosition = if (usingMediaControls) 0 else null
-
- logger.logStr("New header target positions:")
- logger.logMediaControls(mediaState?.targetPosition ?: -1)
- logger.logIncomingHeader(incomingState?.targetPosition ?: -1)
- logger.logConversationsHeader(peopleState?.targetPosition ?: -1)
- logger.logAlertingHeader(alertingState?.targetPosition ?: -1)
- logger.logSilentHeader(gentleState?.targetPosition ?: -1)
-
- // Update headers in reverse order to preserve indices, otherwise movements earlier in the
- // list will affect the target indices of the headers later in the list.
- headersOrdered.asIterable().reversed().forEach { it.adjustViewPosition() }
-
- logger.logStr("Final order:")
- logShadeContents()
- logger.logStr("Section boundary update complete")
-
- // Update headers to reflect state of section contents
- silentHeaderView?.run {
- val hasActiveClearableNotifications = this@NotificationSectionsManager.parent
- .hasActiveClearableNotifications(NotificationStackScrollLayout.ROWS_GENTLE)
- setClearSectionButtonEnabled(hasActiveClearableNotifications)
- }
- }
-
private sealed class SectionBounds {
data class Many(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 427004e71425..952bafbe6eb3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -5822,12 +5822,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
mSpeedBumpIndexDirty = true;
}
- /** Updates the indices of the boundaries between sections. */
- @ShadeViewRefactor(RefactorComponent.INPUT)
- public void updateSectionBoundaries(String reason) {
- mSectionsManager.updateSectionBoundaries(reason);
- }
-
void updateContinuousBackgroundDrawing() {
boolean continuousBackground = !mAmbientState.isFullyAwake()
&& mSwipeHelper.isSwiping();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index cc539b01b894..9998fe41b775 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -90,7 +90,6 @@ import com.android.systemui.statusbar.notification.collection.PipelineDumpable;
import com.android.systemui.statusbar.notification.collection.PipelineDumper;
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy.OnGroupChangeListener;
-import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
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.render.GroupExpansionManager;
@@ -162,7 +161,6 @@ public class NotificationStackScrollLayoutController {
private final NotificationEntryManager mNotificationEntryManager;
private final UiEventLogger mUiEventLogger;
private final NotificationRemoteInputManager mRemoteInputManager;
- private final VisualStabilityManager mVisualStabilityManager;
private final ShadeController mShadeController;
private final KeyguardMediaController mKeyguardMediaController;
private final SysuiStatusBarStateController mStatusBarStateController;
@@ -646,7 +644,6 @@ public class NotificationStackScrollLayoutController {
ShadeTransitionController shadeTransitionController,
UiEventLogger uiEventLogger,
NotificationRemoteInputManager remoteInputManager,
- VisualStabilityManager visualStabilityManager,
ShadeController shadeController,
InteractionJankMonitor jankMonitor,
StackStateLogger stackLogger,
@@ -693,7 +690,6 @@ public class NotificationStackScrollLayoutController {
mNotificationEntryManager = notificationEntryManager;
mUiEventLogger = uiEventLogger;
mRemoteInputManager = remoteInputManager;
- mVisualStabilityManager = visualStabilityManager;
mShadeController = shadeController;
updateResources();
}
@@ -765,8 +761,6 @@ public class NotificationStackScrollLayoutController {
mNotificationRoundnessManager.setOnRoundingChangedCallback(mView::invalidate);
mView.addOnExpandedHeightChangedListener(mNotificationRoundnessManager::setExpanded);
- mVisualStabilityManager.setVisibilityLocationProvider(this::isInVisibleLocation);
-
mTunerService.addTunable(
(key, newValue) -> {
switch (key) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 896e3e53946a..7da1d6c085b0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -207,7 +207,6 @@ import com.android.systemui.statusbar.notification.NotificationActivityStarter;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
-import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
@@ -705,7 +704,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
WakefulnessLifecycle wakefulnessLifecycle,
SysuiStatusBarStateController statusBarStateController,
Optional<Bubbles> bubblesOptional,
- VisualStabilityManager visualStabilityManager,
DeviceProvisionedController deviceProvisionedController,
NavigationBarController navigationBarController,
AccessibilityFloatingMenuController accessibilityFloatingMenuController,
@@ -793,7 +791,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
mWakefulnessLifecycle = wakefulnessLifecycle;
mStatusBarStateController = statusBarStateController;
mBubblesOptional = bubblesOptional;
- mVisualStabilityManager = visualStabilityManager;
mDeviceProvisionedController = deviceProvisionedController;
mNavigationBarController = navigationBarController;
mAccessibilityFloatingMenuController = accessibilityFloatingMenuController;
@@ -3931,9 +3928,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
// all notifications
protected NotificationStackScrollLayout mStackScroller;
- // handling reordering
- private final VisualStabilityManager mVisualStabilityManager;
-
protected AccessibilityManager mAccessibilityManager;
protected boolean mDeviceInteractive;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index 80432dbd277c..51536c310dc9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -326,14 +326,6 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
dumpInternal(pw, args);
}
- @Override
- public boolean shouldExtendLifetime(NotificationEntry entry) {
- // We should not defer the removal if reordering isn't allowed since otherwise
- // these won't disappear until reordering is allowed again, which happens only once
- // the notification panel is collapsed again.
- return mVisualStabilityProvider.isReorderingAllowed() && super.shouldExtendLifetime(entry);
- }
-
///////////////////////////////////////////////////////////////////////////////////////////////
// OnReorderingAllowedListener:
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java
deleted file mode 100644
index ca6e67ec4a83..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java
+++ /dev/null
@@ -1,717 +0,0 @@
-/*
- * Copyright (C) 2018 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.phone;
-
-import static com.android.systemui.statusbar.notification.NotificationUtils.logKey;
-import static com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy.logGroupKey;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.Notification;
-import android.os.SystemClock;
-import android.service.notification.StatusBarNotification;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import com.android.internal.statusbar.NotificationVisibility;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
-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.legacy.NotificationGroupManagerLegacy;
-import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy.NotificationGroup;
-import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
-import com.android.systemui.statusbar.notification.row.RowContentBindParams;
-import com.android.systemui.statusbar.notification.row.RowContentBindStage;
-import com.android.systemui.statusbar.phone.dagger.StatusBarPhoneModule;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
-import com.android.systemui.util.Compile;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-import javax.inject.Inject;
-
-/**
- * A helper class dealing with the alert interactions between {@link NotificationGroupManagerLegacy}
- * and {@link HeadsUpManager}. In particular, this class deals with keeping
- * the correct notification in a group alerting based off the group suppression and alertOverride.
- */
-@SysUISingleton
-public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedListener,
- StateListener {
-
- private static final long ALERT_TRANSFER_TIMEOUT = 300;
- private static final String TAG = "NotifGroupAlertTransfer";
- private static final boolean DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG);
- private static final boolean SPEW = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.VERBOSE);
-
- /**
- * The list of entries containing group alert metadata for each group. Keyed by group key.
- */
- private final ArrayMap<String, GroupAlertEntry> mGroupAlertEntries = new ArrayMap<>();
-
- /**
- * The list of entries currently inflating that should alert after inflation. Keyed by
- * notification key.
- */
- private final ArrayMap<String, PendingAlertInfo> mPendingAlerts = new ArrayMap<>();
-
- private HeadsUpManager mHeadsUpManager;
- private final RowContentBindStage mRowContentBindStage;
- private final NotificationGroupManagerLegacy mGroupManager;
-
- private NotificationEntryManager mEntryManager;
-
- private boolean mIsDozing;
-
- /**
- * Injected constructor. See {@link StatusBarPhoneModule}.
- */
- @Inject
- public NotificationGroupAlertTransferHelper(
- RowContentBindStage bindStage,
- StatusBarStateController statusBarStateController,
- NotificationGroupManagerLegacy notificationGroupManagerLegacy) {
- mRowContentBindStage = bindStage;
- mGroupManager = notificationGroupManagerLegacy;
- statusBarStateController.addCallback(this);
- }
-
- /** Causes the TransferHelper to register itself as a listener to the appropriate classes. */
- public void bind(NotificationEntryManager entryManager,
- NotificationGroupManagerLegacy groupManager) {
- if (mEntryManager != null) {
- throw new IllegalStateException("Already bound.");
- }
-
- // TODO(b/119637830): It would be good if GroupManager already had all pending notifications
- // as normal children (i.e. add notifications to GroupManager before inflation) so that we
- // don't have to have this dependency. We'd also have to worry less about the suppression
- // not being up to date.
- mEntryManager = entryManager;
-
- mEntryManager.addNotificationEntryListener(mNotificationEntryListener);
- groupManager.registerGroupChangeListener(mOnGroupChangeListener);
- }
-
- /**
- * Whether or not a notification has transferred its alert state to the notification and
- * the notification should alert after inflating.
- *
- * @param entry notification to check
- * @return true if the entry was transferred to and should inflate + alert
- */
- public boolean isAlertTransferPending(@NonNull NotificationEntry entry) {
- PendingAlertInfo alertInfo = mPendingAlerts.get(entry.getKey());
- return alertInfo != null && alertInfo.isStillValid();
- }
-
- public void setHeadsUpManager(HeadsUpManager headsUpManager) {
- mHeadsUpManager = headsUpManager;
- }
-
- @Override
- public void onStateChanged(int newState) {}
-
- @Override
- public void onDozingChanged(boolean isDozing) {
- if (mIsDozing != isDozing) {
- for (GroupAlertEntry groupAlertEntry : mGroupAlertEntries.values()) {
- groupAlertEntry.mLastAlertTransferTime = 0;
- groupAlertEntry.mAlertSummaryOnNextAddition = false;
- }
- }
- mIsDozing = isDozing;
- }
-
- private final NotificationGroupManagerLegacy.OnGroupChangeListener mOnGroupChangeListener =
- new NotificationGroupManagerLegacy.OnGroupChangeListener() {
- @Override
- public void onGroupCreated(NotificationGroup group, String groupKey) {
- mGroupAlertEntries.put(groupKey, new GroupAlertEntry(group));
- }
-
- @Override
- public void onGroupRemoved(NotificationGroup group, String groupKey) {
- mGroupAlertEntries.remove(groupKey);
- }
-
- @Override
- public void onGroupSuppressionChanged(NotificationGroup group, boolean suppressed) {
- if (DEBUG) {
- Log.d(TAG, "!! onGroupSuppressionChanged:"
- + " group=" + logGroupKey(group)
- + " group.summary=" + logKey(group.summary)
- + " suppressed=" + suppressed);
- }
- NotificationEntry oldAlertOverride = group.alertOverride;
- onGroupChanged(group, oldAlertOverride);
- }
-
- @Override
- public void onGroupAlertOverrideChanged(NotificationGroup group,
- @Nullable NotificationEntry oldAlertOverride,
- @Nullable NotificationEntry newAlertOverride) {
- if (DEBUG) {
- Log.d(TAG, "!! onGroupAlertOverrideChanged:"
- + " group=" + logGroupKey(group)
- + " group.summary=" + logKey(group.summary)
- + " oldAlertOverride=" + logKey(oldAlertOverride)
- + " newAlertOverride=" + logKey(newAlertOverride));
- }
- onGroupChanged(group, oldAlertOverride);
- }
- };
-
- /**
- * Called when either the suppressed or alertOverride fields of the group changed
- *
- * @param group the group which changed
- * @param oldAlertOverride the previous value of group.alertOverride
- */
- private void onGroupChanged(NotificationGroup group,
- NotificationEntry oldAlertOverride) {
- // Group summary can be null if we are no longer suppressed because the summary was
- // removed. In that case, we don't need to alert the summary.
- if (group.summary == null) {
- if (DEBUG) {
- Log.d(TAG, "onGroupChanged: summary is null");
- }
- return;
- }
- if (group.suppressed || group.alertOverride != null) {
- checkForForwardAlertTransfer(group.summary, oldAlertOverride);
- } else {
- if (DEBUG) {
- Log.d(TAG, "onGroupChanged: maybe transfer back");
- }
- GroupAlertEntry groupAlertEntry = mGroupAlertEntries.get(mGroupManager.getGroupKey(
- group.summary.getSbn()));
- // Group is no longer suppressed or overridden.
- // We should check if we need to transfer the alert back to the summary.
- if (groupAlertEntry.mAlertSummaryOnNextAddition) {
- if (!mHeadsUpManager.isAlerting(group.summary.getKey())) {
- alertNotificationWhenPossible(group.summary);
- }
- groupAlertEntry.mAlertSummaryOnNextAddition = false;
- } else {
- checkShouldTransferBack(groupAlertEntry);
- }
- }
- }
-
- @Override
- public void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) {
- if (DEBUG) {
- Log.d(TAG, "!! onHeadsUpStateChanged:"
- + " entry=" + logKey(entry)
- + " isHeadsUp=" + isHeadsUp);
- }
- if (isHeadsUp && entry.getSbn().getNotification().isGroupSummary()) {
- // a group summary is alerting; trigger the forward transfer checks
- checkForForwardAlertTransfer(entry, /* oldAlertOverride */ null);
- }
- }
-
- /**
- * Handles changes in a group's suppression or alertOverride, but where at least one of those
- * conditions is still true (either the group is suppressed, the group has an alertOverride,
- * or both). The method determined which kind of child needs to receive the alert, finds the
- * entry currently alerting, and makes the transfer.
- *
- * Internally, this is handled with two main cases: the override needs the alert, or there is
- * no override but the summary is suppressed (so an isolated child needs the alert).
- *
- * @param summary the notification entry of the summary of the logical group.
- * @param oldAlertOverride the former value of group.alertOverride, before whatever event
- * required us to check for for a transfer condition.
- */
- private void checkForForwardAlertTransfer(NotificationEntry summary,
- NotificationEntry oldAlertOverride) {
- if (DEBUG) {
- Log.d(TAG, "checkForForwardAlertTransfer: enter");
- }
- NotificationGroup group = mGroupManager.getGroupForSummary(summary.getSbn());
- if (group != null && group.alertOverride != null) {
- handleOverriddenSummaryAlerted(summary);
- } else if (mGroupManager.isSummaryOfSuppressedGroup(summary.getSbn())) {
- handleSuppressedSummaryAlerted(summary, oldAlertOverride);
- }
- if (DEBUG) {
- Log.d(TAG, "checkForForwardAlertTransfer: done");
- }
- }
-
- private final NotificationEntryListener mNotificationEntryListener =
- new NotificationEntryListener() {
- // Called when a new notification has been posted but is not inflated yet. We use this to
- // see as early as we can if we need to abort a transfer.
- @Override
- public void onPendingEntryAdded(NotificationEntry entry) {
- if (DEBUG) {
- Log.d(TAG, "!! onPendingEntryAdded: entry=" + logKey(entry));
- }
- String groupKey = mGroupManager.getGroupKey(entry.getSbn());
- GroupAlertEntry groupAlertEntry = mGroupAlertEntries.get(groupKey);
- if (groupAlertEntry != null && groupAlertEntry.mGroup.alertOverride == null) {
- // new pending group entries require us to transfer back from the child to the
- // group, but alertOverrides are only present in very limited circumstances, so
- // while it's possible the group should ALSO alert, the previous detection which set
- // this alertOverride won't be invalidated by this notification added to this group.
- checkShouldTransferBack(groupAlertEntry);
- }
- }
-
- @Override
- public void onEntryRemoved(
- @Nullable NotificationEntry entry,
- NotificationVisibility visibility,
- boolean removedByUser,
- int reason) {
- // Removes any alerts pending on this entry. Note that this will not stop any inflation
- // tasks started by a transfer, so this should only be used as clean-up for when
- // inflation is stopped and the pending alert no longer needs to happen.
- mPendingAlerts.remove(entry.getKey());
- }
- };
-
- /**
- * Gets the number of new notifications pending inflation that will be added to the group
- * but currently aren't and should not alert.
- *
- * @param group group to check
- * @return the number of new notifications that will be added to the group
- */
- private int getPendingChildrenNotAlerting(@NonNull NotificationGroup group) {
- if (mEntryManager == null) {
- return 0;
- }
- int number = 0;
- Iterable<NotificationEntry> values = mEntryManager.getPendingNotificationsIterator();
- for (NotificationEntry entry : values) {
- if (isPendingNotificationInGroup(entry, group) && onlySummaryAlerts(entry)) {
- number++;
- }
- }
- return number;
- }
-
- /**
- * Checks if the pending inflations will add children to this group.
- *
- * @param group group to check
- * @return true if a pending notification will add to this group
- */
- private boolean pendingInflationsWillAddChildren(@NonNull NotificationGroup group) {
- if (mEntryManager == null) {
- return false;
- }
- Iterable<NotificationEntry> values = mEntryManager.getPendingNotificationsIterator();
- for (NotificationEntry entry : values) {
- if (isPendingNotificationInGroup(entry, group)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Checks if a new pending notification will be added to the group.
- *
- * @param entry pending notification
- * @param group group to check
- * @return true if the notification will add to the group, false o/w
- */
- private boolean isPendingNotificationInGroup(@NonNull NotificationEntry entry,
- @NonNull NotificationGroup group) {
- String groupKey = mGroupManager.getGroupKey(group.summary.getSbn());
- return mGroupManager.isGroupChild(entry.getSbn())
- && Objects.equals(mGroupManager.getGroupKey(entry.getSbn()), groupKey)
- && !group.children.containsKey(entry.getKey());
- }
-
- /**
- * Handles the scenario where a summary that has been suppressed is itself, or has a former
- * alertOverride (in the form of an isolated logical child) which was alerted. A suppressed
- * summary should for all intents and purposes be invisible to the user and as a result should
- * not alert. When this is the case, it is our responsibility to pass the alert to the
- * appropriate child which will be the representative notification alerting for the group.
- *
- * @param summary the summary that is suppressed and (potentially) alerting
- * @param oldAlertOverride the alertOverride before whatever event triggered this method. If
- * the alert override was removed, this will be the entry that should
- * be transferred back from.
- */
- private void handleSuppressedSummaryAlerted(@NonNull NotificationEntry summary,
- NotificationEntry oldAlertOverride) {
- if (DEBUG) {
- Log.d(TAG, "handleSuppressedSummaryAlerted: summary=" + logKey(summary));
- }
- GroupAlertEntry groupAlertEntry =
- mGroupAlertEntries.get(mGroupManager.getGroupKey(summary.getSbn()));
-
- if (!mGroupManager.isSummaryOfSuppressedGroup(summary.getSbn())
- || groupAlertEntry == null) {
- if (DEBUG) {
- Log.d(TAG, "handleSuppressedSummaryAlerted: invalid state");
- }
- return;
- }
- boolean summaryIsAlerting = mHeadsUpManager.isAlerting(summary.getKey());
- boolean priorityIsAlerting = oldAlertOverride != null
- && mHeadsUpManager.isAlerting(oldAlertOverride.getKey());
- if (!summaryIsAlerting && !priorityIsAlerting) {
- if (DEBUG) {
- Log.d(TAG, "handleSuppressedSummaryAlerted: no summary or override alerting");
- }
- return;
- }
-
- if (pendingInflationsWillAddChildren(groupAlertEntry.mGroup)) {
- // New children will actually be added to this group, let's not transfer the alert.
- if (DEBUG) {
- Log.d(TAG, "handleSuppressedSummaryAlerted: pending inflations");
- }
- return;
- }
-
- NotificationEntry child =
- mGroupManager.getLogicalChildren(summary.getSbn()).iterator().next();
- if (summaryIsAlerting) {
- if (DEBUG) {
- Log.d(TAG, "handleSuppressedSummaryAlerted: transfer summary -> child");
- }
- tryTransferAlertState(summary, /*from*/ summary, /*to*/ child, groupAlertEntry);
- return;
- }
- // Summary didn't have the alert, so we're in "transfer back" territory. First, make sure
- // it's not too late to transfer back, then transfer the alert from the oldAlertOverride to
- // the isolated child which should receive the alert.
- if (!canStillTransferBack(groupAlertEntry)) {
- if (DEBUG) {
- Log.d(TAG, "handleSuppressedSummaryAlerted: transfer from override: too late");
- }
- return;
- }
-
- if (DEBUG) {
- Log.d(TAG, "handleSuppressedSummaryAlerted: transfer override -> child");
- }
- tryTransferAlertState(summary, /*from*/ oldAlertOverride, /*to*/ child, groupAlertEntry);
- }
-
- /**
- * Checks for and handles the scenario where the given entry is the summary of a group which
- * has an alertOverride, and either the summary itself or one of its logical isolated children
- * is currently alerting (which happens if the summary is suppressed).
- */
- private void handleOverriddenSummaryAlerted(NotificationEntry summary) {
- if (DEBUG) {
- Log.d(TAG, "handleOverriddenSummaryAlerted: summary=" + logKey(summary));
- }
- GroupAlertEntry groupAlertEntry =
- mGroupAlertEntries.get(mGroupManager.getGroupKey(summary.getSbn()));
- NotificationGroup group = mGroupManager.getGroupForSummary(summary.getSbn());
- if (group == null || group.alertOverride == null || groupAlertEntry == null) {
- if (DEBUG) {
- Log.d(TAG, "handleOverriddenSummaryAlerted: invalid state");
- }
- return;
- }
- boolean summaryIsAlerting = mHeadsUpManager.isAlerting(summary.getKey());
- if (summaryIsAlerting) {
- if (DEBUG) {
- Log.d(TAG, "handleOverriddenSummaryAlerted: transfer summary -> override");
- }
- tryTransferAlertState(summary, /*from*/ summary, group.alertOverride, groupAlertEntry);
- return;
- }
- // Summary didn't have the alert, so we're in "transfer back" territory. First, make sure
- // it's not too late to transfer back, then remove the alert from any of the logical
- // children, and if one of them was alerting, we can alert the override.
- if (!canStillTransferBack(groupAlertEntry)) {
- if (DEBUG) {
- Log.d(TAG, "handleOverriddenSummaryAlerted: transfer from child: too late");
- }
- return;
- }
- List<NotificationEntry> children = mGroupManager.getLogicalChildren(summary.getSbn());
- if (children == null) {
- if (DEBUG) {
- Log.d(TAG, "handleOverriddenSummaryAlerted: no children");
- }
- return;
- }
- children.remove(group.alertOverride); // do not release the alert on our desired destination
- boolean releasedChild = releaseChildAlerts(children);
- if (releasedChild) {
- if (DEBUG) {
- Log.d(TAG, "handleOverriddenSummaryAlerted: transfer child -> override");
- }
- tryTransferAlertState(summary, /*from*/ null, group.alertOverride, groupAlertEntry);
- } else {
- if (DEBUG) {
- Log.d(TAG, "handleOverriddenSummaryAlerted: no child alert released");
- }
- }
- }
-
- /**
- * Transfers the alert state one entry to another. We remove the alert from the first entry
- * immediately to have the incorrect one up as short as possible. The second should alert
- * when possible.
- *
- * @param summary entry of the summary
- * @param fromEntry entry to transfer alert from
- * @param toEntry entry to transfer to
- */
- private void tryTransferAlertState(
- NotificationEntry summary,
- NotificationEntry fromEntry,
- NotificationEntry toEntry,
- GroupAlertEntry groupAlertEntry) {
- if (toEntry != null) {
- if (toEntry.getRow().keepInParent()
- || toEntry.isRowRemoved()
- || toEntry.isRowDismissed()) {
- // The notification is actually already removed. No need to alert it.
- return;
- }
- if (!mHeadsUpManager.isAlerting(toEntry.getKey()) && onlySummaryAlerts(summary)) {
- groupAlertEntry.mLastAlertTransferTime = SystemClock.elapsedRealtime();
- }
- if (DEBUG) {
- Log.d(TAG, "transferAlertState:"
- + " fromEntry=" + logKey(fromEntry)
- + " toEntry=" + logKey(toEntry));
- }
- transferAlertState(fromEntry, toEntry);
- }
- }
- private void transferAlertState(@Nullable NotificationEntry fromEntry,
- @NonNull NotificationEntry toEntry) {
- if (fromEntry != null) {
- mHeadsUpManager.removeNotification(fromEntry.getKey(), true /* releaseImmediately */);
- }
- alertNotificationWhenPossible(toEntry);
- }
-
- /**
- * Determines if we need to transfer the alert back to the summary from the child and does
- * so if needed.
- *
- * This can happen since notification groups are not delivered as a whole unit and it is
- * possible we erroneously transfer the alert from the summary to the child even though
- * more children are coming. Thus, if a child is added within a certain timeframe after we
- * transfer, we back out and alert the summary again.
- *
- * An alert can only transfer back within a small window of time after a transfer away from the
- * summary to a child happened.
- *
- * @param groupAlertEntry group alert entry to check
- */
- private void checkShouldTransferBack(@NonNull GroupAlertEntry groupAlertEntry) {
- if (canStillTransferBack(groupAlertEntry)) {
- NotificationEntry summary = groupAlertEntry.mGroup.summary;
-
- if (!onlySummaryAlerts(summary)) {
- return;
- }
- ArrayList<NotificationEntry> children = mGroupManager.getLogicalChildren(
- summary.getSbn());
- int numActiveChildren = children.size();
- int numPendingChildren = getPendingChildrenNotAlerting(groupAlertEntry.mGroup);
- int numChildren = numActiveChildren + numPendingChildren;
- if (numChildren <= 1) {
- return;
- }
- boolean releasedChild = releaseChildAlerts(children);
- if (releasedChild && !mHeadsUpManager.isAlerting(summary.getKey())) {
- boolean notifyImmediately = numActiveChildren > 1;
- if (notifyImmediately) {
- alertNotificationWhenPossible(summary);
- } else {
- // Should wait until the pending child inflates before alerting.
- groupAlertEntry.mAlertSummaryOnNextAddition = true;
- }
- groupAlertEntry.mLastAlertTransferTime = 0;
- }
- }
- }
-
- private boolean canStillTransferBack(@NonNull GroupAlertEntry groupAlertEntry) {
- return SystemClock.elapsedRealtime() - groupAlertEntry.mLastAlertTransferTime
- < ALERT_TRANSFER_TIMEOUT;
- }
-
- private boolean releaseChildAlerts(List<NotificationEntry> children) {
- boolean releasedChild = false;
- if (SPEW) {
- Log.d(TAG, "releaseChildAlerts: numChildren=" + children.size());
- }
- for (int i = 0; i < children.size(); i++) {
- NotificationEntry entry = children.get(i);
- if (SPEW) {
- Log.d(TAG, "releaseChildAlerts: checking i=" + i + " entry=" + entry
- + " onlySummaryAlerts=" + onlySummaryAlerts(entry)
- + " isAlerting=" + mHeadsUpManager.isAlerting(entry.getKey())
- + " isPendingAlert=" + mPendingAlerts.containsKey(entry.getKey()));
- }
- if (onlySummaryAlerts(entry) && mHeadsUpManager.isAlerting(entry.getKey())) {
- releasedChild = true;
- mHeadsUpManager.removeNotification(
- entry.getKey(), true /* releaseImmediately */);
- }
- if (mPendingAlerts.containsKey(entry.getKey())) {
- // This is the child that would've been removed if it was inflated.
- releasedChild = true;
- mPendingAlerts.get(entry.getKey()).mAbortOnInflation = true;
- }
- }
- if (SPEW) {
- Log.d(TAG, "releaseChildAlerts: didRelease=" + releasedChild);
- }
- return releasedChild;
- }
-
- /**
- * Tries to alert the notification. If its content view is not inflated, we inflate and continue
- * when the entry finishes inflating the view.
- *
- * @param entry entry to show
- */
- private void alertNotificationWhenPossible(@NonNull NotificationEntry entry) {
- @InflationFlag int contentFlag = mHeadsUpManager.getContentFlag();
- final RowContentBindParams params = mRowContentBindStage.getStageParams(entry);
- if ((params.getContentViews() & contentFlag) == 0) {
- if (DEBUG) {
- Log.d(TAG, "alertNotificationWhenPossible:"
- + " async requestRebind entry=" + logKey(entry));
- }
- mPendingAlerts.put(entry.getKey(), new PendingAlertInfo(entry));
- params.requireContentViews(contentFlag);
- mRowContentBindStage.requestRebind(entry, en -> {
- PendingAlertInfo alertInfo = mPendingAlerts.remove(entry.getKey());
- if (alertInfo != null) {
- if (alertInfo.isStillValid()) {
- alertNotificationWhenPossible(entry);
- } else {
- if (DEBUG) {
- Log.d(TAG, "alertNotificationWhenPossible:"
- + " markContentViewsFreeable entry=" + logKey(entry));
- }
- // The transfer is no longer valid. Free the content.
- mRowContentBindStage.getStageParams(entry).markContentViewsFreeable(
- contentFlag);
- mRowContentBindStage.requestRebind(entry, null);
- }
- }
- });
- return;
- }
- if (mHeadsUpManager.isAlerting(entry.getKey())) {
- if (DEBUG) {
- Log.d(TAG, "alertNotificationWhenPossible:"
- + " continue alerting entry=" + logKey(entry));
- }
- mHeadsUpManager.updateNotification(entry.getKey(), true /* alert */);
- } else {
- if (DEBUG) {
- Log.d(TAG, "alertNotificationWhenPossible:"
- + " start alerting entry=" + logKey(entry));
- }
- mHeadsUpManager.showNotification(entry);
- }
- }
-
- private boolean onlySummaryAlerts(NotificationEntry entry) {
- return entry.getSbn().getNotification().getGroupAlertBehavior()
- == Notification.GROUP_ALERT_SUMMARY;
- }
-
- /**
- * Information about a pending alert used to determine if the alert is still needed when
- * inflation completes.
- */
- private class PendingAlertInfo {
-
- /**
- * The original notification when the transfer is initiated. This is used to determine if
- * the transfer is still valid if the notification is updated.
- */
- final StatusBarNotification mOriginalNotification;
- final NotificationEntry mEntry;
-
- /**
- * The notification is still pending inflation but we've decided that we no longer need
- * the content view (e.g. suppression might have changed and we decided we need to transfer
- * back).
- *
- * TODO: Replace this entire structure with {@link RowContentBindStage#requestRebind)}.
- */
- boolean mAbortOnInflation;
-
- PendingAlertInfo(NotificationEntry entry) {
- mOriginalNotification = entry.getSbn();
- mEntry = entry;
- }
-
- /**
- * Whether or not the pending alert is still valid and should still alert after inflation.
- *
- * @return true if the pending alert should still occur, false o/w
- */
- private boolean isStillValid() {
- if (mAbortOnInflation) {
- // Notification is aborted due to the transfer being explicitly cancelled
- return false;
- }
- if (!mEntry.getSbn().getGroupKey().equals(mOriginalNotification.getGroupKey())) {
- // Groups have changed
- return false;
- }
- if (mEntry.getSbn().getNotification().isGroupSummary()
- != mOriginalNotification.getNotification().isGroupSummary()) {
- // Notification has changed from group summary to not or vice versa
- return false;
- }
- return true;
- }
- }
-
- /**
- * Contains alert metadata for the notification group used to determine when/how the alert
- * should be transferred.
- */
- private static class GroupAlertEntry {
- /**
- * The time when the last alert transfer from summary to child happened.
- */
- long mLastAlertTransferTime;
- boolean mAlertSummaryOnNextAddition;
- final NotificationGroup mGroup;
-
- GroupAlertEntry(NotificationGroup group) {
- this.mGroup = group;
- }
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
index d414660018a8..2aab9e82986e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
@@ -43,7 +43,6 @@ import android.widget.TextView;
import androidx.core.graphics.drawable.IconCompat;
import androidx.test.filters.SmallTest;
-import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
@@ -54,7 +53,7 @@ import com.android.systemui.animation.DialogLaunchAnimator;
import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
import org.junit.Before;
import org.junit.Test;
@@ -83,8 +82,7 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase {
LocalBluetoothLeBroadcast.class);
private ActivityStarter mStarter = mock(ActivityStarter.class);
private BroadcastSender mBroadcastSender = mock(BroadcastSender.class);
- private NotificationEntryManager mNotificationEntryManager =
- mock(NotificationEntryManager.class);
+ private final CommonNotifCollection mNotifCollection = mock(CommonNotifCollection.class);
private NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock(
NearbyMediaDevicesManager.class);
private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class);
@@ -120,7 +118,7 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase {
mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE,
mMediaSessionManager, mLocalBluetoothManager, mStarter,
- mNotificationEntryManager, mDialogLaunchAnimator,
+ mNotifCollection, mDialogLaunchAnimator,
Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager);
mMediaOutputBaseDialogImpl = new MediaOutputBaseDialogImpl(mContext, mBroadcastSender,
mMediaOutputController);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
index 6afed1a846b0..4779d322a90e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
@@ -47,7 +47,7 @@ import com.android.systemui.animation.DialogLaunchAnimator;
import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
import org.junit.After;
import org.junit.Before;
@@ -78,8 +78,7 @@ public class MediaOutputDialogTest extends SysuiTestCase {
private final BroadcastSender mBroadcastSender = mock(BroadcastSender.class);
private final LocalMediaManager mLocalMediaManager = mock(LocalMediaManager.class);
private final MediaDevice mMediaDevice = mock(MediaDevice.class);
- private final NotificationEntryManager mNotificationEntryManager =
- mock(NotificationEntryManager.class);
+ private final CommonNotifCollection mNotifCollection = mock(CommonNotifCollection.class);
private final UiEventLogger mUiEventLogger = mock(UiEventLogger.class);
private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class);
private final NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock(
@@ -104,7 +103,7 @@ public class MediaOutputDialogTest extends SysuiTestCase {
mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE,
mMediaSessionManager, mLocalBluetoothManager, mStarter,
- mNotificationEntryManager, mDialogLaunchAnimator,
+ mNotifCollection, mDialogLaunchAnimator,
Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager);
mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
mMediaOutputDialog = new MediaOutputDialog(mContext, false, mBroadcastSender,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
index fba19861b006..bd913bab6f65 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
@@ -63,7 +63,6 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
import com.android.systemui.people.widget.PeopleTileKey;
import com.android.systemui.statusbar.NotificationListener;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
@@ -196,8 +195,6 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
@Mock
private PackageManager mPackageManager;
@Mock
- private NotificationEntryManager mNotificationEntryManager;
- @Mock
private PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
@Mock
private BackupManager mBackupManager;
@@ -234,8 +231,6 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
when(mMockContext.getString(R.string.over_two_weeks_timestamp)).thenReturn(
mContext.getString(R.string.over_two_weeks_timestamp));
when(mPackageManager.getApplicationIcon(anyString())).thenReturn(null);
- when(mNotificationEntryManager.getVisibleNotifications())
- .thenReturn(List.of(mNotificationEntry1, mNotificationEntry2, mNotificationEntry3));
}
@After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
index 8a388479c0e7..98de1763825f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
@@ -25,7 +25,6 @@ import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
import android.app.ActivityManager;
import android.app.Notification;
@@ -218,41 +217,4 @@ public class AlertingNotificationManagerTest extends SysuiTestCase {
// The entry has just been added so we should not remove immediately.
assertFalse(mAlertingNotificationManager.canRemoveImmediately(mEntry.getKey()));
}
-
- @Test
- public void testShouldExtendLifetime() {
- mAlertingNotificationManager.showNotification(mEntry);
-
- // While the entry is alerting, it should not be removable.
- assertTrue(mAlertingNotificationManager.shouldExtendLifetime(mEntry));
- }
-
- @Test
- public void testSetShouldManageLifetime_setShouldManage() {
- mAlertingNotificationManager.showNotification(mEntry);
-
- mAlertingNotificationManager.setShouldManageLifetime(mEntry, true /* shouldManage */);
-
- assertTrue(mAlertingNotificationManager.mExtendedLifetimeAlertEntries.contains(mEntry));
- }
-
- @Test
- public void testSetShouldManageLifetime_setShouldManageCallsRemoval() {
- mAlertingNotificationManager.showNotification(mEntry);
- mAlertingNotificationManager.setShouldManageLifetime(mEntry, true /* shouldManage */);
- if (mAlertingNotificationManager instanceof TestableAlertingNotificationManager) {
- TestableAlertingNotificationManager testableManager =
- (TestableAlertingNotificationManager) mAlertingNotificationManager;
- verify(testableManager.mLastCreatedEntry).removeAsSoonAsPossible();
- }
- }
-
- @Test
- public void testSetShouldManageLifetime_setShouldNotManage() {
- mAlertingNotificationManager.mExtendedLifetimeAlertEntries.add(mEntry);
-
- mAlertingNotificationManager.setShouldManageLifetime(mEntry, false /* shouldManage */);
-
- assertFalse(mAlertingNotificationManager.mExtendedLifetimeAlertEntries.contains(mEntry));
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
index 34d13c76399a..6e29669a227b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
@@ -161,10 +161,8 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase {
smartReplyController,
visibilityProvider,
notificationEntryManager,
- rebuilder,
centralSurfacesOptionalLazy,
statusBarStateController,
- mainHandler,
remoteInputUriController,
clickNotifier,
actionClickLogger,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
deleted file mode 100644
index 842f057b96fc..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ /dev/null
@@ -1,684 +0,0 @@
-/*
- * Copyright (C) 2017 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;
-
-import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
-import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED;
-import static android.service.notification.NotificationListenerService.REASON_CANCEL;
-import static android.service.notification.NotificationStats.DISMISSAL_SHADE;
-import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
-
-import static com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.app.ActivityManager;
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.PendingIntent;
-import android.content.Intent;
-import android.graphics.drawable.Icon;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.service.notification.NotificationListenerService.Ranking;
-import android.service.notification.NotificationListenerService.RankingMap;
-import android.service.notification.StatusBarNotification;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.util.ArraySet;
-
-import androidx.annotation.NonNull;
-import androidx.test.filters.SmallTest;
-
-import com.android.internal.statusbar.IStatusBarService;
-import com.android.internal.statusbar.NotificationVisibility;
-import com.android.systemui.Dependency;
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.dump.DumpManager;
-import com.android.systemui.statusbar.NotificationLifetimeExtender;
-import com.android.systemui.statusbar.NotificationListener;
-import com.android.systemui.statusbar.NotificationMediaManager;
-import com.android.systemui.statusbar.NotificationPresenter;
-import com.android.systemui.statusbar.NotificationRemoteInputManager;
-import com.android.systemui.statusbar.NotificationRemoveInterceptor;
-import com.android.systemui.statusbar.SmartReplyController;
-import com.android.systemui.statusbar.notification.NotificationEntryManager.KeyguardEnvironment;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
-import com.android.systemui.statusbar.notification.collection.NotificationRankingManager;
-import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
-import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
-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.HighPriorityProvider;
-import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.notification.row.RowInflaterTask;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.leak.LeakDetector;
-import com.android.systemui.util.time.FakeSystemClock;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatcher;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Unit tests for {@link NotificationEntryManager}.
- */
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper()
-public class NotificationEntryManagerTest extends SysuiTestCase {
- private static final String TEST_PACKAGE_NAME = "test";
- private static final int TEST_UID = 0;
-
- @Mock private NotificationPresenter mPresenter;
- @Mock private KeyguardEnvironment mEnvironment;
- @Mock private ExpandableNotificationRow mRow;
- @Mock private NotificationEntryListener mEntryListener;
- @Mock private NotifCollectionListener mNotifCollectionListener;
- @Mock private NotificationRemoveInterceptor mRemoveInterceptor;
- @Mock private HeadsUpManager mHeadsUpManager;
- @Mock private RankingMap mRankingMap;
- @Mock private NotificationGroupManagerLegacy mGroupManager;
- @Mock private NotificationRemoteInputManager mRemoteInputManager;
- @Mock private DeviceProvisionedController mDeviceProvisionedController;
- @Mock private RowInflaterTask mAsyncInflationTask;
- @Mock private NotificationEntryManagerLogger mLogger;
- @Mock private NotifPipelineFlags mNotifPipelineFlags;
- @Mock private LeakDetector mLeakDetector;
- @Mock private NotificationMediaManager mNotificationMediaManager;
- @Mock private NotificationRowBinder mNotificationRowBinder;
- @Mock private NotificationListener mNotificationListener;
- @Mock private IStatusBarService mStatusBarService;
-
- private FakeSystemClock mFakeSystemClock = new FakeSystemClock();
- private FakeExecutor mBgExecutor = new FakeExecutor(mFakeSystemClock);
-
- private int mId;
- private NotificationEntry mEntry;
- private DismissedByUserStats mStats;
- private StatusBarNotification mSbn;
- private NotificationEntryManager mEntryManager;
-
- private void setUserSentiment(String key, int sentiment) {
- doAnswer(invocationOnMock -> {
- Ranking ranking = (Ranking)
- invocationOnMock.getArguments()[1];
- ranking.populate(
- key,
- 0,
- false,
- 0,
- 0,
- IMPORTANCE_DEFAULT,
- null, null,
- null, null, null, true, sentiment, false, -1, false, null, null, false, false,
- false, null, 0, false);
- return true;
- }).when(mRankingMap).getRanking(eq(key), any(Ranking.class));
- }
-
- private void setSmartActions(String key, ArrayList<Notification.Action> smartActions) {
- doAnswer(invocationOnMock -> {
- Ranking ranking = (Ranking)
- invocationOnMock.getArguments()[1];
- ranking.populate(
- key,
- 0,
- false,
- 0,
- 0,
- IMPORTANCE_DEFAULT,
- null, null,
- null, null, null, true,
- Ranking.USER_SENTIMENT_NEUTRAL, false, -1,
- false, smartActions, null, false, false, false, null, 0, false);
- return true;
- }).when(mRankingMap).getRanking(eq(key), any(Ranking.class));
- }
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mDependency.injectMockDependency(SmartReplyController.class);
-
- allowTestableLooperAsMainThread();
- mDependency.injectTestDependency(Dependency.MAIN_HANDLER,
- Handler.createAsync(TestableLooper.get(this).getLooper()));
-
- mEntry = createNotification();
- mStats = defaultStats(mEntry);
- mSbn = mEntry.getSbn();
-
- mEntryManager = new NotificationEntryManager(
- mLogger,
- mGroupManager,
- mNotifPipelineFlags,
- () -> mNotificationRowBinder,
- () -> mRemoteInputManager,
- mLeakDetector,
- mStatusBarService,
- mock(DumpManager.class),
- mBgExecutor
- );
- mEntryManager.initialize(
- mNotificationListener,
- new NotificationRankingManager(
- () -> mNotificationMediaManager,
- mGroupManager,
- mHeadsUpManager,
- mock(NotificationFilter.class),
- mLogger,
- mock(NotificationSectionsFeatureManager.class),
- mock(PeopleNotificationIdentifier.class),
- mock(HighPriorityProvider.class),
- mEnvironment));
- mEntryManager.addNotificationEntryListener(mEntryListener);
- mEntryManager.addCollectionListener(mNotifCollectionListener);
- mEntryManager.addNotificationRemoveInterceptor(mRemoveInterceptor);
-
- setUserSentiment(mSbn.getKey(), Ranking.USER_SENTIMENT_NEUTRAL);
- }
-
- @Test
- public void testAddNotification_noDuplicateEntriesCreated() {
- // GIVEN a notification has been added
- mEntryManager.addNotification(mSbn, mRankingMap);
-
- // WHEN the same notification is added multiple times before the previous entry (with
- // the same key) didn't finish inflating
- mEntryManager.addNotification(mSbn, mRankingMap);
- mEntryManager.addNotification(mSbn, mRankingMap);
- mEntryManager.addNotification(mSbn, mRankingMap);
-
- // THEN getAllNotifs() only contains exactly one notification with this key
- int count = 0;
- for (NotificationEntry entry : mEntryManager.getAllNotifs()) {
- if (entry.getKey().equals(mSbn.getKey())) {
- count++;
- }
- }
- assertEquals("Should only be one entry with key=" + mSbn.getKey() + " in mAllNotifs. "
- + "Instead there are " + count, 1, count);
- }
-
- @Test
- public void testAddNotification_setsUserSentiment() {
- mEntryManager.addNotification(mSbn, mRankingMap);
-
- ArgumentCaptor<NotificationEntry> entryCaptor = ArgumentCaptor.forClass(
- NotificationEntry.class);
- verify(mEntryListener).onPendingEntryAdded(entryCaptor.capture());
- NotificationEntry entry = entryCaptor.getValue();
-
- assertEquals(entry.getUserSentiment(), Ranking.USER_SENTIMENT_NEUTRAL);
- }
-
- @Test
- public void testUpdateNotification_prePostEntryOrder() throws Exception {
- TestableLooper.get(this).processAllMessages();
-
- mEntryManager.addActiveNotificationForTest(mEntry);
-
- mEntryManager.updateNotification(mSbn, mRankingMap);
-
- // Ensure that update callbacks happen in correct order
- InOrder order = inOrder(mEntryListener, mPresenter, mEntryListener);
- order.verify(mEntryListener).onPreEntryUpdated(mEntry);
- order.verify(mEntryListener).onPostEntryUpdated(mEntry);
- }
-
- @Test
- public void testRemoveNotification() {
- mEntry.setRow(mRow);
- mEntryManager.addActiveNotificationForTest(mEntry);
-
- mEntryManager.removeNotification(mSbn.getKey(), mRankingMap, UNDEFINED_DISMISS_REASON);
-
- verify(mEntryListener).onEntryRemoved(
- argThat(matchEntryOnKey()), any(),
- eq(false) /* removedByUser */, eq(UNDEFINED_DISMISS_REASON));
- verify(mRow).setRemoved();
-
- assertNull(mEntryManager.getActiveNotificationUnfiltered(mSbn.getKey()));
- }
-
- @Test
- public void testRemoveUninflatedNotification_removesNotificationFromAllNotifsList() {
- // GIVEN an uninflated entry is added
- mEntryManager.addNotification(mSbn, mRankingMap);
- assertTrue(entriesContainKey(mEntryManager.getAllNotifs(), mSbn.getKey()));
-
- // WHEN the uninflated entry is removed
- mEntryManager.performRemoveNotification(mSbn, mock(DismissedByUserStats.class),
- UNDEFINED_DISMISS_REASON);
-
- // THEN the entry is still removed from the allNotifications list
- assertFalse(entriesContainKey(mEntryManager.getAllNotifs(), mSbn.getKey()));
- }
-
- @Test
- public void testPerformRemoveNotification_sendRemovalToServer() throws RemoteException {
- // GIVEN an entry manager with a notification
- mEntryManager.addActiveNotificationForTest(mEntry);
-
- // GIVEN interceptor that doesn't intercept
- when(mRemoveInterceptor.onNotificationRemoveRequested(
- eq(mEntry.getKey()), argThat(matchEntryOnKey()), anyInt()))
- .thenReturn(false);
-
- // WHEN the notification entry is removed
- mEntryManager.performRemoveNotification(mSbn, mStats, REASON_CANCEL);
-
- // THEN notification removal is sent to the server
- FakeExecutor.exhaustExecutors(mBgExecutor);
- verify(mStatusBarService).onNotificationClear(
- mSbn.getPackageName(),
- mSbn.getUser().getIdentifier(),
- mSbn.getKey(),
- mStats.dismissalSurface,
- mStats.dismissalSentiment,
- mStats.notificationVisibility);
- verifyNoMoreInteractions(mStatusBarService);
- }
-
- @Test
- public void testRemoveNotification_onEntryRemoveNotFiredIfEntryDoesntExist() {
-
- mEntryManager.removeNotification("not_a_real_key", mRankingMap, UNDEFINED_DISMISS_REASON);
-
- verify(mEntryListener, never()).onEntryRemoved(argThat(matchEntryOnKey()), any(),
- eq(false) /* removedByUser */, eq(UNDEFINED_DISMISS_REASON));
- }
-
- /** Regression test for b/201097913. */
- @Test
- public void testRemoveNotification_whilePending_onlyCollectionListenerNotified() {
- // Add and then remove a pending entry (entry that hasn't been inflated).
- mEntryManager.addNotification(mSbn, mRankingMap);
- mEntryManager.removeNotification(mSbn.getKey(), mRankingMap, UNDEFINED_DISMISS_REASON);
-
- // Verify that only the listener for the NEW pipeline is notified.
- // Old pipeline:
- verify(mEntryListener, never()).onEntryRemoved(
- argThat(matchEntryOnKey()), any(), anyBoolean(), anyInt());
- // New pipeline:
- verify(mNotifCollectionListener).onEntryRemoved(
- argThat(matchEntryOnKey()), anyInt());
- }
-
- @Test
- public void testUpdateNotificationRanking_noChange() {
- when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
- when(mEnvironment.isNotificationForCurrentProfiles(any())).thenReturn(true);
-
- mEntry.setRow(mRow);
- mEntryManager.addActiveNotificationForTest(mEntry);
- setSmartActions(mEntry.getKey(), null);
-
- mEntryManager.updateNotificationRanking(mRankingMap);
- assertThat(mEntry.getSmartActions()).isEmpty();
- }
-
- @Test
- public void testUpdateNotificationRanking_pendingNotification() {
- when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
- when(mEnvironment.isNotificationForCurrentProfiles(any())).thenReturn(true);
-
- mEntry.setRow(null);
- mEntryManager.mPendingNotifications.put(mEntry.getKey(), mEntry);
- setSmartActions(mEntry.getKey(), new ArrayList<>(Arrays.asList(createAction())));
-
- mEntryManager.updateNotificationRanking(mRankingMap);
- assertEquals(1, mEntry.getSmartActions().size());
- assertEquals("action", mEntry.getSmartActions().get(0).title);
- }
-
- @Test
- public void testUpdatePendingNotification_rankingUpdated() {
- // GIVEN a notification with ranking is pending
- final Ranking originalRanking = mEntry.getRanking();
- mEntryManager.mPendingNotifications.put(mEntry.getKey(), mEntry);
-
- // WHEN the same notification has been updated with a new ranking
- final int newRank = 2345;
- doAnswer(invocationOnMock -> {
- Ranking ranking = (Ranking)
- invocationOnMock.getArguments()[1];
- ranking.populate(
- mEntry.getKey(),
- newRank, /* this changed!! */
- false,
- 0,
- 0,
- IMPORTANCE_DEFAULT,
- null, null,
- null, null, null, true,
- Ranking.USER_SENTIMENT_NEUTRAL, false, -1,
- false, null, null, false, false, false, null, 0, false);
- return true;
- }).when(mRankingMap).getRanking(eq(mEntry.getKey()), any(Ranking.class));
- mEntryManager.addNotification(mSbn, mRankingMap);
-
- // THEN ranking for the entry has been updated with new ranking
- assertEquals(newRank, mEntry.getRanking().getRank());
- }
-
- @Test
- public void testNotifyChannelModified_notifiesListeners() {
- NotificationChannel channel = mock(NotificationChannel.class);
- String pkg = "PKG";
- mEntryManager.notifyChannelModified(pkg, UserHandle.CURRENT, channel,
- NOTIFICATION_CHANNEL_OR_GROUP_UPDATED);
- verify(mNotifCollectionListener).onNotificationChannelModified(eq(pkg),
- eq(UserHandle.CURRENT), eq(channel), eq(NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
- verify(mEntryListener).onNotificationChannelModified(eq(pkg),
- eq(UserHandle.CURRENT), eq(channel), eq(NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
- }
-
- @Test
- public void testLifetimeExtenders_ifNotificationIsRetainedItIsntRemoved() {
- // GIVEN an entry manager with a notification
- mEntryManager.addActiveNotificationForTest(mEntry);
-
- // GIVEN a lifetime extender that always tries to extend lifetime
- NotificationLifetimeExtender extender = mock(NotificationLifetimeExtender.class);
- when(extender.shouldExtendLifetime(mEntry)).thenReturn(true);
- mEntryManager.addNotificationLifetimeExtender(extender);
-
- // WHEN the notification is removed
- mEntryManager.removeNotification(mEntry.getKey(), mRankingMap, UNDEFINED_DISMISS_REASON);
-
- // THEN the extender is asked to manage the lifetime
- verify(extender).setShouldManageLifetime(mEntry, true);
- // THEN the notification is retained
- assertNotNull(mEntryManager.getActiveNotificationUnfiltered(mSbn.getKey()));
- verify(mEntryListener, never()).onEntryRemoved(
- argThat(matchEntryOnKey()), any(), eq(false), eq(UNDEFINED_DISMISS_REASON));
- }
-
- @Test
- public void testLifetimeExtenders_whenRetentionEndsNotificationIsRemoved() {
- // GIVEN an entry manager with a notification whose life has been extended
- mEntryManager.addActiveNotificationForTest(mEntry);
- final FakeNotificationLifetimeExtender extender = new FakeNotificationLifetimeExtender();
- mEntryManager.addNotificationLifetimeExtender(extender);
- mEntryManager.removeNotification(mEntry.getKey(), mRankingMap, UNDEFINED_DISMISS_REASON);
- assertTrue(extender.isManaging(mEntry.getKey()));
-
- // WHEN the extender finishes its extension
- extender.setExtendLifetimes(false);
- extender.getCallback().onSafeToRemove(mEntry.getKey());
-
- // THEN the notification is removed
- assertNull(mEntryManager.getActiveNotificationUnfiltered(mSbn.getKey()));
- verify(mEntryListener).onEntryRemoved(
- argThat(matchEntryOnKey()), any(), eq(false), eq(UNDEFINED_DISMISS_REASON));
- }
-
- @Test
- public void testLifetimeExtenders_whenNotificationUpdatedRetainersAreCanceled() {
- // GIVEN an entry manager with a notification whose life has been extended
- mEntryManager.addActiveNotificationForTest(mEntry);
- NotificationLifetimeExtender extender = mock(NotificationLifetimeExtender.class);
- when(extender.shouldExtendLifetime(mEntry)).thenReturn(true);
- mEntryManager.addNotificationLifetimeExtender(extender);
- mEntryManager.removeNotification(mEntry.getKey(), mRankingMap, UNDEFINED_DISMISS_REASON);
-
- // WHEN the notification is updated
- mEntryManager.updateNotification(mEntry.getSbn(), mRankingMap);
-
- // THEN the lifetime extension is canceled
- verify(extender).setShouldManageLifetime(mEntry, false);
- }
-
- @Test
- public void testLifetimeExtenders_whenNewExtenderTakesPrecedenceOldExtenderIsCanceled() {
- // GIVEN an entry manager with a notification
- mEntryManager.addActiveNotificationForTest(mEntry);
-
- // GIVEN two lifetime extenders, the first which never extends and the second which
- // always extends
- NotificationLifetimeExtender extender1 = mock(NotificationLifetimeExtender.class);
- when(extender1.shouldExtendLifetime(mEntry)).thenReturn(false);
- NotificationLifetimeExtender extender2 = mock(NotificationLifetimeExtender.class);
- when(extender2.shouldExtendLifetime(mEntry)).thenReturn(true);
- mEntryManager.addNotificationLifetimeExtender(extender1);
- mEntryManager.addNotificationLifetimeExtender(extender2);
-
- // GIVEN a notification was lifetime-extended and extender2 is managing it
- mEntryManager.removeNotification(mEntry.getKey(), mRankingMap, UNDEFINED_DISMISS_REASON);
- verify(extender1, never()).setShouldManageLifetime(mEntry, true);
- verify(extender2).setShouldManageLifetime(mEntry, true);
-
- // WHEN the extender1 changes its mind and wants to extend the lifetime of the notif
- when(extender1.shouldExtendLifetime(mEntry)).thenReturn(true);
- mEntryManager.removeNotification(mEntry.getKey(), mRankingMap, UNDEFINED_DISMISS_REASON);
-
- // THEN extender2 stops managing the notif and extender1 starts managing it
- verify(extender1).setShouldManageLifetime(mEntry, true);
- verify(extender2).setShouldManageLifetime(mEntry, false);
- }
-
- /**
- * Ensure that calling NotificationEntryManager.performRemoveNotification() doesn't crash when
- * given a notification that has already been removed from NotificationData.
- */
- @Test
- public void testPerformRemoveNotification_removedEntry() {
- mEntryManager.removeNotification(mSbn.getKey(), null, 0);
- mEntryManager.performRemoveNotification(mSbn, mock(DismissedByUserStats.class),
- REASON_CANCEL);
- }
-
- @Test
- public void testRemoveInterceptor_interceptsDontGetRemoved() throws InterruptedException {
- // GIVEN an entry manager with a notification
- mEntryManager.addActiveNotificationForTest(mEntry);
-
- // GIVEN interceptor that intercepts that entry
- when(mRemoveInterceptor.onNotificationRemoveRequested(
- eq(mEntry.getKey()), argThat(matchEntryOnKey()), anyInt()))
- .thenReturn(true);
-
- // WHEN the notification is removed
- mEntryManager.removeNotification(mEntry.getKey(), mRankingMap, UNDEFINED_DISMISS_REASON);
-
- // THEN the interceptor intercepts & the entry is not removed & no listeners are called
- assertNotNull(mEntryManager.getActiveNotificationUnfiltered(mSbn.getKey()));
- verify(mEntryListener, never()).onEntryRemoved(argThat(matchEntryOnKey()),
- any(NotificationVisibility.class), anyBoolean(), eq(UNDEFINED_DISMISS_REASON));
- }
-
- @Test
- public void testRemoveInterceptor_notInterceptedGetsRemoved() {
- // GIVEN an entry manager with a notification
- mEntryManager.addActiveNotificationForTest(mEntry);
-
- // GIVEN interceptor that doesn't intercept
- when(mRemoveInterceptor.onNotificationRemoveRequested(
- eq(mEntry.getKey()), argThat(matchEntryOnKey()), anyInt()))
- .thenReturn(false);
-
- // WHEN the notification is removed
- mEntryManager.removeNotification(mEntry.getKey(), mRankingMap, UNDEFINED_DISMISS_REASON);
-
- // THEN the interceptor intercepts & the entry is not removed & no listeners are called
- assertNull(mEntryManager.getActiveNotificationUnfiltered(mSbn.getKey()));
- verify(mEntryListener, atLeastOnce()).onEntryRemoved(argThat(matchEntryOnKey()),
- any(NotificationVisibility.class), anyBoolean(), eq(UNDEFINED_DISMISS_REASON));
- }
-
- /* Tests annexed from NotificationDataTest go here */
-
- @Test
- public void testGetNotificationsForCurrentUser_shouldFilterNonCurrentUserNotifications() {
- Notification.Builder n = new Notification.Builder(mContext, "di")
- .setSmallIcon(R.drawable.ic_person)
- .setContentTitle("Title")
- .setContentText("Text");
-
- NotificationEntry e2 = new NotificationEntryBuilder()
- .setPkg(TEST_PACKAGE_NAME)
- .setOpPkg(TEST_PACKAGE_NAME)
- .setUid(TEST_UID)
- .setId(mId++)
- .setNotification(n.build())
- .setUser(new UserHandle(ActivityManager.getCurrentUser()))
- .setChannel(new NotificationChannel("id", "", IMPORTANCE_DEFAULT))
- .build();
-
- mEntryManager.addActiveNotificationForTest(mEntry);
- mEntryManager.addActiveNotificationForTest(e2);
-
- when(mEnvironment.isNotificationForCurrentProfiles(mEntry.getSbn())).thenReturn(false);
- when(mEnvironment.isNotificationForCurrentProfiles(e2.getSbn())).thenReturn(true);
-
- List<NotificationEntry> result = mEntryManager.getActiveNotificationsForCurrentUser();
- assertEquals(result.size(), 1);
- junit.framework.Assert.assertEquals(result.get(0), e2);
- }
-
- /* End annex */
-
- private boolean entriesContainKey(Collection<NotificationEntry> entries, String key) {
- for (NotificationEntry entry : entries) {
- if (entry.getSbn().getKey().equals(key)) {
- return true;
- }
- }
- return false;
- }
-
- private Notification.Action createAction() {
- return new Notification.Action.Builder(
- Icon.createWithResource(getContext(), android.R.drawable.sym_def_app_icon),
- "action",
- PendingIntent.getBroadcast(getContext(), 0, new Intent("Action"),
- PendingIntent.FLAG_IMMUTABLE)).build();
- }
-
- private ArgumentMatcher<NotificationEntry> matchEntryOnKey() {
- return e -> e.getKey().equals(mEntry.getKey());
- }
-
- private static class FakeNotificationLifetimeExtender implements NotificationLifetimeExtender {
- private NotificationSafeToRemoveCallback mCallback;
- private boolean mExtendLifetimes = true;
- private Set<String> mManagedNotifs = new ArraySet<>();
-
- @Override
- public void setCallback(@NonNull NotificationSafeToRemoveCallback callback) {
- mCallback = callback;
- }
-
- @Override
- public boolean shouldExtendLifetime(@NonNull NotificationEntry entry) {
- return mExtendLifetimes;
- }
-
- @Override
- public void setShouldManageLifetime(
- @NonNull NotificationEntry entry,
- boolean shouldManage) {
- final boolean hasEntry = mManagedNotifs.contains(entry.getKey());
- if (shouldManage) {
- if (hasEntry) {
- throw new RuntimeException("Already managing this entry: " + entry.getKey());
- }
- mManagedNotifs.add(entry.getKey());
- } else {
- if (!hasEntry) {
- throw new RuntimeException("Not managing this entry: " + entry.getKey());
- }
- mManagedNotifs.remove(entry.getKey());
- }
- }
-
- public void setExtendLifetimes(boolean extendLifetimes) {
- mExtendLifetimes = extendLifetimes;
- }
-
- public NotificationSafeToRemoveCallback getCallback() {
- return mCallback;
- }
-
- public boolean isManaging(String notificationKey) {
- return mManagedNotifs.contains(notificationKey);
- }
- }
-
- private NotificationEntry createNotification() {
- Notification.Builder n = new Notification.Builder(mContext, "id")
- .setSmallIcon(R.drawable.ic_person)
- .setContentTitle("Title")
- .setContentText("Text");
-
- return new NotificationEntryBuilder()
- .setPkg(TEST_PACKAGE_NAME)
- .setOpPkg(TEST_PACKAGE_NAME)
- .setUid(TEST_UID)
- .setId(mId++)
- .setNotification(n.build())
- .setChannel(new NotificationChannel("id", "", IMPORTANCE_DEFAULT))
- .setUser(new UserHandle(ActivityManager.getCurrentUser()))
- .build();
- }
-
- private static DismissedByUserStats defaultStats(NotificationEntry entry) {
- return new DismissedByUserStats(
- DISMISSAL_SHADE,
- DISMISS_SENTIMENT_NEUTRAL,
- NotificationVisibility.obtain(entry.getKey(), 7, 2, true));
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java
deleted file mode 100644
index 2cacaf78479d..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2018 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;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.Manifest;
-import android.app.Notification;
-import android.app.Notification.MediaStyle;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.media.session.MediaSession;
-import android.os.Bundle;
-import android.service.notification.StatusBarNotification;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.testing.TestableLooper.RunWithLooper;
-
-import androidx.annotation.NonNull;
-import androidx.test.annotation.UiThreadTest;
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.ForegroundServiceController;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.dump.DumpManager;
-import com.android.systemui.media.MediaFeatureFlag;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.shade.ShadeController;
-import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.notification.NotificationEntryManager.KeyguardEnvironment;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
-import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
-import com.android.systemui.statusbar.notification.collection.provider.DebugModeFilterProvider;
-import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
-import com.android.wm.shell.bubbles.Bubbles;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.Optional;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@RunWithLooper
-public class NotificationFilterTest extends SysuiTestCase {
-
- private static final int UID_NORMAL = 123;
- private static final int UID_ALLOW_DURING_SETUP = 456;
- private static final String TEST_HIDDEN_NOTIFICATION_KEY = "testHiddenNotificationKey";
-
- private final StatusBarNotification mMockStatusBarNotification =
- mock(StatusBarNotification.class);
-
- @Mock
- DebugModeFilterProvider mDebugModeFilterProvider;
- @Mock
- StatusBarStateController mStatusBarStateController;
- @Mock
- KeyguardEnvironment mEnvironment;
- @Mock
- ForegroundServiceController mFsc;
- @Mock
- NotificationLockscreenUserManager mUserManager;
- @Mock
- MediaFeatureFlag mMediaFeatureFlag;
-
- private final IPackageManager mMockPackageManager = mock(IPackageManager.class);
-
- private NotificationFilter mNotificationFilter;
- private ExpandableNotificationRow mRow;
- private NotificationEntry mMediaEntry;
- private MediaSession mMediaSession;
-
- @Before
- public void setUp() throws Exception {
- allowTestableLooperAsMainThread();
- MockitoAnnotations.initMocks(this);
- when(mMockStatusBarNotification.getUid()).thenReturn(UID_NORMAL);
-
- mMediaSession = new MediaSession(mContext, "TEST_MEDIA_SESSION");
- NotificationEntryBuilder builder = new NotificationEntryBuilder();
- builder.modifyNotification(mContext).setStyle(
- new MediaStyle().setMediaSession(mMediaSession.getSessionToken()));
- mMediaEntry = builder.build();
-
- when(mMockPackageManager.checkUidPermission(
- eq(Manifest.permission.NOTIFICATION_DURING_SETUP),
- eq(UID_NORMAL)))
- .thenReturn(PackageManager.PERMISSION_DENIED);
- when(mMockPackageManager.checkUidPermission(
- eq(Manifest.permission.NOTIFICATION_DURING_SETUP),
- eq(UID_ALLOW_DURING_SETUP)))
- .thenReturn(PackageManager.PERMISSION_GRANTED);
- mDependency.injectTestDependency(ForegroundServiceController.class, mFsc);
- mDependency.injectTestDependency(NotificationGroupManagerLegacy.class,
- new NotificationGroupManagerLegacy(
- mock(StatusBarStateController.class),
- () -> mock(PeopleNotificationIdentifier.class),
- Optional.of(mock(Bubbles.class)),
- mock(DumpManager.class)));
- mDependency.injectMockDependency(ShadeController.class);
- mDependency.injectMockDependency(NotificationLockscreenUserManager.class);
- mDependency.injectTestDependency(KeyguardEnvironment.class, mEnvironment);
- when(mEnvironment.isDeviceProvisioned()).thenReturn(true);
- when(mEnvironment.isNotificationForCurrentProfiles(any())).thenReturn(true);
- NotificationTestHelper testHelper = new NotificationTestHelper(
- mContext,
- mDependency,
- TestableLooper.get(this));
- mRow = testHelper.createRow();
- mNotificationFilter = newNotificationFilter();
- }
-
- @NonNull
- private NotificationFilter newNotificationFilter() {
- return new NotificationFilter(
- mDebugModeFilterProvider,
- mStatusBarStateController,
- mEnvironment,
- mFsc,
- mUserManager,
- mMediaFeatureFlag);
- }
-
- @After
- public void tearDown() {
- mMediaSession.release();
- }
-
- @Test
- @UiThreadTest
- public void testShowNotificationEvenIfUnprovisioned_FalseIfNoExtra() {
- initStatusBarNotification(false);
- when(mMockStatusBarNotification.getUid()).thenReturn(UID_ALLOW_DURING_SETUP);
-
- assertFalse(
- NotificationFilter.showNotificationEvenIfUnprovisioned(
- mMockPackageManager,
- mMockStatusBarNotification));
- }
-
- @Test
- @UiThreadTest
- public void testShowNotificationEvenIfUnprovisioned_FalseIfNoPermission() {
- initStatusBarNotification(true);
-
- assertFalse(
- NotificationFilter.showNotificationEvenIfUnprovisioned(
- mMockPackageManager,
- mMockStatusBarNotification));
- }
-
- @Test
- @UiThreadTest
- public void testShowNotificationEvenIfUnprovisioned_TrueIfHasPermissionAndExtra() {
- initStatusBarNotification(true);
- when(mMockStatusBarNotification.getUid()).thenReturn(UID_ALLOW_DURING_SETUP);
-
- assertTrue(
- NotificationFilter.showNotificationEvenIfUnprovisioned(
- mMockPackageManager,
- mMockStatusBarNotification));
- }
-
- @Test
- public void testShouldFilterHiddenNotifications() {
- initStatusBarNotification(false);
- // setup
- when(mFsc.isSystemAlertWarningNeeded(anyInt(), anyString())).thenReturn(false);
-
- // test should filter out hidden notifications:
- // hidden
- NotificationEntry entry = new NotificationEntryBuilder()
- .setSuspended(true)
- .build();
-
- assertTrue(mNotificationFilter.shouldFilterOut(entry));
-
- // not hidden
- entry = new NotificationEntryBuilder()
- .setSuspended(false)
- .build();
- assertFalse(mNotificationFilter.shouldFilterOut(entry));
- }
-
- @Test
- public void shouldFilterOtherNotificationWhenDisabled() {
- // GIVEN that the media feature is disabled
- when(mMediaFeatureFlag.getEnabled()).thenReturn(false);
- NotificationFilter filter = newNotificationFilter();
- // WHEN the media filter is asked about an entry
- NotificationEntry otherEntry = new NotificationEntryBuilder().build();
- final boolean shouldFilter = filter.shouldFilterOut(otherEntry);
- // THEN it shouldn't be filtered
- assertFalse(shouldFilter);
- }
-
- @Test
- public void shouldFilterOtherNotificationWhenEnabled() {
- // GIVEN that the media feature is enabled
- when(mMediaFeatureFlag.getEnabled()).thenReturn(true);
- NotificationFilter filter = newNotificationFilter();
- // WHEN the media filter is asked about an entry
- NotificationEntry otherEntry = new NotificationEntryBuilder().build();
- final boolean shouldFilter = filter.shouldFilterOut(otherEntry);
- // THEN it shouldn't be filtered
- assertFalse(shouldFilter);
- }
-
- @Test
- public void shouldFilterMediaNotificationWhenDisabled() {
- // GIVEN that the media feature is disabled
- when(mMediaFeatureFlag.getEnabled()).thenReturn(false);
- NotificationFilter filter = newNotificationFilter();
- // WHEN the media filter is asked about a media entry
- final boolean shouldFilter = filter.shouldFilterOut(mMediaEntry);
- // THEN it shouldn't be filtered
- assertFalse(shouldFilter);
- }
-
- @Test
- public void shouldFilterMediaNotificationWhenEnabled() {
- // GIVEN that the media feature is enabled
- when(mMediaFeatureFlag.getEnabled()).thenReturn(true);
- NotificationFilter filter = newNotificationFilter();
- // WHEN the media filter is asked about a media entry
- final boolean shouldFilter = filter.shouldFilterOut(mMediaEntry);
- // THEN it should be filtered
- assertTrue(shouldFilter);
- }
-
- private void initStatusBarNotification(boolean allowDuringSetup) {
- Bundle bundle = new Bundle();
- bundle.putBoolean(Notification.EXTRA_ALLOW_DURING_SETUP, allowDuringSetup);
- Notification notification = new Notification.Builder(mContext, "test")
- .addExtras(bundle)
- .build();
- when(mMockStatusBarNotification.getNotification()).thenReturn(notification);
- }
-}
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
deleted file mode 100644
index 58abbf2ddef7..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (C) 2017 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;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.os.Handler;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.dump.DumpManager;
-import com.android.systemui.keyguard.WakefulnessLifecycle;
-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;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper()
-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);
- private NotificationEntry mEntry;
-
- private StatusBarStateController.StateListener mStatusBarStateListener;
- private WakefulnessLifecycle.Observer mWakefulnessObserver;
-
- @Before
- public void setUp() {
- StatusBarStateController statusBarStateController = mock(StatusBarStateController.class);
- WakefulnessLifecycle wakefulnessLifecycle = mock(WakefulnessLifecycle.class);
-
- mTestableLooper = TestableLooper.get(this);
- mVisualStabilityManager = new VisualStabilityManager(
- mock(NotificationEntryManager.class),
- mVisualStabilityProvider,
- new Handler(mTestableLooper.getLooper()),
- statusBarStateController,
- wakefulnessLifecycle,
- mock(DumpManager.class));
-
- mVisualStabilityManager.setVisibilityLocationProvider(mLocationProvider);
- mEntry = new NotificationEntryBuilder().build();
- mEntry.setRow(mRow);
-
- when(mRow.getEntry()).thenReturn(mEntry);
-
- ArgumentCaptor<StatusBarStateController.StateListener> stateListenerCaptor =
- ArgumentCaptor.forClass(StatusBarStateController.StateListener.class);
- verify(statusBarStateController).addCallback(stateListenerCaptor.capture());
- mStatusBarStateListener = stateListenerCaptor.getValue();
-
- ArgumentCaptor<WakefulnessLifecycle.Observer> wakefulnessObserverCaptor =
- ArgumentCaptor.forClass(WakefulnessLifecycle.Observer.class);
- verify(wakefulnessLifecycle).addObserver(wakefulnessObserverCaptor.capture());
- mWakefulnessObserver = wakefulnessObserverCaptor.getValue();
- }
-
- @Test
- public void testPanelExpansion() {
- setPanelExpanded(true);
- setScreenOn(true);
- assertFalse(mVisualStabilityManager.canReorderNotification(mRow));
- setPanelExpanded(false);
- assertTrue(mVisualStabilityManager.canReorderNotification(mRow));
- }
-
- @Test
- public void testScreenOn() {
- setPanelExpanded(true);
- setScreenOn(true);
- assertFalse(mVisualStabilityManager.canReorderNotification(mRow));
- setScreenOn(false);
- assertTrue(mVisualStabilityManager.canReorderNotification(mRow));
- }
-
- @Test
- public void testReorderingAllowedChangesScreenOn() {
- setPanelExpanded(true);
- setScreenOn(true);
- assertFalse(mVisualStabilityManager.isReorderingAllowed());
- setScreenOn(false);
- assertTrue(mVisualStabilityManager.isReorderingAllowed());
- }
-
- @Test
- public void testReorderingAllowedChangesPanel() {
- setPanelExpanded(true);
- setScreenOn(true);
- assertFalse(mVisualStabilityManager.isReorderingAllowed());
- setPanelExpanded(false);
- assertTrue(mVisualStabilityManager.isReorderingAllowed());
- }
-
- @Test
- public void testCallBackCalledScreenOn() {
- setPanelExpanded(true);
- setScreenOn(true);
- mVisualStabilityManager.addReorderingAllowedCallback(mCallback, false /* persistent */);
- setScreenOn(false);
- verify(mCallback).onChangeAllowed();
- }
-
- @Test
- public void testCallBackCalledPanelExpanded() {
- setPanelExpanded(true);
- setScreenOn(true);
- mVisualStabilityManager.addReorderingAllowedCallback(mCallback, false /* persistent */);
- setPanelExpanded(false);
- verify(mCallback).onChangeAllowed();
- }
-
- @Test
- public void testCallBackExactlyOnce() {
- setPanelExpanded(true);
- setScreenOn(true);
- mVisualStabilityManager.addReorderingAllowedCallback(mCallback, false /* persistent */);
- setScreenOn(false);
- setScreenOn(true);
- setScreenOn(false);
- verify(mCallback).onChangeAllowed();
- }
-
- @Test
- public void testCallBackCalledContinuouslyWhenRequested() {
- setPanelExpanded(true);
- setScreenOn(true);
- mVisualStabilityManager.addReorderingAllowedCallback(mCallback, true /* persistent */);
- setScreenOn(false);
- setScreenOn(true);
- setScreenOn(false);
- verify(mCallback, times(2)).onChangeAllowed();
- }
-
- @Test
- public void testAddedCanReorder() {
- setPanelExpanded(true);
- setScreenOn(true);
- mVisualStabilityManager.notifyViewAddition(mRow);
- assertTrue(mVisualStabilityManager.canReorderNotification(mRow));
- }
-
- @Test
- public void testReorderingVisibleHeadsUpNotAllowed() {
- setPanelExpanded(true);
- setScreenOn(true);
- when(mLocationProvider.isInVisibleLocation(any(NotificationEntry.class))).thenReturn(true);
- mVisualStabilityManager.onHeadsUpStateChanged(mEntry, true);
- assertFalse(mVisualStabilityManager.canReorderNotification(mRow));
- }
-
- @Test
- public void testReorderingVisibleHeadsUpAllowed() {
- setPanelExpanded(true);
- setScreenOn(true);
- when(mLocationProvider.isInVisibleLocation(any(NotificationEntry.class))).thenReturn(false);
- mVisualStabilityManager.onHeadsUpStateChanged(mEntry, true);
- assertTrue(mVisualStabilityManager.canReorderNotification(mRow));
- }
-
- @Test
- public void testReorderingVisibleHeadsUpAllowedOnce() {
- setPanelExpanded(true);
- setScreenOn(true);
- when(mLocationProvider.isInVisibleLocation(any(NotificationEntry.class))).thenReturn(false);
- mVisualStabilityManager.onHeadsUpStateChanged(mEntry, true);
- mVisualStabilityManager.onReorderingFinished();
- assertFalse(mVisualStabilityManager.canReorderNotification(mRow));
- }
-
- @Test
- public void testPulsing() {
- setPulsing(true);
- assertFalse(mVisualStabilityManager.canReorderNotification(mRow));
- setPulsing(false);
- assertTrue(mVisualStabilityManager.canReorderNotification(mRow));
- }
-
- @Test
- public void testReorderingAllowedChanges_Pulsing() {
- setPulsing(true);
- assertFalse(mVisualStabilityManager.isReorderingAllowed());
- setPulsing(false);
- assertTrue(mVisualStabilityManager.isReorderingAllowed());
- }
-
- @Test
- public void testCallBackCalled_Pulsing() {
- setPulsing(true);
- mVisualStabilityManager.addReorderingAllowedCallback(mCallback, false /* persistent */);
- setPulsing(false);
- verify(mCallback).onChangeAllowed();
- }
-
- @Test
- public void testTemporarilyAllowReorderingNotifiesCallbacks() {
- // GIVEN having the panel open (which would block reordering)
- setScreenOn(true);
- setPanelExpanded(true);
- mVisualStabilityManager.addReorderingAllowedCallback(mCallback, false /* persistent */);
-
- // WHEN we temprarily allow reordering
- mVisualStabilityManager.temporarilyAllowReordering();
-
- // THEN callbacks are notified that reordering is allowed
- verify(mCallback).onChangeAllowed();
- assertTrue(mVisualStabilityManager.isReorderingAllowed());
- }
-
- @Test
- public void testTemporarilyAllowReorderingDoesntOverridePulsing() {
- // GIVEN we are in a pulsing state
- setPulsing(true);
- mVisualStabilityManager.addReorderingAllowedCallback(mCallback, false /* persistent */);
-
- // WHEN we temprarily allow reordering
- mVisualStabilityManager.temporarilyAllowReordering();
-
- // THEN reordering is still not allowed
- verify(mCallback, never()).onChangeAllowed();
- assertFalse(mVisualStabilityManager.isReorderingAllowed());
- }
-
- @Test
- public void testTemporarilyAllowReorderingExpires() {
- // GIVEN having the panel open (which would block reordering)
- setScreenOn(true);
- setPanelExpanded(true);
- mVisualStabilityManager.addReorderingAllowedCallback(mCallback, false /* persistent */);
-
- // WHEN we temprarily allow reordering and then wait until the window expires
- mVisualStabilityManager.temporarilyAllowReordering();
- assertTrue(mVisualStabilityManager.isReorderingAllowed());
- mTestableLooper.processMessages(1);
-
- // THEN reordering is no longer allowed
- assertFalse(mVisualStabilityManager.isReorderingAllowed());
- }
-
- private void setPanelExpanded(boolean expanded) {
- mStatusBarStateListener.onExpandedChanged(expanded);
- }
-
- private void setPulsing(boolean pulsing) {
- mStatusBarStateListener.onPulsingChanged(pulsing);
- }
-
- private void setScreenOn(boolean screenOn) {
- if (screenOn) {
- mWakefulnessObserver.onStartedWakingUp();
- } else {
- mWakefulnessObserver.onFinishedGoingToSleep();
- }
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt
deleted file mode 100644
index c51c628c5457..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
- * Copyright (C) 2019 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
-
-import android.app.Notification
-import android.app.NotificationChannel
-import android.app.NotificationManager.IMPORTANCE_DEFAULT
-import android.app.NotificationManager.IMPORTANCE_HIGH
-import android.app.NotificationManager.IMPORTANCE_LOW
-import android.app.PendingIntent
-import android.app.Person
-import android.os.SystemClock
-import android.service.notification.NotificationListenerService.RankingMap
-import android.testing.AndroidTestingRunner
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.statusbar.NotificationEntryHelper.modifyRanking
-import com.android.systemui.statusbar.NotificationMediaManager
-import com.android.systemui.statusbar.notification.NotificationEntryManager.KeyguardEnvironment
-import com.android.systemui.statusbar.notification.NotificationEntryManagerLogger
-import com.android.systemui.statusbar.notification.NotificationFilter
-import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
-import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy
-import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider
-import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
-import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_FULL_PERSON
-import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_IMPORTANT_PERSON
-import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_PERSON
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
-import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING
-import com.android.systemui.statusbar.notification.stack.BUCKET_FOREGROUND_SERVICE
-import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT
-import com.android.systemui.statusbar.policy.HeadsUpManager
-import com.google.common.truth.Truth.assertThat
-import dagger.Lazy
-import junit.framework.Assert.assertEquals
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mockito.mock
-import org.mockito.Mockito.`when` as whenever
-
-@SmallTest
-@RunWith(AndroidTestingRunner::class)
-class NotificationRankingManagerTest : SysuiTestCase() {
-
- private val lazyMedia: Lazy<NotificationMediaManager> = Lazy {
- mock(NotificationMediaManager::class.java)
- }
- private lateinit var personNotificationIdentifier: PeopleNotificationIdentifier
- private lateinit var rankingManager: TestableNotificationRankingManager
- private lateinit var sectionsManager: NotificationSectionsFeatureManager
- private lateinit var notificationFilter: NotificationFilter
-
- @Before
- fun setup() {
- personNotificationIdentifier =
- mock(PeopleNotificationIdentifier::class.java)
- sectionsManager = mock(NotificationSectionsFeatureManager::class.java)
- notificationFilter = mock(NotificationFilter::class.java)
- rankingManager = TestableNotificationRankingManager(
- lazyMedia,
- mock(NotificationGroupManagerLegacy::class.java),
- mock(HeadsUpManager::class.java),
- notificationFilter,
- mock(NotificationEntryManagerLogger::class.java),
- sectionsManager,
- personNotificationIdentifier,
- HighPriorityProvider(
- personNotificationIdentifier,
- mock(NotificationGroupManagerLegacy::class.java)),
- mock(KeyguardEnvironment::class.java)
- )
- }
-
- @Test
- fun testSort_highPriorityTrumpsNMSRank() {
- // NMS rank says A and then B. But A is not high priority and B is, so B should sort in
- // front
- val a = NotificationEntryBuilder()
- .setImportance(IMPORTANCE_LOW) // low priority
- .setRank(1) // NMS says rank first
- .setPkg("pkg")
- .setOpPkg("pkg")
- .setTag("tag")
- .setNotification(
- Notification.Builder(mContext, "test")
- .build())
- .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
- .setUser(mContext.getUser())
- .setOverrideGroupKey("")
- .build()
-
- val b = NotificationEntryBuilder()
- .setImportance(IMPORTANCE_HIGH) // high priority
- .setRank(2) // NMS says rank second
- .setPkg("pkg2")
- .setOpPkg("pkg2")
- .setTag("tag")
- .setNotification(
- Notification.Builder(mContext, "test")
- .build())
- .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
- .setUser(mContext.getUser())
- .setOverrideGroupKey("")
- .build()
-
- assertEquals(
- listOf(b, a),
- rankingManager.updateRanking(null, listOf(a, b), "test"))
- }
-
- @Test
- fun testSort_samePriorityUsesNMSRank() {
- // NMS rank says A and then B, and they are the same priority so use that rank
- val aN = Notification.Builder(mContext, "test")
- .setStyle(Notification.MessagingStyle(""))
- .build()
- val a = NotificationEntryBuilder()
- .setRank(1)
- .setImportance(IMPORTANCE_HIGH)
- .setPkg("pkg")
- .setOpPkg("pkg")
- .setTag("tag")
- .setNotification(aN)
- .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
- .setUser(mContext.getUser())
- .setOverrideGroupKey("")
- .build()
-
- val bN = Notification.Builder(mContext, "test")
- .setStyle(Notification.MessagingStyle(""))
- .build()
- val b = NotificationEntryBuilder()
- .setRank(2)
- .setImportance(IMPORTANCE_HIGH)
- .setPkg("pkg2")
- .setOpPkg("pkg2")
- .setTag("tag")
- .setNotification(bN)
- .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
- .setUser(mContext.getUser())
- .setOverrideGroupKey("")
- .build()
-
- assertEquals(
- listOf(a, b),
- rankingManager.updateRanking(null, listOf(a, b), "test"))
- }
-
- @Test
- fun testSort_headsUp_trumpsPeople() {
- whenever(sectionsManager.isFilteringEnabled()).thenReturn(true)
- val aN = Notification.Builder(mContext, "test")
- .setStyle(Notification.MessagingStyle(""))
- .build()
- val a = NotificationEntryBuilder()
- .setImportance(IMPORTANCE_HIGH)
- .setPkg("pkg")
- .setOpPkg("pkg")
- .setTag("tag")
- .setNotification(aN)
- .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
- .setUser(mContext.getUser())
- .setOverrideGroupKey("")
- .build()
-
- whenever(personNotificationIdentifier.getPeopleNotificationType(a))
- .thenReturn(TYPE_IMPORTANT_PERSON)
-
- val bN = Notification.Builder(mContext, "test")
- .setStyle(Notification.MessagingStyle(""))
- .build()
- val b = NotificationEntryBuilder()
- .setImportance(IMPORTANCE_HIGH)
- .setPkg("pkg2")
- .setOpPkg("pkg2")
- .setTag("tag")
- .setNotification(bN)
- .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
- .setUser(mContext.getUser())
- .setOverrideGroupKey("")
- .build()
- b.row = mock(ExpandableNotificationRow::class.java).also {
- whenever(it.isHeadsUp).thenReturn(true)
- }
-
- whenever(personNotificationIdentifier.getPeopleNotificationType(a))
- .thenReturn(TYPE_PERSON)
-
- assertEquals(listOf(b, a), rankingManager.updateRanking(null, listOf(a, b), "test"))
- }
-
- @Test
- fun testSort_importantPeople() {
- whenever(sectionsManager.isFilteringEnabled()).thenReturn(true)
- val aN = Notification.Builder(mContext, "test")
- .setStyle(Notification.MessagingStyle(""))
- .build()
- val a = NotificationEntryBuilder()
- .setImportance(IMPORTANCE_HIGH)
- .setPkg("pkg")
- .setOpPkg("pkg")
- .setTag("tag")
- .setNotification(aN)
- .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
- .setUser(mContext.user)
- .setOverrideGroupKey("")
- .build()
- whenever(personNotificationIdentifier.getPeopleNotificationType(a))
- .thenReturn(TYPE_PERSON)
-
- val bN = Notification.Builder(mContext, "test")
- .setStyle(Notification.MessagingStyle(""))
- .build()
- val b = NotificationEntryBuilder()
- .setImportance(IMPORTANCE_HIGH)
- .setPkg("pkg2")
- .setOpPkg("pkg2")
- .setTag("tag")
- .setNotification(bN)
- .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
- .setUser(mContext.user)
- .setOverrideGroupKey("")
- .build()
- whenever(personNotificationIdentifier.getPeopleNotificationType(b))
- .thenReturn(TYPE_IMPORTANT_PERSON)
-
- whenever(personNotificationIdentifier.compareTo(TYPE_PERSON, TYPE_IMPORTANT_PERSON))
- .thenReturn(TYPE_IMPORTANT_PERSON.compareTo(TYPE_PERSON))
- whenever(personNotificationIdentifier.compareTo(TYPE_IMPORTANT_PERSON, TYPE_PERSON))
- .thenReturn(TYPE_PERSON.compareTo(TYPE_IMPORTANT_PERSON))
-
- assertEquals(
- listOf(b, a),
- rankingManager.updateRanking(null, listOf(a, b), "test"))
- }
-
- @Test
- fun testSort_fullPeople() {
- whenever(sectionsManager.isFilteringEnabled()).thenReturn(true)
- val aN = Notification.Builder(mContext, "test")
- .setStyle(Notification.MessagingStyle(""))
- .build()
- val a = NotificationEntryBuilder()
- .setImportance(IMPORTANCE_HIGH)
- .setPkg("pkg")
- .setOpPkg("pkg")
- .setTag("tag")
- .setNotification(aN)
- .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
- .setUser(mContext.user)
- .setOverrideGroupKey("")
- .build()
- whenever(personNotificationIdentifier.getPeopleNotificationType(a))
- .thenReturn(TYPE_PERSON)
-
- val bN = Notification.Builder(mContext, "test")
- .setStyle(Notification.MessagingStyle(""))
- .build()
- val b = NotificationEntryBuilder()
- .setImportance(IMPORTANCE_HIGH)
- .setPkg("pkg2")
- .setOpPkg("pkg2")
- .setTag("tag")
- .setNotification(bN)
- .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
- .setUser(mContext.user)
- .setOverrideGroupKey("")
- .build()
- whenever(personNotificationIdentifier.getPeopleNotificationType(b))
- .thenReturn(TYPE_FULL_PERSON)
-
- whenever(personNotificationIdentifier.compareTo(TYPE_PERSON, TYPE_FULL_PERSON))
- .thenReturn(TYPE_FULL_PERSON.compareTo(TYPE_PERSON))
- whenever(personNotificationIdentifier.compareTo(TYPE_FULL_PERSON, TYPE_PERSON))
- .thenReturn(TYPE_PERSON.compareTo(TYPE_FULL_PERSON))
-
- assertEquals(
- listOf(b, a),
- rankingManager.updateRanking(null, listOf(a, b), "test"))
- }
-
- @Test
- fun testSort_properlySetsAlertingBucket() {
- val notif = Notification.Builder(mContext, "test") .build()
-
- val e = NotificationEntryBuilder()
- .setPkg("pkg")
- .setOpPkg("pkg")
- .setTag("tag")
- .setNotification(notif)
- .setUser(mContext.user)
- .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
- .setOverrideGroupKey("")
- .build()
-
- modifyRanking(e).setImportance(IMPORTANCE_DEFAULT).build()
-
- rankingManager.updateRanking(RankingMap(arrayOf(e.ranking)), listOf(e), "test")
- assertEquals(e.bucket, BUCKET_ALERTING)
- }
-
- @Test
- fun testSort_properlySetsSilentBucket() {
- val notif = Notification.Builder(mContext, "test") .build()
-
- val e = NotificationEntryBuilder()
- .setPkg("pkg")
- .setOpPkg("pkg")
- .setTag("tag")
- .setNotification(notif)
- .setUser(mContext.user)
- .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
- .setOverrideGroupKey("")
- .build()
-
- modifyRanking(e).setImportance(IMPORTANCE_LOW).build()
-
- rankingManager.updateRanking(RankingMap(arrayOf(e.ranking)), listOf(e), "test")
- assertEquals(e.bucket, BUCKET_SILENT)
- }
-
- @Test
- fun testFilter_resetsInitalizationTime() {
- // GIVEN an entry that was initialized 1 second ago
- val notif = Notification.Builder(mContext, "test") .build()
-
- val e = NotificationEntryBuilder()
- .setPkg("pkg")
- .setOpPkg("pkg")
- .setTag("tag")
- .setNotification(notif)
- .setUser(mContext.user)
- .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
- .setOverrideGroupKey("")
- .build()
-
- e.setInitializationTime(SystemClock.elapsedRealtime() - 1000)
- assertEquals(true, e.hasFinishedInitialization())
-
- // WHEN we update ranking and filter out the notification entry
- whenever(notificationFilter.shouldFilterOut(e)).thenReturn(true)
- rankingManager.updateRanking(RankingMap(arrayOf(e.ranking)), listOf(e), "test")
-
- // THEN the initialization time for the entry is reset
- assertEquals(false, e.hasFinishedInitialization())
- }
-
- @Test
- fun testSort_colorizedForegroundService() {
- whenever(sectionsManager.isFilteringEnabled()).thenReturn(true)
-
- val a = NotificationEntryBuilder()
- .setImportance(IMPORTANCE_HIGH)
- .setPkg("pkg")
- .setOpPkg("pkg")
- .setTag("tag")
- .setNotification(
- Notification.Builder(mContext, "test")
- .build())
- .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
- .setUser(mContext.getUser())
- .setOverrideGroupKey("")
- .build()
-
- val b = NotificationEntryBuilder()
- .setImportance(IMPORTANCE_DEFAULT) // high priority
- .setPkg("pkg2")
- .setOpPkg("pkg2")
- .setTag("tag")
- .setNotification(mock(Notification::class.java).also { notif ->
- whenever(notif.isForegroundService).thenReturn(true)
- whenever(notif.isColorized).thenReturn(true)
- })
- .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
- .setUser(mContext.getUser())
- .setOverrideGroupKey("")
- .build()
-
- val cN = Notification.Builder(mContext, "test")
- .setStyle(Notification.MessagingStyle(""))
- .build()
- val c = NotificationEntryBuilder()
- .setImportance(IMPORTANCE_HIGH)
- .setPkg("pkg")
- .setOpPkg("pkg")
- .setTag("tag")
- .setNotification(cN)
- .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
- .setUser(mContext.user)
- .setOverrideGroupKey("")
- .build()
- whenever(personNotificationIdentifier.getPeopleNotificationType(a))
- .thenReturn(TYPE_IMPORTANT_PERSON)
-
- assertThat(rankingManager.updateRanking(null, listOf(a, b, c), "test"))
- .containsExactly(b, c, a)
- assertThat(b.bucket).isEqualTo(BUCKET_FOREGROUND_SERVICE)
- }
-
- @Test
- fun testSort_importantCall() {
- whenever(sectionsManager.isFilteringEnabled()).thenReturn(true)
-
- val a = NotificationEntryBuilder()
- .setImportance(IMPORTANCE_HIGH)
- .setPkg("pkg")
- .setOpPkg("pkg")
- .setTag("tag")
- .setNotification(
- Notification.Builder(mContext, "test")
- .build())
- .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
- .setUser(mContext.getUser())
- .setOverrideGroupKey("")
- .build()
-
- val b = NotificationEntryBuilder()
- .setImportance(IMPORTANCE_DEFAULT) // high priority
- .setPkg("pkg2")
- .setOpPkg("pkg2")
- .setTag("tag")
- .setNotification(mock(Notification::class.java).also { notif ->
- whenever(notif.isForegroundService).thenReturn(true)
- whenever(notif.isColorized).thenReturn(true)
- })
- .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
- .setUser(mContext.getUser())
- .setOverrideGroupKey("")
- .build()
-
- val cN = Notification.Builder(mContext, "test")
- .setStyle(Notification.MessagingStyle(""))
- .build()
- val c = NotificationEntryBuilder()
- .setImportance(IMPORTANCE_HIGH)
- .setPkg("pkg")
- .setOpPkg("pkg")
- .setTag("tag")
- .setNotification(cN)
- .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
- .setUser(mContext.user)
- .setOverrideGroupKey("")
- .build()
-
- val dN = Notification.Builder(mContext, "test")
- .setStyle(Notification.CallStyle.forOngoingCall(
- Person.Builder().setName("caller").build(),
- mock(PendingIntent::class.java)))
- .build()
- val d = NotificationEntryBuilder()
- .setImportance(IMPORTANCE_DEFAULT) // high priority
- .setPkg("pkg2")
- .setOpPkg("pkg2")
- .setTag("tag")
- .setNotification(dN)
- .setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
- .setUser(mContext.user)
- .setOverrideGroupKey("")
- .build()
- whenever(personNotificationIdentifier.getPeopleNotificationType(a))
- .thenReturn(TYPE_IMPORTANT_PERSON)
-
- assertThat(rankingManager.updateRanking(null, listOf(a, b, c, d), "test"))
- .containsExactly(b, d, c, a)
- assertThat(d.bucket).isEqualTo(BUCKET_FOREGROUND_SERVICE)
- }
-
- internal class TestableNotificationRankingManager(
- mediaManager: Lazy<NotificationMediaManager>,
- groupManager: NotificationGroupManagerLegacy,
- headsUpManager: HeadsUpManager,
- filter: NotificationFilter,
- logger: NotificationEntryManagerLogger,
- sectionsFeatureManager: NotificationSectionsFeatureManager,
- peopleNotificationIdentifier: PeopleNotificationIdentifier,
- highPriorityProvider: HighPriorityProvider,
- keyguardEnvironment: KeyguardEnvironment
- ) : NotificationRankingManager(
- mediaManager,
- groupManager,
- headsUpManager,
- filter,
- logger,
- sectionsFeatureManager,
- peopleNotificationIdentifier,
- highPriorityProvider,
- keyguardEnvironment
- ) {
- fun applyTestRankingMap(r: RankingMap) {
- rankingMap = r
- }
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
index e00e20f0e46b..46f630b7db63 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
@@ -33,9 +33,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -57,7 +55,6 @@ import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
-import com.android.systemui.statusbar.notification.NotificationFilter;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.policy.BatteryController;
@@ -85,8 +82,6 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
@Mock
AmbientDisplayConfiguration mAmbientDisplayConfiguration;
@Mock
- NotificationFilter mNotificationFilter;
- @Mock
StatusBarStateController mStatusBarStateController;
@Mock
KeyguardStateController mKeyguardStateController;
@@ -131,20 +126,10 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
/**
* Sets up the state such that any requests to
- * {@link NotificationInterruptStateProviderImpl#canAlertCommon(NotificationEntry)} will
- * pass as long its provided NotificationEntry fulfills group suppression check.
- */
- private void ensureStateForAlertCommon() {
- when(mNotificationFilter.shouldFilterOut(any())).thenReturn(false);
- }
-
- /**
- * Sets up the state such that any requests to
* {@link NotificationInterruptStateProviderImpl#shouldHeadsUp(NotificationEntry)} will
* pass as long its provided NotificationEntry fulfills importance & DND checks.
*/
private void ensureStateForHeadsUpWhenAwake() throws RemoteException {
- ensureStateForAlertCommon();
when(mHeadsUpManager.isSnoozed(any())).thenReturn(false);
when(mStatusBarStateController.isDozing()).thenReturn(false);
@@ -158,21 +143,10 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
* pass as long its provided NotificationEntry fulfills importance & DND checks.
*/
private void ensureStateForHeadsUpWhenDozing() {
- ensureStateForAlertCommon();
-
when(mStatusBarStateController.isDozing()).thenReturn(true);
when(mAmbientDisplayConfiguration.pulseOnNotificationEnabled(anyInt())).thenReturn(true);
}
- /**
- * Sets up the state such that any requests to
- * {@link NotificationInterruptStateProviderImpl#shouldBubbleUp(NotificationEntry)} will
- * pass as long its provided NotificationEntry fulfills importance & bubble checks.
- */
- private void ensureStateForBubbleUp() {
- ensureStateForAlertCommon();
- }
-
@Test
public void testDefaultSuppressorDoesNotSuppress() {
// GIVEN a suppressor without any overrides
@@ -201,27 +175,6 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
}
@Test
- public void testShouldNotHeadsUpAwake_flteredOut() throws RemoteException {
- // GIVEN state for "heads up when awake" is true
- ensureStateForHeadsUpWhenAwake();
-
- // WHEN this entry should be filtered out
- NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
- when(mNotificationFilter.shouldFilterOut(entry)).thenReturn(true);
-
- // THEN we shouldn't heads up this entry
- assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
- }
-
- @Test
- public void testDoNotRunFilterOnNewPipeline() {
- // WHEN this entry should be filtered out
- NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
- mNotifInterruptionStateProvider.shouldHeadsUp(entry);
- verify(mNotificationFilter, times(0)).shouldFilterOut(eq(entry));
- }
-
- @Test
public void testShouldNotHeadsUp_suppressedForGroups() throws RemoteException {
// GIVEN state for "heads up when awake" is true
ensureStateForHeadsUpWhenAwake();
@@ -654,7 +607,6 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
*/
@Test
public void testShouldBubbleUp() {
- ensureStateForBubbleUp();
assertThat(mNotifInterruptionStateProvider.shouldBubbleUp(createBubble())).isTrue();
}
@@ -664,7 +616,6 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
*/
@Test
public void testShouldBubbleUp_notifInGroupWithOnlySummaryAlerts() {
- ensureStateForBubbleUp();
NotificationEntry bubble = createBubble("testgroup", GROUP_ALERT_SUMMARY);
assertThat(mNotifInterruptionStateProvider.shouldBubbleUp(bubble)).isTrue();
}
@@ -674,8 +625,6 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
*/
@Test
public void shouldNotBubbleUp_notAllowedToBubble() {
- ensureStateForBubbleUp();
-
NotificationEntry entry = createBubble();
modifyRanking(entry)
.setCanBubble(false)
@@ -689,8 +638,6 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
*/
@Test
public void shouldNotBubbleUp_notABubble() {
- ensureStateForBubbleUp();
-
NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
modifyRanking(entry)
.setCanBubble(true)
@@ -704,8 +651,6 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
*/
@Test
public void shouldNotBubbleUp_invalidMetadata() {
- ensureStateForBubbleUp();
-
NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
modifyRanking(entry)
.setCanBubble(true)
@@ -717,8 +662,6 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
@Test
public void shouldNotBubbleUp_suppressedInterruptions() {
- ensureStateForBubbleUp();
-
// If the notification can't heads up in general, it shouldn't bubble.
mNotifInterruptionStateProvider.addSuppressor(mSuppressInterruptions);
@@ -727,8 +670,6 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
@Test
public void shouldNotBubbleUp_filteredOut() {
- ensureStateForBubbleUp();
-
// Make canAlertCommon false by saying it's filtered out
when(mKeyguardNotificationVisibilityProvider.shouldHideNotification(any()))
.thenReturn(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
index f57c40958b24..b6a1bb3b27d6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
@@ -26,7 +26,6 @@ import static android.service.notification.NotificationListenerService.Ranking.U
import static com.android.systemui.statusbar.NotificationEntryHelper.modifyRanking;
import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
@@ -37,7 +36,6 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anySet;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@@ -77,7 +75,6 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.notification.AssistantFeedbackController;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
@@ -88,7 +85,6 @@ import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.wmshell.BubblesManager;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -128,7 +124,6 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
@Mock private AccessibilityManager mAccessibilityManager;
@Mock private HighPriorityProvider mHighPriorityProvider;
@Mock private INotificationManager mINotificationManager;
- @Mock private NotificationEntryManager mNotificationEntryManager;
@Mock private LauncherApps mLauncherApps;
@Mock private ShortcutManager mShortcutManager;
@Mock private ChannelEditorDialogController mChannelEditorDialogController;
@@ -160,7 +155,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
mPeopleSpaceWidgetManager, mLauncherApps, mShortcutManager,
mChannelEditorDialogController, mContextTracker, mAssistantFeedbackController,
Optional.of(mBubblesManager), new UiEventLoggerFake(), mOnUserInteractionCallback,
- mShadeController, mock(DumpManager.class));
+ mShadeController);
mGutsManager.setUpWithPresenter(mPresenter, mNotificationListContainer,
mOnSettingsClickListener);
mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
@@ -446,36 +441,6 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
eq(mAssistantFeedbackController));
}
- @Test
- public void testShouldExtendLifetime() {
- NotificationGuts guts = new NotificationGuts(mContext);
- ExpandableNotificationRow row = spy(createTestNotificationRow());
- doReturn(guts).when(row).getGuts();
- NotificationEntry entry = row.getEntry();
- entry.setRow(row);
- mGutsManager.setExposedGuts(guts);
-
- assertTrue(mGutsManager.shouldExtendLifetime(entry));
- }
-
- @Test
- @Ignore
- public void testSetShouldManageLifetime_setShouldManage() {
- NotificationEntry entry = createTestNotificationRow().getEntry();
- mGutsManager.setShouldManageLifetime(entry, true /* shouldManage */);
-
- assertTrue(entry.getKey().equals(mGutsManager.mKeyToRemoveOnGutsClosed));
- }
-
- @Test
- public void testSetShouldManageLifetime_setShouldNotManage() {
- NotificationEntry entry = createTestNotificationRow().getEntry();
- mGutsManager.mKeyToRemoveOnGutsClosed = entry.getKey();
- mGutsManager.setShouldManageLifetime(entry, false /* shouldManage */);
-
- assertNull(mGutsManager.mKeyToRemoveOnGutsClosed);
- }
-
////////////////////////////////////////////////////////////////////////////////////////////////
// Utility methods:
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index 38bd078589dc..66821dd5e4b4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -51,7 +51,6 @@ import com.android.internal.logging.MetricsLogger;
import com.android.systemui.TestableDependency;
import com.android.systemui.classifier.FalsingCollectorFake;
import com.android.systemui.classifier.FalsingManagerFake;
-import com.android.systemui.dump.DumpManager;
import com.android.systemui.media.MediaFeatureFlag;
import com.android.systemui.media.dialog.MediaOutputDialogFactory;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -62,10 +61,11 @@ import com.android.systemui.statusbar.SmartReplyController;
import com.android.systemui.statusbar.notification.ConversationNotificationProcessor;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
-import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
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.GroupMembershipManager;
import com.android.systemui.statusbar.notification.icon.IconBuilder;
import com.android.systemui.statusbar.notification.icon.IconManager;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
@@ -84,7 +84,6 @@ import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent;
import com.android.systemui.tests.R;
import com.android.systemui.wmshell.BubblesManager;
import com.android.systemui.wmshell.BubblesTestActivity;
-import com.android.wm.shell.bubbles.Bubbles;
import org.mockito.ArgumentCaptor;
@@ -112,8 +111,8 @@ public class NotificationTestHelper {
private final Context mContext;
private final TestableLooper mTestLooper;
private int mId;
- private final NotificationGroupManagerLegacy mGroupMembershipManager;
- private final NotificationGroupManagerLegacy mGroupExpansionManager;
+ private final GroupMembershipManager mGroupMembershipManager;
+ private final GroupExpansionManager mGroupExpansionManager;
private ExpandableNotificationRow mRow;
private HeadsUpManagerPhone mHeadsUpManager;
private final NotifBindPipeline mBindPipeline;
@@ -136,24 +135,19 @@ public class NotificationTestHelper {
dependency.injectMockDependency(NotificationShadeWindowController.class);
dependency.injectMockDependency(MediaOutputDialogFactory.class);
mStatusBarStateController = mock(StatusBarStateController.class);
- mGroupMembershipManager = new NotificationGroupManagerLegacy(
- mStatusBarStateController,
- () -> mock(PeopleNotificationIdentifier.class),
- Optional.of((mock(Bubbles.class))),
- mock(DumpManager.class));
- mGroupExpansionManager = mGroupMembershipManager;
+ mGroupMembershipManager = mock(GroupMembershipManager.class);
+ mGroupExpansionManager = mock(GroupExpansionManager.class);
mHeadsUpManager = new HeadsUpManagerPhone(
mContext,
mock(HeadsUpManagerLogger.class),
mStatusBarStateController,
mock(KeyguardBypassController.class),
- mock(NotificationGroupManagerLegacy.class),
+ mock(GroupMembershipManager.class),
mock(VisualStabilityProvider.class),
mock(ConfigurationControllerImpl.class)
);
mHeadsUpManager.mHandler.removeCallbacksAndMessages(null);
mHeadsUpManager.mHandler = new Handler(mTestLooper.getLooper());
- mGroupMembershipManager.setHeadsUpManager(mHeadsUpManager);
mIconManager = new IconManager(
mock(CommonNotifCollection.class),
mock(LauncherApps.class),
@@ -529,10 +523,6 @@ public class NotificationTestHelper {
mBindStage.getStageParams(entry).requireContentViews(extraInflationFlags);
inflateAndWait(entry);
- // This would be done as part of onAsyncInflationFinished, but we skip large amounts of
- // the callback chain, so we need to make up for not adding it to the group manager
- // here.
- mGroupMembershipManager.onEntryAdded(entry);
return row;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
index ac9fcc064375..9d848e87b0a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
@@ -18,24 +18,7 @@ package com.android.systemui.statusbar.notification.stack;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_ALERTING;
-import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_FOREGROUND_SERVICE;
-import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_HEADS_UP;
-import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_PEOPLE;
-import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_SILENT;
-
-import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.testing.AndroidTestingRunner;
@@ -50,28 +33,19 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.media.KeyguardMediaController;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.notification.NotifPipelineFlags;
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.render.MediaContainerController;
import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
-import com.android.systemui.statusbar.notification.row.ActivatableNotificationViewController;
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.notification.row.dagger.NotificationRowComponent;
import com.android.systemui.statusbar.policy.ConfigurationController;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
-import java.util.ArrayList;
-import java.util.List;
-
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -84,15 +58,11 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
@Mock private ConfigurationController mConfigurationController;
@Mock private KeyguardMediaController mKeyguardMediaController;
@Mock private NotificationSectionsFeatureManager mSectionsFeatureManager;
- @Mock private NotificationRowComponent mNotificationRowComponent;
- @Mock private ActivatableNotificationViewController mActivatableNotificationViewController;
- @Mock private NotificationSectionsLogger mLogger;
@Mock private MediaContainerController mMediaContainerController;
@Mock private SectionHeaderController mIncomingHeaderController;
@Mock private SectionHeaderController mPeopleHeaderController;
@Mock private SectionHeaderController mAlertingHeaderController;
@Mock private SectionHeaderController mSilentHeaderController;
- @Mock private NotifPipelineFlags mNotifPipelineFlags;
private NotificationSectionsManager mSectionsManager;
@@ -113,22 +83,11 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
}
return count;
});
- when(mNotificationRowComponent.getActivatableNotificationViewController())
- .thenReturn(mActivatableNotificationViewController);
- when(mMediaContainerController.getMediaContainerView())
- .thenReturn(mock(MediaContainerView.class));
- when(mIncomingHeaderController.getHeaderView()).thenReturn(mock(SectionHeaderView.class));
- when(mPeopleHeaderController.getHeaderView()).thenReturn(mock(SectionHeaderView.class));
- when(mAlertingHeaderController.getHeaderView()).thenReturn(mock(SectionHeaderView.class));
- when(mSilentHeaderController.getHeaderView()).thenReturn(mock(SectionHeaderView.class));
mSectionsManager =
new NotificationSectionsManager(
- mStatusBarStateController,
mConfigurationController,
mKeyguardMediaController,
mSectionsFeatureManager,
- mLogger,
- mNotifPipelineFlags,
mMediaContainerController,
mIncomingHeaderController,
mPeopleHeaderController,
@@ -141,7 +100,6 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
mSectionsManager.initialize(mNssl);
when(mNssl.indexOfChild(any(View.class))).thenReturn(-1);
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
-
}
@Test(expected = IllegalStateException.class)
@@ -149,641 +107,4 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
mSectionsManager.initialize(mNssl);
}
- @Test
- public void testInsertHeader() {
- // GIVEN a stack with HI and LO rows but no section headers
- setStackState(
- ALERTING,
- ALERTING,
- ALERTING,
- GENTLE);
-
- // WHEN we update the section headers
- mSectionsManager.updateSectionBoundaries();
-
- // THEN a LO section header is added
- verify(mNssl).addView(mSectionsManager.getSilentHeaderView(), 3);
- }
-
- @Test
- public void testRemoveHeader() {
- // GIVEN a stack that originally had a header between the HI and LO sections
- setStackState(
- ALERTING,
- ALERTING,
- GENTLE);
- mSectionsManager.updateSectionBoundaries();
-
- // WHEN the last LO row is replaced with a HI row
- setStackState(
- ALERTING,
- ALERTING,
- GENTLE_HEADER,
- ALERTING);
- clearInvocations(mNssl);
- mSectionsManager.updateSectionBoundaries();
-
- // THEN the LO section header is removed
- verify(mNssl).removeView(mSectionsManager.getSilentHeaderView());
- }
-
- @Test
- public void testDoNothingIfHeaderAlreadyRemoved() {
- // GIVEN a stack with only HI rows
- setStackState(
- ALERTING,
- ALERTING,
- ALERTING);
-
- // WHEN we update the sections headers
- mSectionsManager.updateSectionBoundaries();
-
- // THEN we don't add any section headers
- verify(mNssl, never()).addView(eq(mSectionsManager.getSilentHeaderView()), anyInt());
- }
-
- @Test
- public void testMoveHeaderForward() {
- // GIVEN a stack that originally had a header between the HI and LO sections
- setStackState(
- ALERTING,
- ALERTING,
- ALERTING,
- GENTLE);
- mSectionsManager.updateSectionBoundaries();
-
- // WHEN the LO section moves forward
- setStackState(
- ALERTING,
- ALERTING,
- GENTLE,
- GENTLE_HEADER,
- GENTLE);
- mSectionsManager.updateSectionBoundaries();
-
- // THEN the LO section header is also moved forward
- verify(mNssl).changeViewPosition(mSectionsManager.getSilentHeaderView(), 2);
- }
-
- @Test
- public void testMoveHeaderBackward() {
- // GIVEN a stack that originally had a header between the HI and LO sections
- setStackState(
- ALERTING,
- GENTLE,
- GENTLE,
- GENTLE);
- mSectionsManager.updateSectionBoundaries();
-
- // WHEN the LO section moves backward
- setStackState(
- ALERTING,
- GENTLE_HEADER,
- ALERTING,
- ALERTING,
- GENTLE);
- mSectionsManager.updateSectionBoundaries();
-
- // THEN the LO section header is also moved backward (with appropriate index shifting)
- verify(mNssl).changeViewPosition(mSectionsManager.getSilentHeaderView(), 3);
- }
-
- @Test
- public void testHeaderRemovedFromTransientParent() {
- // GIVEN a stack where the header is animating away
- setStackState(
- ALERTING,
- GENTLE_HEADER);
- mSectionsManager.updateSectionBoundaries();
- clearInvocations(mNssl);
-
- SectionHeaderView silentHeaderView = mSectionsManager.getSilentHeaderView();
- ViewGroup transientParent = mock(ViewGroup.class);
- when(silentHeaderView.getTransientContainer()).thenReturn(transientParent);
-
- // WHEN the LO section reappears
- setStackState(
- ALERTING,
- GENTLE);
- mSectionsManager.updateSectionBoundaries();
-
- // THEN the header is first removed from the transient parent before being added to the
- // NSSL.
- final InOrder inOrder = inOrder(silentHeaderView, mNssl);
- inOrder.verify(silentHeaderView).removeFromTransientContainer();
- inOrder.verify(mNssl).addView(eq(silentHeaderView), eq(1));
- }
-
- @Test
- public void testHeaderNotShownOnLockscreen() {
- // GIVEN a stack of HI and LO notifs on the lockscreen
- when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
- setStackState(
- ALERTING,
- ALERTING,
- ALERTING,
- GENTLE);
-
- // WHEN we update the section headers
- mSectionsManager.updateSectionBoundaries();
-
- // Then the section header is not added
- verify(mNssl, never()).addView(eq(mSectionsManager.getSilentHeaderView()), anyInt());
- }
-
- @Test
- public void testHeaderShownWhenEnterLockscreen() {
- // GIVEN a stack of HI and LO notifs on the lockscreen
- when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
- setStackState(
- ALERTING,
- ALERTING,
- ALERTING,
- GENTLE);
- mSectionsManager.updateSectionBoundaries();
-
- // WHEN we unlock
- when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
- mSectionsManager.updateSectionBoundaries();
-
- // Then the section header is added
- verify(mNssl).addView(mSectionsManager.getSilentHeaderView(), 3);
- }
-
- @Test
- public void testHeaderHiddenWhenEnterLockscreen() {
- // GIVEN a stack of HI and LO notifs on the shade
- setStackState(
- ALERTING,
- GENTLE_HEADER,
- GENTLE);
-
- // WHEN we go back to the keyguard
- when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
- mSectionsManager.updateSectionBoundaries();
-
- // Then the section header is removed
- verify(mNssl).removeView(mSectionsManager.getSilentHeaderView());
- }
-
- @Test
- public void testPeopleFiltering_onlyAddSilentHeader() {
- enablePeopleFiltering();
-
- setStackState(
- PERSON,
- ALERTING,
- GENTLE);
- mSectionsManager.updateSectionBoundaries();
-
- verify(mNssl).addView(mSectionsManager.getSilentHeaderView(), 2);
- }
-
- @Test
- public void testPeopleFiltering_AlertingHunWhilePeopleVisible() {
- enablePeopleFiltering();
-
- setupMockStack(
- PEOPLE_HEADER,
- ALERTING,
- PERSON,
- ALERTING_HEADER,
- GENTLE_HEADER,
- GENTLE
- );
- mSectionsManager.updateSectionBoundaries();
-
- verifyMockStack(
- ChildType.HEADS_UP,
- ChildType.PERSON,
- ChildType.GENTLE_HEADER,
- ChildType.GENTLE
- );
- }
-
- @Test
- public void testPeopleFiltering_PersonHunWhileAlertingHunVisible() {
- enablePeopleFiltering();
-
- setupMockStack(
- PERSON,
- INCOMING_HEADER,
- ALERTING,
- PEOPLE_HEADER,
- PERSON
- );
- mSectionsManager.updateSectionBoundaries();
-
- verifyMockStack(
- ChildType.HEADS_UP,
- ChildType.HEADS_UP,
- ChildType.PERSON
- );
- }
-
- @Test
- public void testPeopleFiltering_PersonHun() {
- enablePeopleFiltering();
-
- setupMockStack(
- PERSON,
- PEOPLE_HEADER,
- PERSON
- );
- mSectionsManager.updateSectionBoundaries();
-
- verifyMockStack(
- ChildType.PERSON,
- ChildType.PERSON
- );
- }
-
- @Test
- public void testPeopleFiltering_AlertingHunWhilePersonHunning() {
- enablePeopleFiltering();
-
- setupMockStack(
- ALERTING,
- PERSON
- );
- mSectionsManager.updateSectionBoundaries();
- verifyMockStack(
- ChildType.HEADS_UP,
- ChildType.PERSON
- );
- }
-
- @Test
- public void testPeopleFiltering_Fsn() {
- enablePeopleFiltering();
-
- setupMockStack(
- INCOMING_HEADER,
- ALERTING,
- PEOPLE_HEADER,
- FSN,
- PERSON,
- ALERTING,
- GENTLE
- );
- mSectionsManager.updateSectionBoundaries();
-
- verifyMockStack(
- ChildType.HEADS_UP,
- ChildType.FSN,
- ChildType.PERSON,
- ChildType.ALERTING,
- ChildType.GENTLE_HEADER,
- ChildType.GENTLE
- );
- }
-
- @Test
- public void testMediaControls_AddWhenEnterKeyguard() {
- enableMediaControls();
-
- // GIVEN a stack that doesn't include media controls
- setStackState(ALERTING, GENTLE_HEADER, GENTLE);
-
- // WHEN we go back to the keyguard
- when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
- mSectionsManager.updateSectionBoundaries();
-
- // Then the media controls are added
- verify(mNssl).addView(mSectionsManager.getMediaControlsView(), 0);
- }
-
- @Test
- public void testMediaControls_AddWhenEnterKeyguardWithHeadsUp() {
- enableMediaControls();
-
- // GIVEN a stack that doesn't include media
- setupMockStack(
- ALERTING,
- ALERTING,
- GENTLE_HEADER,
- GENTLE);
-
- // WHEN we go back to the keyguard
- when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
- mSectionsManager.updateSectionBoundaries();
-
- verifyMockStack(
- ChildType.MEDIA_CONTROLS,
- ChildType.ALERTING,
- ChildType.ALERTING,
- ChildType.GENTLE);
- }
-
- @Test
- public void testRemoveNonSilentHeader() {
- enablePeopleFiltering();
- enableMediaControls();
-
- setupMockStack(
- MEDIA_CONTROLS,
- INCOMING_HEADER,
- PERSON,
- ALERTING,
- PEOPLE_HEADER,
- ALERTING_HEADER,
- ALERTING,
- ALERTING,
- GENTLE_HEADER,
- GENTLE,
- GENTLE
- );
-
- mSectionsManager.updateSectionBoundaries();
-
- verifyMockStack(
- ChildType.MEDIA_CONTROLS,
- ChildType.PERSON,
- ChildType.ALERTING,
- ChildType.ALERTING,
- ChildType.ALERTING,
- ChildType.GENTLE_HEADER,
- ChildType.GENTLE,
- ChildType.GENTLE
- );
- }
-
- @Test
- public void testExpandIncomingSection() {
- enablePeopleFiltering();
-
- setupMockStack(
- INCOMING_HEADER,
- PERSON,
- ALERTING,
- PEOPLE_HEADER,
- ALERTING,
- PERSON,
- ALERTING_HEADER,
- ALERTING
- );
-
- mSectionsManager.updateSectionBoundaries();
-
- verifyMockStack(
- ChildType.HEADS_UP,
- ChildType.HEADS_UP,
- ChildType.HEADS_UP,
- ChildType.PERSON,
- ChildType.ALERTING
- );
- }
-
- @Test
- public void testIgnoreGoneView() {
- enablePeopleFiltering();
-
- setupMockStack(
- PERSON.gone(),
- ALERTING,
- GENTLE
- );
-
- mSectionsManager.updateSectionBoundaries();
-
- verifyMockStack(
- ChildType.PERSON,
- ChildType.ALERTING,
- ChildType.GENTLE_HEADER,
- ChildType.GENTLE
- );
- }
-
- private void enablePeopleFiltering() {
- when(mSectionsFeatureManager.isFilteringEnabled()).thenReturn(true);
- }
-
- private void enableMediaControls() {
- when(mSectionsFeatureManager.isMediaControlsEnabled()).thenReturn(true);
- }
-
- private enum ChildType {
- INCOMING_HEADER, MEDIA_CONTROLS, PEOPLE_HEADER, ALERTING_HEADER, GENTLE_HEADER, HEADS_UP,
- FSN, PERSON, ALERTING, GENTLE, OTHER
- }
-
- private void setStackState(StackEntry... children) {
- when(mNssl.getChildCount()).thenReturn(children.length);
- for (int i = 0; i < children.length; i++) {
- View child;
- StackEntry entry = children[i];
- switch (entry.mChildType) {
- case INCOMING_HEADER:
- child = mSectionsManager.getIncomingHeaderView();
- break;
- case MEDIA_CONTROLS:
- child = mSectionsManager.getMediaControlsView();
- break;
- case PEOPLE_HEADER:
- child = mSectionsManager.getPeopleHeaderView();
- break;
- case ALERTING_HEADER:
- child = mSectionsManager.getAlertingHeaderView();
- break;
- case GENTLE_HEADER:
- child = mSectionsManager.getSilentHeaderView();
- break;
- case FSN:
- child = mockNotification(BUCKET_FOREGROUND_SERVICE, entry.mIsGone);
- break;
- case PERSON:
- child = mockNotification(BUCKET_PEOPLE, entry.mIsGone);
- break;
- case ALERTING:
- child = mockNotification(BUCKET_ALERTING, entry.mIsGone);
- break;
- case GENTLE:
- child = mockNotification(BUCKET_SILENT, entry.mIsGone);
- break;
- case OTHER:
- child = mock(View.class);
- when(child.getVisibility()).thenReturn(View.VISIBLE);
- when(child.getParent()).thenReturn(mNssl);
- break;
- default:
- throw new RuntimeException("Unknown ChildType: " + children[i]);
- }
- when(mNssl.getChildAt(i)).thenReturn(child);
- when(mNssl.indexOfChild(child)).thenReturn(i);
- }
- }
-
- private View mockNotification(@PriorityBucket int bucket, boolean isGone) {
- ExpandableNotificationRow notifRow =
- mock(ExpandableNotificationRow.class, RETURNS_DEEP_STUBS);
- when(notifRow.getVisibility()).thenReturn(View.VISIBLE);
- when(notifRow.getParent()).thenReturn(mNssl);
-
- NotificationEntry mockEntry = mock(NotificationEntry.class);
- when(notifRow.getEntry()).thenReturn(mockEntry);
-
- int[] bucketRef = new int[] { bucket };
- when(mockEntry.getBucket()).thenAnswer(invocation -> bucketRef[0]);
- doAnswer(invocation -> {
- bucketRef[0] = invocation.getArgument(0);
- return null;
- }).when(mockEntry).setBucket(anyInt());
-
- when(notifRow.getVisibility()).thenReturn(isGone ? View.GONE : View.VISIBLE);
- return notifRow;
- }
-
- private void verifyMockStack(ChildType... expected) {
- final List<ChildType> actual = new ArrayList<>();
- int childCount = mNssl.getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = mNssl.getChildAt(i);
- if (child == mSectionsManager.getIncomingHeaderView()) {
- actual.add(ChildType.INCOMING_HEADER);
- continue;
- }
- if (child == mSectionsManager.getMediaControlsView()) {
- actual.add(ChildType.MEDIA_CONTROLS);
- continue;
- }
- if (child == mSectionsManager.getPeopleHeaderView()) {
- actual.add(ChildType.PEOPLE_HEADER);
- continue;
- }
- if (child == mSectionsManager.getAlertingHeaderView()) {
- actual.add(ChildType.ALERTING_HEADER);
- continue;
- }
- if (child == mSectionsManager.getSilentHeaderView()) {
- actual.add(ChildType.GENTLE_HEADER);
- continue;
- }
- if (child instanceof ExpandableNotificationRow) {
- switch (((ExpandableNotificationRow) child).getEntry().getBucket()) {
- case BUCKET_HEADS_UP:
- actual.add(ChildType.HEADS_UP);
- break;
- case BUCKET_FOREGROUND_SERVICE:
- actual.add(ChildType.FSN);
- break;
- case BUCKET_PEOPLE:
- actual.add(ChildType.PERSON);
- break;
- case BUCKET_ALERTING:
- actual.add(ChildType.ALERTING);
- break;
- case BUCKET_SILENT:
- actual.add(ChildType.GENTLE);
- break;
- default:
- actual.add(ChildType.OTHER);
- break;
- }
- continue;
- }
- actual.add(ChildType.OTHER);
- }
- assertThat(actual).containsExactly((Object[]) expected).inOrder();
- }
-
- private void setupMockStack(StackEntry... entries) {
- final List<View> children = new ArrayList<>();
- when(mNssl.getChildCount()).thenAnswer(invocation -> children.size());
- when(mNssl.getChildAt(anyInt()))
- .thenAnswer(invocation -> {
- Integer index = invocation.getArgument(0);
- if (index == null || index < 0 || index >= children.size()) {
- return null;
- }
- return children.get(index);
- });
- when(mNssl.indexOfChild(any()))
- .thenAnswer(invocation -> children.indexOf(invocation.getArgument(0)));
- doAnswer(invocation -> {
- View child = invocation.getArgument(0);
- int index = invocation.getArgument(1);
- children.add(index, child);
- return null;
- }).when(mNssl).addView(any(), anyInt());
- doAnswer(invocation -> {
- View child = invocation.getArgument(0);
- children.remove(child);
- return null;
- }).when(mNssl).removeView(any());
- doAnswer(invocation -> {
- View child = invocation.getArgument(0);
- int newIndex = invocation.getArgument(1);
- children.remove(child);
- children.add(newIndex, child);
- return null;
- }).when(mNssl).changeViewPosition(any(), anyInt());
- for (StackEntry entry : entries) {
- View child;
- switch (entry.mChildType) {
- case INCOMING_HEADER:
- child = mSectionsManager.getIncomingHeaderView();
- break;
- case MEDIA_CONTROLS:
- child = mSectionsManager.getMediaControlsView();
- break;
- case PEOPLE_HEADER:
- child = mSectionsManager.getPeopleHeaderView();
- break;
- case ALERTING_HEADER:
- child = mSectionsManager.getAlertingHeaderView();
- break;
- case GENTLE_HEADER:
- child = mSectionsManager.getSilentHeaderView();
- break;
- case FSN:
- child = mockNotification(BUCKET_FOREGROUND_SERVICE, entry.mIsGone);
- break;
- case PERSON:
- child = mockNotification(BUCKET_PEOPLE, entry.mIsGone);
- break;
- case ALERTING:
- child = mockNotification(BUCKET_ALERTING, entry.mIsGone);
- break;
- case GENTLE:
- child = mockNotification(BUCKET_SILENT, entry.mIsGone);
- break;
- case OTHER:
- child = mock(View.class);
- when(child.getVisibility()).thenReturn(View.VISIBLE);
- when(child.getParent()).thenReturn(mNssl);
- break;
- default:
- throw new RuntimeException("Unknown ChildType: " + entry.mChildType);
- }
- children.add(child);
- }
- }
-
- private static final StackEntry INCOMING_HEADER = new StackEntry(ChildType.INCOMING_HEADER);
- private static final StackEntry MEDIA_CONTROLS = new StackEntry(ChildType.MEDIA_CONTROLS);
- private static final StackEntry PEOPLE_HEADER = new StackEntry(ChildType.PEOPLE_HEADER);
- private static final StackEntry ALERTING_HEADER = new StackEntry(ChildType.ALERTING_HEADER);
- private static final StackEntry GENTLE_HEADER = new StackEntry(ChildType.GENTLE_HEADER);
- private static final StackEntry FSN = new StackEntry(ChildType.FSN);
- private static final StackEntry PERSON = new StackEntry(ChildType.PERSON);
- private static final StackEntry ALERTING = new StackEntry(ChildType.ALERTING);
- private static final StackEntry GENTLE = new StackEntry(ChildType.GENTLE);
-
- private static class StackEntry {
- final ChildType mChildType;
- final boolean mIsGone;
-
- StackEntry(ChildType childType) {
- this(childType, false);
- }
-
- StackEntry(ChildType childType, boolean isGone) {
- mChildType = childType;
- mIsGone = isGone;
- }
-
- public StackEntry gone() {
- return new StackEntry(mChildType, true);
- }
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
index 9bcea101f83b..1460e048d234 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
@@ -67,6 +67,7 @@ import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -121,7 +122,8 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
@Mock private NotificationSwipeHelper mNotificationSwipeHelper;
@Mock private CentralSurfaces mCentralSurfaces;
@Mock private ScrimController mScrimController;
- @Mock private NotificationGroupManagerLegacy mLegacyGroupManager;
+ @Mock private NotificationGroupManagerLegacy mGroupManagerLegacy;
+ @Mock private GroupExpansionManager mGroupExpansionManager;
@Mock private SectionHeaderController mSilentHeaderController;
@Mock private NotifPipelineFlags mNotifPipelineFlags;
@Mock private NotifPipeline mNotifPipeline;
@@ -174,8 +176,8 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
mNotificationSwipeHelperBuilder,
mCentralSurfaces,
mScrimController,
- mLegacyGroupManager,
- mLegacyGroupManager,
+ mGroupManagerLegacy,
+ mGroupExpansionManager,
mSilentHeaderController,
mNotifPipeline,
mNotifCollection,
@@ -184,7 +186,6 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
mShadeTransitionController,
mUiEventLogger,
mRemoteInputManager,
- mVisualStabilityManager,
mShadeController,
mJankMonitor,
mStackLogger,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 37a48937419a..3c22edc0fcf2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -66,7 +66,6 @@ import com.android.systemui.statusbar.NotificationShelfController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -101,8 +100,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
@Rule public MockitoRule mockito = MockitoJUnit.rule();
@Mock private CentralSurfaces mCentralSurfaces;
@Mock private SysuiStatusBarStateController mBarState;
- @Mock private NotificationGroupManagerLegacy mGroupMembershipManger;
- @Mock private NotificationGroupManagerLegacy mGroupExpansionManager;
+ @Mock private GroupMembershipManager mGroupMembershipManger;
+ @Mock private GroupExpansionManager mGroupExpansionManager;
@Mock private DumpManager mDumpManager;
@Mock private ExpandHelper mExpandHelper;
@Mock private EmptyShadeView mEmptyShadeView;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index 7b7f45a44615..a0f7087ddb9e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -418,7 +418,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
wakefulnessLifecycle,
mStatusBarStateController,
Optional.of(mBubbles),
- mVisualStabilityManager,
mDeviceProvisionedController,
mNavigationBarController,
mAccessibilityFloatingMenuController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
index db5741c90ebc..2ab2172b7e29 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
@@ -25,7 +25,6 @@ import static org.mockito.Mockito.when;
import android.content.Context;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
-import android.view.View;
import androidx.test.filters.SmallTest;
@@ -35,8 +34,8 @@ import com.android.systemui.statusbar.AlertingNotificationManagerTest;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
-import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
+import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.HeadsUpManagerLogger;
@@ -60,19 +59,18 @@ public class HeadsUpManagerPhoneTest extends AlertingNotificationManagerTest {
private HeadsUpManagerPhone mHeadsUpManager;
@Mock private HeadsUpManagerLogger mHeadsUpManagerLogger;
- @Mock private NotificationGroupManagerLegacy mGroupManager;
- @Mock private View mNotificationShadeWindowView;
+ @Mock private GroupMembershipManager mGroupManager;
@Mock private VisualStabilityProvider mVSProvider;
@Mock private StatusBarStateController mStatusBarStateController;
@Mock private KeyguardBypassController mBypassController;
@Mock private ConfigurationControllerImpl mConfigurationController;
private boolean mLivesPastNormalTime;
- private final class TestableHeadsUpManagerPhone extends HeadsUpManagerPhone {
+ private static final class TestableHeadsUpManagerPhone extends HeadsUpManagerPhone {
TestableHeadsUpManagerPhone(
Context context,
HeadsUpManagerLogger headsUpManagerLogger,
- NotificationGroupManagerLegacy groupManager,
+ GroupMembershipManager groupManager,
VisualStabilityProvider visualStabilityProvider,
StatusBarStateController statusBarStateController,
KeyguardBypassController keyguardBypassController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
deleted file mode 100644
index 7070bc19db62..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * Copyright (C) 2018 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.phone;
-
-import static com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON;
-import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.Notification;
-import android.service.notification.StatusBarNotification;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.dump.DumpManager;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-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.legacy.NotificationGroupManagerLegacy;
-import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
-import com.android.systemui.statusbar.notification.row.NotifBindPipeline.BindCallback;
-import com.android.systemui.statusbar.notification.row.RowContentBindParams;
-import com.android.systemui.statusbar.notification.row.RowContentBindStage;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.statusbar.policy.HeadsUpManagerLogger;
-import com.android.wm.shell.bubbles.Bubbles;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-import java.util.HashMap;
-import java.util.Optional;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class NotificationGroupAlertTransferHelperTest extends SysuiTestCase {
- @Rule public MockitoRule rule = MockitoJUnit.rule();
-
- private NotificationGroupAlertTransferHelper mGroupAlertTransferHelper;
- private NotificationGroupManagerLegacy mGroupManager;
- private HeadsUpManager mHeadsUpManager;
- @Mock private NotificationEntryManager mNotificationEntryManager;
- @Mock private RowContentBindStage mBindStage;
- @Mock PeopleNotificationIdentifier mPeopleNotificationIdentifier;
- @Mock StatusBarStateController mStatusBarStateController;
- @Captor private ArgumentCaptor<NotificationEntryListener> mListenerCaptor;
- private NotificationEntryListener mNotificationEntryListener;
- private final HashMap<String, NotificationEntry> mPendingEntries = new HashMap<>();
- private final NotificationGroupTestHelper mGroupTestHelper =
- new NotificationGroupTestHelper(mContext);
-
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- mHeadsUpManager = new HeadsUpManager(mContext, mock(HeadsUpManagerLogger.class)) {};
-
- when(mNotificationEntryManager.getPendingNotificationsIterator())
- .thenReturn(mPendingEntries.values());
-
- mGroupManager = new NotificationGroupManagerLegacy(
- mStatusBarStateController,
- () -> mPeopleNotificationIdentifier,
- Optional.of(mock(Bubbles.class)),
- mock(DumpManager.class));
- mDependency.injectTestDependency(NotificationGroupManagerLegacy.class, mGroupManager);
- mGroupManager.setHeadsUpManager(mHeadsUpManager);
-
- when(mBindStage.getStageParams(any())).thenReturn(new RowContentBindParams());
-
- mGroupAlertTransferHelper = new NotificationGroupAlertTransferHelper(
- mBindStage, mStatusBarStateController, mGroupManager);
- mGroupAlertTransferHelper.setHeadsUpManager(mHeadsUpManager);
-
- mGroupAlertTransferHelper.bind(mNotificationEntryManager, mGroupManager);
- verify(mNotificationEntryManager).addNotificationEntryListener(mListenerCaptor.capture());
- mNotificationEntryListener = mListenerCaptor.getValue();
- mHeadsUpManager.addListener(mGroupAlertTransferHelper);
- }
-
- @After
- public void tearDown() {
- mHeadsUpManager.mHandler.removeCallbacksAndMessages(null);
- }
-
- private void mockHasHeadsUpContentView(NotificationEntry entry,
- boolean hasHeadsUpContentView) {
- RowContentBindParams params = new RowContentBindParams();
- if (hasHeadsUpContentView) {
- params.requireContentViews(FLAG_CONTENT_VIEW_HEADS_UP);
- }
- when(mBindStage.getStageParams(eq(entry))).thenReturn(params);
- }
-
- private void mockHasHeadsUpContentView(NotificationEntry entry) {
- mockHasHeadsUpContentView(entry, true);
- }
-
- private void mockIsPriority(NotificationEntry priorityEntry) {
- when(mPeopleNotificationIdentifier.getPeopleNotificationType(eq(priorityEntry)))
- .thenReturn(PeopleNotificationIdentifier.TYPE_IMPORTANT_PERSON);
- }
-
- @Test
- public void testSuppressedSummaryHeadsUpTransfersToChild() {
- NotificationEntry summaryEntry = mGroupTestHelper.createSummaryNotification();
- mHeadsUpManager.showNotification(summaryEntry);
- NotificationEntry childEntry = mGroupTestHelper.createChildNotification();
-
- mockHasHeadsUpContentView(childEntry);
-
- // Summary will be suppressed because there is only one child.
- mGroupManager.onEntryAdded(summaryEntry);
- mGroupManager.onEntryAdded(childEntry);
-
- // A suppressed summary should transfer its alert state to the child.
- assertFalse(mHeadsUpManager.isAlerting(summaryEntry.getKey()));
- assertTrue(mHeadsUpManager.isAlerting(childEntry.getKey()));
- }
-
- @Test
- public void testSuppressedSummaryHeadsUpTransfersToChildButBackAgain() {
- NotificationEntry summaryEntry =
- mGroupTestHelper.createSummaryNotification(Notification.GROUP_ALERT_SUMMARY);
- NotificationEntry childEntry =
- mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY);
- NotificationEntry childEntry2 =
- mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY);
- mHeadsUpManager.showNotification(summaryEntry);
- // Trigger a transfer of alert state from summary to child.
- mGroupManager.onEntryAdded(summaryEntry);
- mGroupManager.onEntryAdded(childEntry);
-
- // Add second child notification so that summary is no longer suppressed.
- mPendingEntries.put(childEntry2.getKey(), childEntry2);
- mNotificationEntryListener.onPendingEntryAdded(childEntry2);
- mGroupManager.onEntryAdded(childEntry2);
-
- // The alert state should transfer back to the summary as there is now more than one
- // child and the summary should no longer be suppressed.
- assertTrue(mHeadsUpManager.isAlerting(summaryEntry.getKey()));
- assertFalse(mHeadsUpManager.isAlerting(childEntry.getKey()));
- }
-
- @Test
- public void testSuppressedSummaryHeadsUpDoesntTransferBackOnDozingChanged() {
- NotificationEntry summaryEntry =
- mGroupTestHelper.createSummaryNotification(Notification.GROUP_ALERT_SUMMARY);
- NotificationEntry childEntry =
- mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY);
- NotificationEntry childEntry2 =
- mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY);
- mHeadsUpManager.showNotification(summaryEntry);
- // Trigger a transfer of alert state from summary to child.
- mGroupManager.onEntryAdded(summaryEntry);
- mGroupManager.onEntryAdded(childEntry);
-
- // Set dozing to true.
- mGroupAlertTransferHelper.onDozingChanged(true);
-
- // Add second child notification so that summary is no longer suppressed.
- mPendingEntries.put(childEntry2.getKey(), childEntry2);
- mNotificationEntryListener.onPendingEntryAdded(childEntry2);
- mGroupManager.onEntryAdded(childEntry2);
-
- // Dozing changed so no reason to re-alert summary.
- assertFalse(mHeadsUpManager.isAlerting(summaryEntry.getKey()));
- }
-
- @Test
- public void testSuppressedSummaryHeadsUpTransferDoesNotAlertChildIfUninflated() {
- NotificationEntry summaryEntry = mGroupTestHelper.createSummaryNotification();
- mHeadsUpManager.showNotification(summaryEntry);
- NotificationEntry childEntry = mGroupTestHelper.createChildNotification();
- mockHasHeadsUpContentView(childEntry, false);
-
- mGroupManager.onEntryAdded(summaryEntry);
- mGroupManager.onEntryAdded(childEntry);
-
- // Alert is immediately removed from summary, but we do not show child yet either as its
- // content is not inflated.
- assertFalse(mHeadsUpManager.isAlerting(summaryEntry.getKey()));
- assertFalse(mHeadsUpManager.isAlerting(childEntry.getKey()));
- assertTrue(mGroupAlertTransferHelper.isAlertTransferPending(childEntry));
- }
-
- @Test
- public void testSuppressedSummaryHeadsUpTransferAlertsChildOnInflation() {
- NotificationEntry summaryEntry = mGroupTestHelper.createSummaryNotification();
- mHeadsUpManager.showNotification(summaryEntry);
- NotificationEntry childEntry = mGroupTestHelper.createChildNotification();
- mockHasHeadsUpContentView(childEntry, false);
-
- mGroupManager.onEntryAdded(summaryEntry);
- mGroupManager.onEntryAdded(childEntry);
-
- // Child entry finishes its inflation.
- ArgumentCaptor<BindCallback> callbackCaptor = ArgumentCaptor.forClass(BindCallback.class);
- verify(mBindStage).requestRebind(eq(childEntry), callbackCaptor.capture());
- callbackCaptor.getValue().onBindFinished(childEntry);
-
- // Alert is immediately removed from summary, and we show child as its content is inflated.
- assertFalse(mHeadsUpManager.isAlerting(summaryEntry.getKey()));
- assertTrue(mHeadsUpManager.isAlerting(childEntry.getKey()));
- }
-
- @Test
- public void testSuppressedSummaryHeadsUpTransferBackAbortsChildInflation() {
- NotificationEntry summaryEntry =
- mGroupTestHelper.createSummaryNotification(Notification.GROUP_ALERT_SUMMARY);
- NotificationEntry childEntry =
- mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY);
- RowContentBindParams params = new RowContentBindParams();
- when(mBindStage.getStageParams(eq(childEntry))).thenReturn(params);
-
- NotificationEntry childEntry2 =
- mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY);
- mHeadsUpManager.showNotification(summaryEntry);
- // Trigger a transfer of alert state from summary to child.
- mGroupManager.onEntryAdded(summaryEntry);
- mGroupManager.onEntryAdded(childEntry);
-
- // Add second child notification so that summary is no longer suppressed.
- mPendingEntries.put(childEntry2.getKey(), childEntry2);
- mNotificationEntryListener.onPendingEntryAdded(childEntry2);
- mGroupManager.onEntryAdded(childEntry2);
-
- // Child entry finishes its inflation.
- ArgumentCaptor<BindCallback> callbackCaptor = ArgumentCaptor.forClass(BindCallback.class);
- verify(mBindStage).requestRebind(eq(childEntry), callbackCaptor.capture());
- callbackCaptor.getValue().onBindFinished(childEntry);
-
- assertTrue((params.getContentViews() & FLAG_CONTENT_VIEW_HEADS_UP) == 0);
- assertFalse(mHeadsUpManager.isAlerting(childEntry.getKey()));
- }
-
- @Test
- public void testCleanUpPendingAlertInfo() {
- NotificationEntry summaryEntry =
- mGroupTestHelper.createSummaryNotification(Notification.GROUP_ALERT_SUMMARY);
- NotificationEntry childEntry =
- mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY);
- mockHasHeadsUpContentView(childEntry, false);
-
- mHeadsUpManager.showNotification(summaryEntry);
- // Trigger a transfer of alert state from summary to child.
- mGroupManager.onEntryAdded(summaryEntry);
- mGroupManager.onEntryAdded(childEntry);
-
- mNotificationEntryListener.onEntryRemoved(
- childEntry, null, false, UNDEFINED_DISMISS_REASON);
-
- assertFalse(mGroupAlertTransferHelper.isAlertTransferPending(childEntry));
- }
-
- @Test
- public void testUpdateGroupChangeDoesNotTransfer() {
- NotificationEntry summaryEntry =
- mGroupTestHelper.createSummaryNotification(Notification.GROUP_ALERT_SUMMARY);
- NotificationEntry childEntry =
- mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY);
- mockHasHeadsUpContentView(childEntry, false);
-
- mHeadsUpManager.showNotification(summaryEntry);
- // Trigger a transfer of alert state from summary to child.
- mGroupManager.onEntryAdded(summaryEntry);
- mGroupManager.onEntryAdded(childEntry);
-
- // Notify that entry changed groups.
- StatusBarNotification oldNotification = childEntry.getSbn();
- StatusBarNotification newSbn = spy(childEntry.getSbn().clone());
- doReturn("other_group").when(newSbn).getGroupKey();
- childEntry.setSbn(newSbn);
- mGroupManager.onEntryUpdated(childEntry, oldNotification);
-
- assertFalse(mGroupAlertTransferHelper.isAlertTransferPending(childEntry));
- }
-
- @Test
- public void testUpdateChildToSummaryDoesNotTransfer() {
- final String tag = "fooTag";
- NotificationEntry summaryEntry =
- mGroupTestHelper.createSummaryNotification(Notification.GROUP_ALERT_SUMMARY);
- NotificationEntry childEntry =
- mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY, 47, tag);
- mockHasHeadsUpContentView(childEntry, false);
-
- mHeadsUpManager.showNotification(summaryEntry);
- // Trigger a transfer of alert state from summary to child.
- mGroupManager.onEntryAdded(summaryEntry);
- mGroupManager.onEntryAdded(childEntry);
-
- // Update that child to a summary.
- StatusBarNotification oldNotification = childEntry.getSbn();
- childEntry.setSbn(
- mGroupTestHelper.createSummaryNotification(
- Notification.GROUP_ALERT_SUMMARY, 47, tag).getSbn());
- mGroupManager.onEntryUpdated(childEntry, oldNotification);
-
- assertFalse(mGroupAlertTransferHelper.isAlertTransferPending(childEntry));
- }
-
- @Test
- public void testOverriddenSummaryHeadsUpTransfersToPriority() {
- // Creation order is oldest to newest, meaning the priority will be deemed newest
- int groupAlert = Notification.GROUP_ALERT_SUMMARY;
- NotificationEntry summaryEntry = mGroupTestHelper.createSummaryNotification(groupAlert);
- NotificationEntry childEntry = mGroupTestHelper.createChildNotification(groupAlert);
- NotificationEntry priorityEntry = mGroupTestHelper.createChildNotification(groupAlert);
- mockIsPriority(priorityEntry);
-
- // summary gets heads up
- mHeadsUpManager.showNotification(summaryEntry);
-
- mockHasHeadsUpContentView(summaryEntry);
- mockHasHeadsUpContentView(priorityEntry);
- mockHasHeadsUpContentView(childEntry);
-
- // Summary will have an alertOverride.
- mGroupManager.onEntryAdded(summaryEntry);
- mGroupManager.onEntryAdded(priorityEntry);
- mGroupManager.onEntryAdded(childEntry);
-
- // An overridden summary should transfer its alert state to the priority.
- assertFalse(mHeadsUpManager.isAlerting(summaryEntry.getKey()));
- assertFalse(mHeadsUpManager.isAlerting(childEntry.getKey()));
- assertTrue(mHeadsUpManager.isAlerting(priorityEntry.getKey()));
- }
-
- @Test
- public void testOverriddenSummaryHeadsUpTransferDoesNotAlertPriorityIfUninflated() {
- // Creation order is oldest to newest, meaning the priority will be deemed newest
- int groupAlert = Notification.GROUP_ALERT_SUMMARY;
- NotificationEntry summaryEntry = mGroupTestHelper.createSummaryNotification(groupAlert);
- NotificationEntry childEntry = mGroupTestHelper.createChildNotification(groupAlert);
- NotificationEntry priorityEntry = mGroupTestHelper.createChildNotification(groupAlert);
- mockIsPriority(priorityEntry);
-
- // summary gets heads up
- mHeadsUpManager.showNotification(summaryEntry);
-
- mockHasHeadsUpContentView(summaryEntry);
- mockHasHeadsUpContentView(priorityEntry, false);
- mockHasHeadsUpContentView(childEntry);
-
- // Summary will have an alertOverride.
- mGroupManager.onEntryAdded(summaryEntry);
- mGroupManager.onEntryAdded(priorityEntry);
- mGroupManager.onEntryAdded(childEntry);
-
- // Alert is immediately removed from summary, but we do not show priority yet either as its
- // content is not inflated.
- assertFalse(mHeadsUpManager.isAlerting(summaryEntry.getKey()));
- assertFalse(mHeadsUpManager.isAlerting(childEntry.getKey()));
- assertFalse(mHeadsUpManager.isAlerting(priorityEntry.getKey()));
- assertTrue(mGroupAlertTransferHelper.isAlertTransferPending(priorityEntry));
- }
-
- @Test
- public void testOverriddenSummaryHeadsUpTransfersToPriorityButBackAgain() {
- // Creation order is oldest to newest, meaning the child2 will ultimately be deemed newest
- int groupAlert = Notification.GROUP_ALERT_SUMMARY;
- NotificationEntry summaryEntry = mGroupTestHelper.createSummaryNotification(groupAlert);
- NotificationEntry childEntry = mGroupTestHelper.createChildNotification(groupAlert);
- NotificationEntry priorityEntry = mGroupTestHelper.createChildNotification(groupAlert);
- NotificationEntry childEntry2 = mGroupTestHelper.createChildNotification(groupAlert);
- mockIsPriority(priorityEntry);
-
- // summary gets heads up
- mHeadsUpManager.showNotification(summaryEntry);
-
- mockHasHeadsUpContentView(summaryEntry);
- mockHasHeadsUpContentView(priorityEntry);
- mockHasHeadsUpContentView(childEntry);
- mockHasHeadsUpContentView(childEntry2);
-
- // Summary will have an alertOverride.
- mGroupManager.onEntryAdded(summaryEntry);
- mGroupManager.onEntryAdded(priorityEntry);
- mGroupManager.onEntryAdded(childEntry);
-
- // An overridden summary should transfer its alert state to the priority.
- assertFalse(mHeadsUpManager.isAlerting(summaryEntry.getKey()));
- assertFalse(mHeadsUpManager.isAlerting(childEntry.getKey()));
- assertTrue(mHeadsUpManager.isAlerting(priorityEntry.getKey()));
-
- mGroupManager.onEntryAdded(childEntry2);
-
- // An overridden summary should transfer its alert state to the priority.
- assertTrue(mHeadsUpManager.isAlerting(summaryEntry.getKey()));
- assertFalse(mHeadsUpManager.isAlerting(childEntry.getKey()));
- assertFalse(mHeadsUpManager.isAlerting(childEntry2.getKey()));
- assertFalse(mHeadsUpManager.isAlerting(priorityEntry.getKey()));
- }
-
- @Test
- public void testOverriddenSuppressedSummaryHeadsUpTransfersToChildThenToPriority() {
- // Creation order is oldest to newest, meaning the priority will ultimately be deemed newest
- int groupAlert = Notification.GROUP_ALERT_SUMMARY;
- NotificationEntry summaryEntry = mGroupTestHelper.createSummaryNotification(groupAlert);
- NotificationEntry childEntry = mGroupTestHelper.createChildNotification(groupAlert);
- NotificationEntry priorityEntry = mGroupTestHelper.createChildNotification(groupAlert);
- mockIsPriority(priorityEntry);
-
- // summary gets heads up
- mHeadsUpManager.showNotification(summaryEntry);
-
- mockHasHeadsUpContentView(summaryEntry);
- mockHasHeadsUpContentView(priorityEntry);
- mockHasHeadsUpContentView(childEntry);
-
- // Summary will be suppressed, and the child will receive the alert
- mGroupManager.onEntryAdded(summaryEntry);
- mGroupManager.onEntryAdded(childEntry);
-
- assertFalse(mHeadsUpManager.isAlerting(summaryEntry.getKey()));
- assertTrue(mHeadsUpManager.isAlerting(childEntry.getKey()));
-
- // Alert should be transferred "back" from the child to the priority
- mGroupManager.onEntryAdded(priorityEntry);
-
- assertFalse(mHeadsUpManager.isAlerting(summaryEntry.getKey()));
- assertFalse(mHeadsUpManager.isAlerting(childEntry.getKey()));
- assertTrue(mHeadsUpManager.isAlerting(priorityEntry.getKey()));
- }
-
- @Test
- public void testOverriddenSuppressedSummaryHeadsUpTransfersToPriorityThenToChild() {
- // Creation order is oldest to newest, meaning the child will ultimately be deemed newest
- int groupAlert = Notification.GROUP_ALERT_SUMMARY;
- NotificationEntry summaryEntry = mGroupTestHelper.createSummaryNotification(groupAlert);
- NotificationEntry priorityEntry = mGroupTestHelper.createChildNotification(groupAlert);
- NotificationEntry childEntry = mGroupTestHelper.createChildNotification(groupAlert);
- mockIsPriority(priorityEntry);
-
- // summary gets heads up
- mHeadsUpManager.showNotification(summaryEntry);
-
- mockHasHeadsUpContentView(summaryEntry);
- mockHasHeadsUpContentView(priorityEntry);
- mockHasHeadsUpContentView(childEntry);
-
- // Summary will have alert override of the priority
- mGroupManager.onEntryAdded(summaryEntry);
- mGroupManager.onEntryAdded(priorityEntry);
-
- assertFalse(mHeadsUpManager.isAlerting(summaryEntry.getKey()));
- assertTrue(mHeadsUpManager.isAlerting(priorityEntry.getKey()));
-
- // Alert should be transferred "back" from the priority to the child (which is newer)
- mGroupManager.onEntryAdded(childEntry);
-
- assertFalse(mHeadsUpManager.isAlerting(summaryEntry.getKey()));
- assertTrue(mHeadsUpManager.isAlerting(childEntry.getKey()));
- assertFalse(mHeadsUpManager.isAlerting(priorityEntry.getKey()));
- }
-
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerLegacyTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerLegacyTest.java
deleted file mode 100644
index d002cebe5cb1..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerLegacyTest.java
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * Copyright (C) 2018 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.phone;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import static org.junit.Assert.assertNull;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.app.Notification;
-import android.service.notification.StatusBarNotification;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.util.Log;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.dump.DumpManager;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
-import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy.NotificationGroup;
-import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy.OnGroupChangeListener;
-import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.wm.shell.bubbles.Bubbles;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-import java.util.Optional;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class NotificationGroupManagerLegacyTest extends SysuiTestCase {
- @Rule
- public MockitoRule rule = MockitoJUnit.rule();
-
- private NotificationGroupManagerLegacy mGroupManager;
- private final NotificationGroupTestHelper mGroupTestHelper =
- new NotificationGroupTestHelper(mContext);
-
- @Mock
- PeopleNotificationIdentifier mPeopleNotificationIdentifier;
- @Mock
- HeadsUpManager mHeadsUpManager;
-
- @Before
- public void setup() {
- mDependency.injectMockDependency(Bubbles.class);
- initializeGroupManager();
- }
-
- private void initializeGroupManager() {
- mGroupManager = new NotificationGroupManagerLegacy(
- mock(StatusBarStateController.class),
- () -> mPeopleNotificationIdentifier,
- Optional.of(mock(Bubbles.class)),
- mock(DumpManager.class));
- mGroupManager.setHeadsUpManager(mHeadsUpManager);
- }
-
- @Test
- public void testIsOnlyChildInGroup() {
- NotificationEntry childEntry = mGroupTestHelper.createChildNotification();
- NotificationEntry summaryEntry = mGroupTestHelper.createSummaryNotification();
-
- mGroupManager.onEntryAdded(summaryEntry);
- mGroupManager.onEntryAdded(childEntry);
-
- assertTrue(mGroupManager.isOnlyChildInGroup(childEntry));
- }
-
- @Test
- public void testIsChildInGroupWithSummary() {
- NotificationEntry childEntry = mGroupTestHelper.createChildNotification();
- NotificationEntry summaryEntry = mGroupTestHelper.createSummaryNotification();
-
- mGroupManager.onEntryAdded(summaryEntry);
- mGroupManager.onEntryAdded(childEntry);
- mGroupManager.onEntryAdded(mGroupTestHelper.createChildNotification());
-
- assertTrue(mGroupManager.isChildInGroup(childEntry));
- }
-
- @Test
- public void testIsSummaryOfGroupWithChildren() {
- NotificationEntry childEntry = mGroupTestHelper.createChildNotification();
- NotificationEntry summaryEntry = mGroupTestHelper.createSummaryNotification();
-
- mGroupManager.onEntryAdded(summaryEntry);
- mGroupManager.onEntryAdded(childEntry);
- mGroupManager.onEntryAdded(mGroupTestHelper.createChildNotification());
-
- assertTrue(mGroupManager.isGroupSummary(summaryEntry));
- assertEquals(summaryEntry, mGroupManager.getGroupSummary(childEntry));
- }
-
- @Test
- public void testRemoveChildFromGroupWithSummary() {
- NotificationEntry childEntry = mGroupTestHelper.createChildNotification();
- NotificationEntry summaryEntry = mGroupTestHelper.createSummaryNotification();
- mGroupManager.onEntryAdded(summaryEntry);
- mGroupManager.onEntryAdded(childEntry);
- mGroupManager.onEntryAdded(mGroupTestHelper.createChildNotification());
-
- mGroupManager.onEntryRemoved(childEntry);
-
- assertFalse(mGroupManager.isChildInGroup(childEntry));
- }
-
- @Test
- public void testRemoveSummaryFromGroupWithSummary() {
- NotificationEntry childEntry = mGroupTestHelper.createChildNotification();
- NotificationEntry summaryEntry = mGroupTestHelper.createSummaryNotification();
- mGroupManager.onEntryAdded(summaryEntry);
- mGroupManager.onEntryAdded(childEntry);
- mGroupManager.onEntryAdded(mGroupTestHelper.createChildNotification());
-
- mGroupManager.onEntryRemoved(summaryEntry);
-
- assertNull(mGroupManager.getGroupSummary(childEntry));
- assertFalse(mGroupManager.isGroupSummary(summaryEntry));
- }
-
- @Test
- public void testHeadsUpEntryIsIsolated() {
- NotificationEntry childEntry = mGroupTestHelper.createChildNotification();
- NotificationEntry summaryEntry = mGroupTestHelper.createSummaryNotification();
- mGroupManager.onEntryAdded(summaryEntry);
- mGroupManager.onEntryAdded(childEntry);
- mGroupManager.onEntryAdded(mGroupTestHelper.createChildNotification());
- when(mHeadsUpManager.isAlerting(childEntry.getKey())).thenReturn(true);
-
- mGroupManager.onHeadsUpStateChanged(childEntry, true);
-
- // Child entries that are heads upped should be considered separate groups visually even if
- // they are the same group logically
- assertEquals(childEntry, mGroupManager.getGroupSummary(childEntry));
- assertEquals(summaryEntry, mGroupManager.getLogicalGroupSummary(childEntry));
- }
-
- @Test
- public void testAlertOverrideWithSiblings_0() {
- helpTestAlertOverrideWithSiblings(0);
- }
-
- @Test
- public void testAlertOverrideWithSiblings_1() {
- helpTestAlertOverrideWithSiblings(1);
- }
-
- @Test
- public void testAlertOverrideWithSiblings_2() {
- helpTestAlertOverrideWithSiblings(2);
- }
-
- @Test
- public void testAlertOverrideWithSiblings_3() {
- helpTestAlertOverrideWithSiblings(3);
- }
-
- @Test
- public void testAlertOverrideWithSiblings_9() {
- helpTestAlertOverrideWithSiblings(9);
- }
-
- /**
- * Helper for testing various sibling counts
- */
- private void helpTestAlertOverrideWithSiblings(int numSiblings) {
- helpTestAlertOverride(
- /* numSiblings */ numSiblings,
- /* summaryGroupAlert */ Notification.GROUP_ALERT_SUMMARY,
- /* priorityGroupAlert */ Notification.GROUP_ALERT_SUMMARY,
- /* siblingGroupAlert */ Notification.GROUP_ALERT_SUMMARY,
- /* expectAlertOverride */ true);
- }
-
- @Test
- public void testAlertOverrideWithParentAlertAll() {
- // tests that summary can have GROUP_ALERT_ALL and this still works
- helpTestAlertOverride(
- /* numSiblings */ 1,
- /* summaryGroupAlert */ Notification.GROUP_ALERT_ALL,
- /* priorityGroupAlert */ Notification.GROUP_ALERT_SUMMARY,
- /* siblingGroupAlert */ Notification.GROUP_ALERT_SUMMARY,
- /* expectAlertOverride */ true);
- }
-
- @Test
- public void testAlertOverrideWithParentAlertChild() {
- // Tests that if the summary alerts CHILDREN, there's no alertOverride
- helpTestAlertOverride(
- /* numSiblings */ 1,
- /* summaryGroupAlert */ Notification.GROUP_ALERT_CHILDREN,
- /* priorityGroupAlert */ Notification.GROUP_ALERT_SUMMARY,
- /* siblingGroupAlert */ Notification.GROUP_ALERT_SUMMARY,
- /* expectAlertOverride */ false);
- }
-
- @Test
- public void testAlertOverrideWithChildrenAlertAll() {
- // Tests that if the children alert ALL, there's no alertOverride
- helpTestAlertOverride(
- /* numSiblings */ 1,
- /* summaryGroupAlert */ Notification.GROUP_ALERT_SUMMARY,
- /* priorityGroupAlert */ Notification.GROUP_ALERT_ALL,
- /* siblingGroupAlert */ Notification.GROUP_ALERT_ALL,
- /* expectAlertOverride */ false);
- }
-
- /**
- * This tests, for a group with a priority entry and the given number of siblings, that:
- * 1) the priority entry is identified as the alertOverride for the group
- * 2) the onAlertOverrideChanged method is called at that time
- * 3) when the priority entry is removed, these are reversed
- */
- private void helpTestAlertOverride(int numSiblings,
- @Notification.GroupAlertBehavior int summaryGroupAlert,
- @Notification.GroupAlertBehavior int priorityGroupAlert,
- @Notification.GroupAlertBehavior int siblingGroupAlert,
- boolean expectAlertOverride) {
- long when = 10000;
- // Create entries in an order so that the priority entry can be deemed the newest child.
- NotificationEntry[] siblings = new NotificationEntry[numSiblings];
- for (int i = 0; i < numSiblings; i++) {
- siblings[i] = mGroupTestHelper
- .createChildNotification(siblingGroupAlert, i, "sibling", ++when);
- }
- NotificationEntry priorityEntry =
- mGroupTestHelper.createChildNotification(priorityGroupAlert, 0, "priority", ++when);
- NotificationEntry summaryEntry =
- mGroupTestHelper.createSummaryNotification(summaryGroupAlert, 0, "summary", ++when);
-
- // The priority entry is an important conversation.
- when(mPeopleNotificationIdentifier.getPeopleNotificationType(eq(priorityEntry)))
- .thenReturn(PeopleNotificationIdentifier.TYPE_IMPORTANT_PERSON);
-
- // Register a listener so we can verify that the event is sent.
- OnGroupChangeListener groupChangeListener = mock(OnGroupChangeListener.class);
- mGroupManager.registerGroupChangeListener(groupChangeListener);
-
- // Add all the entries. The order here shouldn't matter.
- mGroupManager.onEntryAdded(summaryEntry);
- for (int i = 0; i < numSiblings; i++) {
- mGroupManager.onEntryAdded(siblings[i]);
- }
- mGroupManager.onEntryAdded(priorityEntry);
-
- if (!expectAlertOverride) {
- // Test expectation is that there will NOT be an alert, so verify that!
- NotificationGroup summaryGroup =
- mGroupManager.getGroupForSummary(summaryEntry.getSbn());
- assertNull(summaryGroup.alertOverride);
- return;
- }
- int max2Siblings = Math.min(2, numSiblings);
-
- // Verify that the summary group has the priority child as its alertOverride
- NotificationGroup summaryGroup = mGroupManager.getGroupForSummary(summaryEntry.getSbn());
- assertEquals(priorityEntry, summaryGroup.alertOverride);
- verify(groupChangeListener).onGroupAlertOverrideChanged(summaryGroup, null, priorityEntry);
- verify(groupChangeListener).onGroupSuppressionChanged(summaryGroup, true);
- if (numSiblings > 1) {
- verify(groupChangeListener).onGroupSuppressionChanged(summaryGroup, false);
- }
- verify(groupChangeListener).onGroupCreated(any(), eq(priorityEntry.getKey()));
- verify(groupChangeListener).onGroupCreated(any(), eq(summaryEntry.getSbn().getGroupKey()));
- verify(groupChangeListener, times(max2Siblings + 1)).onGroupsChanged();
- verifyNoMoreInteractions(groupChangeListener);
-
- // Verify that only the priority notification is isolated from the group
- assertEquals(priorityEntry, mGroupManager.getGroupSummary(priorityEntry));
- assertEquals(summaryEntry, mGroupManager.getLogicalGroupSummary(priorityEntry));
- // Verify that the siblings are NOT isolated from the group
- for (int i = 0; i < numSiblings; i++) {
- assertEquals(summaryEntry, mGroupManager.getGroupSummary(siblings[i]));
- assertEquals(summaryEntry, mGroupManager.getLogicalGroupSummary(siblings[i]));
- }
-
- // Remove the priority notification to validate that it is removed as the alertOverride
- mGroupManager.onEntryRemoved(priorityEntry);
-
- // verify that the alertOverride is removed when the priority notification is
- assertNull(summaryGroup.alertOverride);
- verify(groupChangeListener).onGroupAlertOverrideChanged(summaryGroup, priorityEntry, null);
- verify(groupChangeListener).onGroupRemoved(any(), eq(priorityEntry.getKey()));
- verify(groupChangeListener, times(max2Siblings + 2)).onGroupsChanged();
- if (numSiblings == 0) {
- verify(groupChangeListener).onGroupSuppressionChanged(summaryGroup, false);
- }
- verifyNoMoreInteractions(groupChangeListener);
- }
-
- @Test
- public void testAlertOverrideWhenUpdatingSummaryAtEnd() {
- long when = 10000;
- int numSiblings = 2;
- int groupAlert = Notification.GROUP_ALERT_SUMMARY;
- // Create entries in an order so that the priority entry can be deemed the newest child.
- NotificationEntry[] siblings = new NotificationEntry[numSiblings];
- for (int i = 0; i < numSiblings; i++) {
- siblings[i] =
- mGroupTestHelper.createChildNotification(groupAlert, i, "sibling", ++when);
- }
- NotificationEntry priorityEntry =
- mGroupTestHelper.createChildNotification(groupAlert, 0, "priority", ++when);
- NotificationEntry summaryEntry =
- mGroupTestHelper.createSummaryNotification(groupAlert, 0, "summary", ++when);
-
- // The priority entry is an important conversation.
- when(mPeopleNotificationIdentifier.getPeopleNotificationType(eq(priorityEntry)))
- .thenReturn(PeopleNotificationIdentifier.TYPE_IMPORTANT_PERSON);
-
- // Register a listener so we can verify that the event is sent.
- OnGroupChangeListener groupChangeListener = mock(OnGroupChangeListener.class);
- mGroupManager.registerGroupChangeListener(groupChangeListener);
-
- // Add all the entries. The order here shouldn't matter.
- mGroupManager.onEntryAdded(summaryEntry);
- for (int i = 0; i < numSiblings; i++) {
- mGroupManager.onEntryAdded(siblings[i]);
- }
- mGroupManager.onEntryAdded(priorityEntry);
-
- int max2Siblings = Math.min(2, numSiblings);
-
- // Verify that the summary group has the priority child as its alertOverride
- NotificationGroup summaryGroup = mGroupManager.getGroupForSummary(summaryEntry.getSbn());
- assertEquals(priorityEntry, summaryGroup.alertOverride);
- verify(groupChangeListener).onGroupAlertOverrideChanged(summaryGroup, null, priorityEntry);
- verify(groupChangeListener).onGroupSuppressionChanged(summaryGroup, true);
- if (numSiblings > 1) {
- verify(groupChangeListener).onGroupSuppressionChanged(summaryGroup, false);
- }
- verify(groupChangeListener).onGroupCreated(any(), eq(priorityEntry.getKey()));
- verify(groupChangeListener).onGroupCreated(any(), eq(summaryEntry.getSbn().getGroupKey()));
- verify(groupChangeListener, times(max2Siblings + 1)).onGroupsChanged();
- verifyNoMoreInteractions(groupChangeListener);
-
- // Verify that only the priority notification is isolated from the group
- assertEquals(priorityEntry, mGroupManager.getGroupSummary(priorityEntry));
- assertEquals(summaryEntry, mGroupManager.getLogicalGroupSummary(priorityEntry));
- // Verify that the siblings are NOT isolated from the group
- for (int i = 0; i < numSiblings; i++) {
- assertEquals(summaryEntry, mGroupManager.getGroupSummary(siblings[i]));
- assertEquals(summaryEntry, mGroupManager.getLogicalGroupSummary(siblings[i]));
- }
-
- Log.d("NotificationGroupManagerLegacyTest",
- "testAlertOverrideWhenUpdatingSummaryAtEnd: About to update summary");
-
- StatusBarNotification oldSummarySbn = mGroupTestHelper.incrementPost(summaryEntry, 10000);
- mGroupManager.onEntryUpdated(summaryEntry, oldSummarySbn);
-
- verify(groupChangeListener, times(max2Siblings + 2)).onGroupsChanged();
- verify(groupChangeListener).onGroupAlertOverrideChanged(summaryGroup, priorityEntry, null);
- verifyNoMoreInteractions(groupChangeListener);
-
- Log.d("NotificationGroupManagerLegacyTest",
- "testAlertOverrideWhenUpdatingSummaryAtEnd: About to update priority child");
-
- StatusBarNotification oldPrioritySbn = mGroupTestHelper.incrementPost(priorityEntry, 10000);
- mGroupManager.onEntryUpdated(priorityEntry, oldPrioritySbn);
-
- verify(groupChangeListener).onGroupRemoved(any(), eq(priorityEntry.getKey()));
- verify(groupChangeListener, times(2)).onGroupCreated(any(), eq(priorityEntry.getKey()));
- verify(groupChangeListener, times(2))
- .onGroupAlertOverrideChanged(summaryGroup, null, priorityEntry);
- verify(groupChangeListener, times(max2Siblings + 3)).onGroupsChanged();
- verifyNoMoreInteractions(groupChangeListener);
-
- Log.d("NotificationGroupManagerLegacyTest",
- "testAlertOverrideWhenUpdatingSummaryAtEnd: Done");
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index c896c0ad93e0..de43a1fabab6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -178,10 +178,10 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
bubbleSbn.getNotification().contentIntent = mContentIntent;
bubbleSbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
- ArrayList<NotificationEntry> activeNotifications = new ArrayList<>();
- activeNotifications.add(mNotificationRow.getEntry());
- activeNotifications.add(mBubbleNotificationRow.getEntry());
- when(mEntryManager.getVisibleNotifications()).thenReturn(activeNotifications);
+// ArrayList<NotificationEntry> activeNotifications = new ArrayList<>();
+// activeNotifications.add(mNotificationRow.getEntry());
+// activeNotifications.add(mBubbleNotificationRow.getEntry());
+// when(mEntryManager.getVisibleNotifications()).thenReturn(activeNotifications);
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
when(mOnUserInteractionCallback.registerFutureDismissal(eq(mNotificationRow.getEntry()),
anyInt())).thenReturn(mFutureDismissalRunnable);
@@ -347,9 +347,6 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
// The content intent should NOT be sent on click.
verifyZeroInteractions(mContentIntent);
-
- // Notification should not be cancelled.
- verify(mEntryManager, never()).performRemoveNotification(eq(sbn), any(), anyInt());
}
@Test
@@ -380,9 +377,6 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
verify(mContentIntent).getIntent();
verify(mContentIntent).isActivity();
verifyNoMoreInteractions(mContentIntent);
-
- // Notification should not be cancelled.
- verify(mEntryManager, never()).performRemoveNotification(eq(sbn), any(), anyInt());
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
index 23b14044b3e9..1ec4de9b573e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
@@ -38,7 +38,7 @@ import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
+import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -79,7 +79,7 @@ public class StatusBarRemoteInputCallbackTest extends SysuiTestCase {
mNotificationLockscreenUserManager);
mRemoteInputCallback = spy(new StatusBarRemoteInputCallback(mContext,
- mock(NotificationGroupManagerLegacy.class), mNotificationLockscreenUserManager,
+ mock(GroupExpansionManager.class), mNotificationLockscreenUserManager,
mKeyguardStateController, mStatusBarStateController, mStatusBarKeyguardViewManager,
mActivityStarter, mShadeController, new CommandQueue(mContext),
mock(ActionClickLogger.class), mFakeExecutor));