summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/Dependency.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinder.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java67
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LowPriorityInflationHelper.java49
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java950
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/legacy/GroupEventDispatcherTest.kt294
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java13
9 files changed, 9 insertions, 1411 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 614a87fc758c..6835267e52aa 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.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.GroupMembershipManager;
@@ -311,7 +310,6 @@ public class Dependency {
@Inject Lazy<AccessibilityFloatingMenuController> mAccessibilityFloatingMenuController;
@Inject Lazy<StatusBarStateController> mStatusBarStateController;
@Inject Lazy<NotificationLockscreenUserManager> mNotificationLockscreenUserManager;
- @Inject Lazy<NotificationGroupManagerLegacy> mNotificationGroupManager;
@Inject Lazy<VisualStabilityManager> mVisualStabilityManager;
@Inject Lazy<NotificationGutsManager> mNotificationGutsManager;
@Inject Lazy<NotificationMediaManager> mNotificationMediaManager;
@@ -524,7 +522,6 @@ public class Dependency {
mProviders.put(NotificationLockscreenUserManager.class,
mNotificationLockscreenUserManager::get);
mProviders.put(VisualStabilityManager.class, mVisualStabilityManager::get);
- mProviders.put(NotificationGroupManagerLegacy.class, mNotificationGroupManager::get);
mProviders.put(NotificationMediaManager.class, mNotificationMediaManager::get);
mProviders.put(NotificationGutsManager.class, mNotificationGutsManager::get);
mProviders.put(NotificationRemoteInputManager.class,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinder.java
index 46b467e8962d..d52f3c692b83 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinder.java
@@ -16,9 +16,8 @@
package com.android.systemui.statusbar.notification.collection.inflation;
-import android.annotation.Nullable;
+import android.annotation.NonNull;
-import com.android.systemui.statusbar.NotificationUiAdjustment;
import com.android.systemui.statusbar.notification.InflationException;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -35,23 +34,11 @@ public interface NotificationRowBinder {
*/
void inflateViews(
NotificationEntry entry,
- NotifInflater.Params params,
+ @NonNull NotifInflater.Params params,
NotificationRowContentBinder.InflationCallback callback)
throws InflationException;
/**
- * Called when the ranking has been updated (but not add or remove has been done). The binder
- * should inspect the old and new adjustments and re-inflate the entry's views if necessary
- * (e.g. if something important changed).
- */
- void onNotificationRankingUpdated(
- NotificationEntry entry,
- @Nullable Integer oldImportance,
- NotificationUiAdjustment oldAdjustment,
- NotificationUiAdjustment newAdjustment,
- NotificationRowContentBinder.InflationCallback callback);
-
- /**
* Called when a notification is no longer likely to be displayed and can have its views freed.
*/
void releaseViews(NotificationEntry entry);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
index 528f7203347f..47cdde444dbd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
@@ -22,6 +22,7 @@ import static com.android.systemui.statusbar.notification.row.NotificationRowCon
import static java.util.Objects.requireNonNull;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.os.Build;
@@ -32,12 +33,9 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
-import com.android.systemui.statusbar.NotificationUiAdjustment;
import com.android.systemui.statusbar.notification.InflationException;
-import com.android.systemui.statusbar.notification.NotifPipelineFlags;
import com.android.systemui.statusbar.notification.NotificationClicker;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.legacy.LowPriorityInflationHelper;
import com.android.systemui.statusbar.notification.icon.IconManager;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController;
@@ -68,8 +66,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
private final ExpandableNotificationRowComponent.Builder
mExpandableNotificationRowComponentBuilder;
private final IconManager mIconManager;
- private final LowPriorityInflationHelper mLowPriorityInflationHelper;
- private final NotifPipelineFlags mNotifPipelineFlags;
private NotificationPresenter mPresenter;
private NotificationListContainer mListContainer;
@@ -86,9 +82,7 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
RowContentBindStage rowContentBindStage,
Provider<RowInflaterTask> rowInflaterTaskProvider,
ExpandableNotificationRowComponent.Builder expandableNotificationRowComponentBuilder,
- IconManager iconManager,
- LowPriorityInflationHelper lowPriorityInflationHelper,
- NotifPipelineFlags notifPipelineFlags) {
+ IconManager iconManager) {
mContext = context;
mNotifBindPipeline = notifBindPipeline;
mRowContentBindStage = rowContentBindStage;
@@ -98,8 +92,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
mRowInflaterTaskProvider = rowInflaterTaskProvider;
mExpandableNotificationRowComponentBuilder = expandableNotificationRowComponentBuilder;
mIconManager = iconManager;
- mLowPriorityInflationHelper = lowPriorityInflationHelper;
- mNotifPipelineFlags = notifPipelineFlags;
}
/**
@@ -125,13 +117,9 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
@Override
public void inflateViews(
NotificationEntry entry,
- NotifInflater.Params params,
+ @NonNull NotifInflater.Params params,
NotificationRowContentBinder.InflationCallback callback)
throws InflationException {
- if (params == null) {
- // weak assert that the params should always be passed in the new pipeline
- mNotifPipelineFlags.checkLegacyPipelineEnabled();
- }
ViewGroup parent = mListContainer.getViewParentForNotification(entry);
if (entry.rowExists()) {
@@ -191,39 +179,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
}
/**
- * Updates the views bound to an entry when the entry's ranking changes, either in-place or by
- * reinflating them.
- *
- * TODO: Should this method be in this class?
- */
- @Override
- public void onNotificationRankingUpdated(
- NotificationEntry entry,
- @Nullable Integer oldImportance,
- NotificationUiAdjustment oldAdjustment,
- NotificationUiAdjustment newAdjustment,
- NotificationRowContentBinder.InflationCallback callback) {
- mNotifPipelineFlags.checkLegacyPipelineEnabled();
- if (NotificationUiAdjustment.needReinflate(oldAdjustment, newAdjustment)) {
- if (entry.rowExists()) {
- ExpandableNotificationRow row = entry.getRow();
- row.reset();
- updateRow(entry, row);
- inflateContentViews(entry, null, row, callback);
- } else {
- // Once the RowInflaterTask is done, it will pick up the updated entry, so
- // no-op here.
- }
- } else {
- if (oldImportance != null && entry.getImportance() != oldImportance) {
- if (entry.rowExists()) {
- entry.getRow().onNotificationRankingUpdated();
- }
- }
- }
- }
-
- /**
* Update row after the notification has updated.
*
* @param entry notification that has updated
@@ -243,24 +198,12 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
*/
private void inflateContentViews(
NotificationEntry entry,
- NotifInflater.Params inflaterParams,
+ @NonNull NotifInflater.Params inflaterParams,
ExpandableNotificationRow row,
@Nullable NotificationRowContentBinder.InflationCallback inflationCallback) {
final boolean useIncreasedCollapsedHeight =
mMessagingUtil.isImportantMessaging(entry.getSbn(), entry.getImportance());
- final boolean isLowPriority;
- if (inflaterParams != null) {
- // NEW pipeline
- isLowPriority = inflaterParams.isLowPriority();
- } else {
- // LEGACY pipeline
- mNotifPipelineFlags.checkLegacyPipelineEnabled();
- // If this is our first time inflating, we don't actually know the groupings for real
- // yet, so we might actually inflate a low priority content view incorrectly here and
- // have to correct it later in the pipeline. On subsequent inflations (i.e. updates),
- // this should inflate the correct view.
- isLowPriority = mLowPriorityInflationHelper.shouldUseLowPriorityView(entry);
- }
+ final boolean isLowPriority = inflaterParams.isLowPriority();
RowContentBindParams params = mRowContentBindStage.getStageParams(entry);
params.requireContentViews(FLAG_CONTENT_VIEW_CONTRACTED);
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
deleted file mode 100644
index 89445a5c6467..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LowPriorityInflationHelper.java
+++ /dev/null
@@ -1,49 +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.collection.legacy;
-
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.statusbar.notification.NotifPipelineFlags;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-
-import javax.inject.Inject;
-
-/**
- * Helper class that provide methods to help check when we need to inflate a low priority version
- * ot notification content.
- */
-@SysUISingleton
-public class LowPriorityInflationHelper {
- private final NotificationGroupManagerLegacy mGroupManager;
- private final NotifPipelineFlags mNotifPipelineFlags;
-
- @Inject
- LowPriorityInflationHelper(
- NotificationGroupManagerLegacy groupManager,
- NotifPipelineFlags notifPipelineFlags) {
- mGroupManager = groupManager;
- mNotifPipelineFlags = notifPipelineFlags;
- }
-
- /**
- * Whether the notification should inflate a low priority version of its content views.
- */
- public boolean shouldUseLowPriorityView(NotificationEntry entry) {
- mNotifPipelineFlags.checkLegacyPipelineEnabled();
- return entry.isAmbient() && !mGroupManager.isChildInGroup(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
deleted file mode 100644
index d41f6fe7bdde..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java
+++ /dev/null
@@ -1,950 +0,0 @@
-/*
- * Copyright (C) 2015 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 static com.android.systemui.statusbar.notification.NotificationUtils.logKey;
-
-import static java.util.Objects.requireNonNull;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.Notification;
-import android.service.notification.StatusBarNotification;
-import android.util.ArraySet;
-import android.util.Log;
-
-import com.android.systemui.Dumpable;
-import com.android.systemui.dagger.SysUISingleton;
-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.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager.OnGroupExpansionChangeListener;
-import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
-import com.android.systemui.util.Compile;
-import com.android.wm.shell.bubbles.Bubbles;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.TreeSet;
-import java.util.function.Function;
-
-import javax.inject.Inject;
-
-import dagger.Lazy;
-
-/**
- * A class to handle notifications and their corresponding groups.
- * This includes:
- * 1. Determining whether an entry is a member of a group and whether it is a summary or a child
- * 2. Tracking group expansion states
- */
-@SysUISingleton
-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);
- private static final boolean SPEW = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.VERBOSE);
- /**
- * The maximum amount of time (in ms) between the posting of notifications that can be
- * considered part of the same update batch.
- */
- private static final long POST_BATCH_MAX_AGE = 5000;
- private final HashMap<String, NotificationGroup> mGroupMap = new HashMap<>();
- private final Lazy<PeopleNotificationIdentifier> mPeopleNotificationIdentifier;
- private final Optional<Bubbles> mBubblesOptional;
- private final GroupEventDispatcher mEventDispatcher = new GroupEventDispatcher(mGroupMap::get);
- private final HashMap<String, StatusBarNotification> mIsolatedEntries = new HashMap<>();
- private boolean mIsUpdatingUnchangedGroup;
-
- @Inject
- public NotificationGroupManagerLegacy(
- StatusBarStateController statusBarStateController,
- Lazy<PeopleNotificationIdentifier> peopleNotificationIdentifier,
- Optional<Bubbles> bubblesOptional,
- DumpManager dumpManager) {
- statusBarStateController.addCallback(this);
- mPeopleNotificationIdentifier = peopleNotificationIdentifier;
- mBubblesOptional = bubblesOptional;
-
- dumpManager.registerDumpable(this);
- }
-
- /**
- * Add a listener for changes to groups.
- */
- public void registerGroupChangeListener(OnGroupChangeListener listener) {
- mEventDispatcher.registerGroupChangeListener(listener);
- }
-
- private void setGroupExpanded(NotificationGroup group, boolean expanded) {
- group.expanded = expanded;
- }
-
- /**
- * When we want to remove an entry from being tracked for grouping
- */
- public void onEntryRemoved(NotificationEntry removed) {
- if (SPEW) {
- Log.d(TAG, "onEntryRemoved: entry=" + logKey(removed));
- }
- mEventDispatcher.openBufferScope();
- onEntryRemovedInternal(removed, removed.getSbn());
- StatusBarNotification oldSbn = mIsolatedEntries.remove(removed.getKey());
- if (oldSbn != null) {
- updateSuppression(mGroupMap.get(oldSbn.getGroupKey()));
- }
- mEventDispatcher.closeBufferScope();
- }
-
- /**
- * An entry was removed.
- *
- * @param removed the removed entry
- * @param sbn the notification the entry has, which doesn't need to be the same as it's internal
- * notification
- */
- private void onEntryRemovedInternal(NotificationEntry removed,
- final StatusBarNotification sbn) {
- onEntryRemovedInternal(removed, sbn.getGroupKey(), sbn.isGroup(),
- sbn.getNotification().isGroupSummary());
- }
-
- private void onEntryRemovedInternal(NotificationEntry removed, String notifGroupKey, boolean
- isGroup, boolean isGroupSummary) {
- String groupKey = getGroupKey(removed.getKey(), notifGroupKey);
- final NotificationGroup group = mGroupMap.get(groupKey);
- if (group == null) {
- // When an app posts 2 different notifications as summary of the same group, then a
- // cancellation of the first notification removes this group.
- // This situation is not supported and we will not allow such notifications anymore in
- // the close future. See b/23676310 for reference.
- return;
- }
- if (SPEW) {
- Log.d(TAG, "onEntryRemovedInternal: entry=" + logKey(removed)
- + " group=" + logGroupKey(group));
- }
- if (isGroupChild(removed.getKey(), isGroup, isGroupSummary)) {
- group.children.remove(removed.getKey());
- } else {
- group.summary = null;
- }
- updateSuppression(group);
- if (group.children.isEmpty()) {
- if (group.summary == null) {
- mGroupMap.remove(groupKey);
- mEventDispatcher.notifyGroupRemoved(group);
- }
- }
- }
-
- private void onEntryAddedInternal(final NotificationEntry added) {
- if (added.isRowRemoved()) {
- added.setDebugThrowable(new Throwable());
- }
- final StatusBarNotification sbn = added.getSbn();
- boolean isGroupChild = isGroupChild(sbn);
- String groupKey = getGroupKey(sbn);
- NotificationGroup group = mGroupMap.get(groupKey);
- if (group == null) {
- group = new NotificationGroup(groupKey);
- mGroupMap.put(groupKey, group);
- mEventDispatcher.notifyGroupCreated(group);
- }
- if (SPEW) {
- Log.d(TAG, "onEntryAddedInternal: entry=" + logKey(added)
- + " group=" + logGroupKey(group));
- }
- if (isGroupChild) {
- NotificationEntry existing = group.children.get(added.getKey());
- if (existing != null && existing != added) {
- Throwable existingThrowable = existing.getDebugThrowable();
- Log.wtf(TAG, "Inconsistent entries found with the same key " + logKey(added)
- + "existing removed: " + existing.isRowRemoved()
- + (existingThrowable != null
- ? Log.getStackTraceString(existingThrowable) + "\n" : "")
- + " added removed" + added.isRowRemoved(), new Throwable());
- }
- group.children.put(added.getKey(), added);
- addToPostBatchHistory(group, added);
- updateSuppression(group);
- } else {
- group.summary = added;
- addToPostBatchHistory(group, added);
- group.expanded = added.areChildrenExpanded();
- updateSuppression(group);
- if (!group.children.isEmpty()) {
- ArrayList<NotificationEntry> childrenCopy =
- new ArrayList<>(group.children.values());
- for (NotificationEntry child : childrenCopy) {
- onEntryBecomingChild(child);
- }
- mEventDispatcher.notifyGroupsChanged();
- }
- }
- }
-
- private void addToPostBatchHistory(NotificationGroup group, @Nullable NotificationEntry entry) {
- if (entry == null) {
- return;
- }
- boolean didAdd = group.postBatchHistory.add(new PostRecord(entry));
- if (didAdd) {
- trimPostBatchHistory(group.postBatchHistory);
- }
- }
-
- /** remove all history that's too old to be in the batch. */
- private void trimPostBatchHistory(@NonNull TreeSet<PostRecord> postBatchHistory) {
- if (postBatchHistory.size() <= 1) {
- return;
- }
- long batchStartTime = postBatchHistory.last().postTime - POST_BATCH_MAX_AGE;
- while (!postBatchHistory.isEmpty() && postBatchHistory.first().postTime < batchStartTime) {
- postBatchHistory.pollFirst();
- }
- }
-
- private void onEntryBecomingChild(NotificationEntry entry) {
- updateIsolation(entry);
- }
-
- private void updateSuppression(NotificationGroup group) {
- if (group == null) {
- return;
- }
- NotificationEntry prevAlertOverride = group.alertOverride;
- group.alertOverride = getPriorityConversationAlertOverride(group);
-
- int childCount = 0;
- boolean hasBubbles = false;
- for (NotificationEntry entry : group.children.values()) {
- if (mBubblesOptional.isPresent() && mBubblesOptional.get()
- .isBubbleNotificationSuppressedFromShade(
- entry.getKey(), entry.getSbn().getGroupKey())) {
- hasBubbles = true;
- } else {
- childCount++;
- }
- }
-
- boolean prevSuppressed = group.suppressed;
- group.suppressed = group.summary != null && !group.expanded
- && (childCount == 1
- || (childCount == 0
- && group.summary.getSbn().getNotification().isGroupSummary()
- && (hasIsolatedChildren(group) || hasBubbles)));
-
- boolean alertOverrideChanged = prevAlertOverride != group.alertOverride;
- boolean suppressionChanged = prevSuppressed != group.suppressed;
- if (alertOverrideChanged || suppressionChanged) {
- if (DEBUG) {
- Log.d(TAG, "updateSuppression:"
- + " willNotifyListeners=" + !mIsUpdatingUnchangedGroup
- + " changes for group:\n" + group);
- if (alertOverrideChanged) {
- Log.d(TAG, "updateSuppression: alertOverride was=" + logKey(prevAlertOverride)
- + " now=" + logKey(group.alertOverride));
- }
- if (suppressionChanged) {
- Log.d(TAG, "updateSuppression: suppressed changed to " + group.suppressed);
- }
- }
- if (alertOverrideChanged) {
- mEventDispatcher.notifyAlertOverrideChanged(group, prevAlertOverride);
- }
- if (suppressionChanged) {
- mEventDispatcher.notifySuppressedChanged(group);
- }
- if (!mIsUpdatingUnchangedGroup) {
- mEventDispatcher.notifyGroupsChanged();
- }
- }
- }
-
- /**
- * Finds the isolated logical child of this group which is should be alerted instead.
- *
- * Notifications from priority conversations are isolated from their groups to make them more
- * prominent, however apps may post these with a GroupAlertBehavior that has the group receiving
- * the alert. This would lead to the group alerting even though the conversation that was
- * updated was not actually a part of that group. This method finds the best priority
- * conversation in this situation, if there is one, so they can be set as the alertOverride of
- * the group.
- *
- * @param group the group to check
- * @return the entry which should receive the alert instead of the group, if any.
- */
- @Nullable
- private NotificationEntry getPriorityConversationAlertOverride(NotificationGroup group) {
- // GOAL: if there is a priority child which wouldn't alert based on its groupAlertBehavior,
- // but which should be alerting (because priority conversations are isolated), find it.
- if (group == null || group.summary == null) {
- if (SPEW) {
- Log.d(TAG, "getPriorityConversationAlertOverride: null group or summary"
- + " group=" + logGroupKey(group));
- }
- return null;
- }
- if (isIsolated(group.summary.getKey())) {
- if (SPEW) {
- Log.d(TAG, "getPriorityConversationAlertOverride: isolated group"
- + " group=" + logGroupKey(group));
- }
- return null;
- }
-
- // Precondiions:
- // * Only necessary when all notifications in the group use GROUP_ALERT_SUMMARY
- // * Only necessary when at least one notification in the group is on a priority channel
- if (group.summary.getSbn().getNotification().getGroupAlertBehavior()
- == Notification.GROUP_ALERT_CHILDREN) {
- if (SPEW) {
- Log.d(TAG, "getPriorityConversationAlertOverride: summary == GROUP_ALERT_CHILDREN"
- + " group=" + logGroupKey(group));
- }
- return null;
- }
-
- // Get the important children first, copy the keys for the final importance check,
- // then add the non-isolated children to the map for unified lookup.
- HashMap<String, NotificationEntry> children = getImportantConversations(group);
- if (children == null || children.isEmpty()) {
- if (SPEW) {
- Log.d(TAG, "getPriorityConversationAlertOverride: no important conversations"
- + " group=" + logGroupKey(group));
- }
- return null;
- }
- HashSet<String> importantChildKeys = new HashSet<>(children.keySet());
- children.putAll(group.children);
-
- // Ensure all children have GROUP_ALERT_SUMMARY
- for (NotificationEntry child : children.values()) {
- if (child.getSbn().getNotification().getGroupAlertBehavior()
- != Notification.GROUP_ALERT_SUMMARY) {
- if (SPEW) {
- Log.d(TAG, "getPriorityConversationAlertOverride: child != GROUP_ALERT_SUMMARY"
- + " group=" + logGroupKey(group));
- }
- return null;
- }
- }
-
- // Create a merged post history from all the children
- TreeSet<PostRecord> combinedHistory = new TreeSet<>(group.postBatchHistory);
- for (String importantChildKey : importantChildKeys) {
- NotificationGroup importantChildGroup = mGroupMap.get(importantChildKey);
- combinedHistory.addAll(importantChildGroup.postBatchHistory);
- }
- trimPostBatchHistory(combinedHistory);
-
- // This is a streamlined implementation of the following idea:
- // * From the subset of notifications in the latest 'batch' of updates. A batch is:
- // * Notifs posted less than POST_BATCH_MAX_AGE before the most recently posted.
- // * Only including notifs newer than the second-to-last post of any notification.
- // * Find the newest child in the batch -- the with the largest 'when' value.
- // * If the newest child is a priority conversation, set that as the override.
- HashSet<String> batchKeys = new HashSet<>();
- long newestChildWhen = -1;
- NotificationEntry newestChild = null;
- // Iterate backwards through the post history, tracking the child with the smallest sort key
- for (PostRecord record : combinedHistory.descendingSet()) {
- if (batchKeys.contains(record.key)) {
- // Once you see a notification again, the batch has ended
- break;
- }
- batchKeys.add(record.key);
- NotificationEntry child = children.get(record.key);
- if (child != null) {
- long childWhen = child.getSbn().getNotification().when;
- if (newestChild == null || childWhen > newestChildWhen) {
- newestChildWhen = childWhen;
- newestChild = child;
- }
- }
- }
- if (newestChild != null && importantChildKeys.contains(newestChild.getKey())) {
- if (SPEW) {
- Log.d(TAG, "getPriorityConversationAlertOverride:"
- + " result=" + logKey(newestChild)
- + " group=" + logGroupKey(group));
- }
- return newestChild;
- }
- if (SPEW) {
- Log.d(TAG, "getPriorityConversationAlertOverride:"
- + " result=null newestChild=" + logKey(newestChild)
- + " group=" + logGroupKey(group));
- }
- return null;
- }
-
- private boolean hasIsolatedChildren(NotificationGroup group) {
- return getNumberOfIsolatedChildren(group.summary.getSbn().getGroupKey()) != 0;
- }
-
- private int getNumberOfIsolatedChildren(String groupKey) {
- int count = 0;
- for (StatusBarNotification sbn : mIsolatedEntries.values()) {
- if (sbn.getGroupKey().equals(groupKey) && isIsolated(sbn.getKey())) {
- count++;
- }
- }
- return count;
- }
-
- @Nullable
- private HashMap<String, NotificationEntry> getImportantConversations(NotificationGroup group) {
- String groupKey = group.summary.getSbn().getGroupKey();
- HashMap<String, NotificationEntry> result = null;
- for (StatusBarNotification sbn : mIsolatedEntries.values()) {
- if (sbn.getGroupKey().equals(groupKey)) {
- NotificationEntry entry = mGroupMap.get(sbn.getKey()).summary;
- if (isImportantConversation(entry)) {
- if (result == null) {
- result = new HashMap<>();
- }
- result.put(sbn.getKey(), entry);
- }
- }
- }
- return result;
- }
-
- private void setStatusBarState(int newState) {
- if (newState == StatusBarState.KEYGUARD) {
- 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());
- int size = groupCopy.size();
- for (int i = 0; i < size; i++) {
- NotificationGroup group = groupCopy.get(i);
- if (group.expanded) {
- setGroupExpanded(group, false);
- }
- updateSuppression(group);
- }
- }
-
- public boolean isChildInGroup(NotificationEntry entry) {
- final StatusBarNotification sbn = entry.getSbn();
- if (!isGroupChild(sbn)) {
- return false;
- }
- NotificationGroup group = mGroupMap.get(getGroupKey(sbn));
- if (group == null || group.summary == null || group.suppressed) {
- return false;
- }
- if (group.children.isEmpty()) {
- // If the suppression of a group changes because the last child was removed, this can
- // still be called temporarily because the child hasn't been fully removed yet. Let's
- // make sure we still return false in that case.
- return false;
- }
- return true;
- }
-
- /**
- * If there is a {@link NotificationGroup} associated with the provided entry, this method
- * will update the suppression of that group.
- */
- public void updateSuppression(NotificationEntry entry) {
- NotificationGroup group = mGroupMap.get(getGroupKey(entry.getSbn()));
- if (group != null) {
- updateSuppression(group);
- }
- }
-
- /**
- * Get the group key. May differ from the one in the notification due to the notification
- * being temporarily isolated.
- *
- * @param sbn notification to check
- * @return the key of the notification
- */
- private String getGroupKey(StatusBarNotification sbn) {
- return getGroupKey(sbn.getKey(), sbn.getGroupKey());
- }
-
- private String getGroupKey(String key, String groupKey) {
- if (isIsolated(key)) {
- return key;
- }
- return groupKey;
- }
-
- private boolean isIsolated(String sbnKey) {
- return mIsolatedEntries.containsKey(sbnKey);
- }
-
- /**
- * Whether a notification is visually a group child.
- *
- * @param sbn notification to check
- * @return true if it is visually a group child
- */
- private boolean isGroupChild(StatusBarNotification sbn) {
- return isGroupChild(sbn.getKey(), sbn.isGroup(), sbn.getNotification().isGroupSummary());
- }
-
- private boolean isGroupChild(String key, boolean isGroup, boolean isGroupSummary) {
- if (isIsolated(key)) {
- return false;
- }
- return isGroup && !isGroupSummary;
- }
-
- /**
- * 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
- * is alerting.
- *
- * @param entry the notification to check
- * @return true if the entry should be isolated
- */
- private boolean shouldIsolate(NotificationEntry entry) {
- StatusBarNotification sbn = entry.getSbn();
- if (!sbn.isGroup() || sbn.getNotification().isGroupSummary()) {
- return false;
- }
- if (isImportantConversation(entry)) {
- return true;
- }
- NotificationGroup notificationGroup = mGroupMap.get(sbn.getGroupKey());
- return (sbn.getNotification().fullScreenIntent != null
- || notificationGroup == null
- || !notificationGroup.expanded
- || isGroupNotFullyVisible(notificationGroup));
- }
-
- private boolean isImportantConversation(NotificationEntry entry) {
- int peopleNotificationType =
- mPeopleNotificationIdentifier.get().getPeopleNotificationType(entry);
- return peopleNotificationType == PeopleNotificationIdentifier.TYPE_IMPORTANT_PERSON;
- }
-
- /**
- * Isolate a notification from its group so that it visually shows as its own group.
- *
- * @param entry the notification to isolate
- */
- private void isolateNotification(NotificationEntry entry) {
- if (SPEW) {
- Log.d(TAG, "isolateNotification: entry=" + logKey(entry));
- }
- // We will be isolated now, so lets update the groups
- onEntryRemovedInternal(entry, entry.getSbn());
-
- mIsolatedEntries.put(entry.getKey(), entry.getSbn());
-
- onEntryAddedInternal(entry);
- // We also need to update the suppression of the old group, because this call comes
- // even before the groupManager knows about the notification at all.
- // When the notification gets added afterwards it is already isolated and therefore
- // it doesn't lead to an update.
- updateSuppression(mGroupMap.get(entry.getSbn().getGroupKey()));
- mEventDispatcher.notifyGroupsChanged();
- }
-
- /**
- * Update the isolation of an entry, splitting it from the group.
- */
- 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
- // cause problems because the mIsolatedEntries map is not in its final state, so the event
- // listener may be unable to correctly determine the true state of the group. By delaying
- // the alertOverride change until after the add phase, we can ensure that listeners only
- // have to handle a consistent state.
- mEventDispatcher.openBufferScope();
- boolean isIsolated = isIsolated(entry.getSbn().getKey());
- if (shouldIsolate(entry)) {
- if (!isIsolated) {
- isolateNotification(entry);
- }
- } else if (isIsolated) {
- stopIsolatingNotification(entry);
- }
- mEventDispatcher.closeBufferScope();
- }
-
- /**
- * Stop isolating a notification and re-group it with its original logical group.
- *
- * @param entry the notification to un-isolate
- */
- private void stopIsolatingNotification(NotificationEntry entry) {
- if (SPEW) {
- Log.d(TAG, "stopIsolatingNotification: entry=" + logKey(entry));
- }
- // not isolated anymore, we need to update the groups
- onEntryRemovedInternal(entry, entry.getSbn());
- mIsolatedEntries.remove(entry.getKey());
- onEntryAddedInternal(entry);
- mEventDispatcher.notifyGroupsChanged();
- }
-
- private boolean isGroupNotFullyVisible(NotificationGroup notificationGroup) {
- return notificationGroup.summary == null
- || notificationGroup.summary.isGroupNotFullyVisible();
- }
-
- @Override
- public void dump(PrintWriter pw, String[] args) {
- pw.println("GroupManagerLegacy state:");
- pw.println(" number of groups: " + mGroupMap.size());
- for (Map.Entry<String, NotificationGroup> entry : mGroupMap.entrySet()) {
- pw.println("\n key: " + logKey(entry.getKey())); pw.println(entry.getValue());
- }
- pw.println("\n isolated entries: " + mIsolatedEntries.size());
- for (Map.Entry<String, StatusBarNotification> entry : mIsolatedEntries.entrySet()) {
- pw.print(" "); pw.print(logKey(entry.getKey()));
- pw.print(", "); pw.println(entry.getValue());
- }
- }
-
- @Override
- public void onStateChanged(int newState) {
- setStatusBarState(newState);
- }
-
- /** Get the group key, reformatted for logging, for the (optional) group */
- private static String logGroupKey(NotificationGroup group) {
- if (group == null) {
- return "null";
- }
- return logKey(group.groupKey);
- }
-
- /**
- * A record of a notification being posted, containing the time of the post and the key of the
- * notification entry. These are stored in a TreeSet by the NotificationGroup and used to
- * calculate a batch of notifications.
- */
- public static class PostRecord implements Comparable<PostRecord> {
- public final long postTime;
- public final String key;
-
- /** constructs a record containing the post time and key from the notification entry */
- public PostRecord(@NonNull NotificationEntry entry) {
- this.postTime = entry.getSbn().getPostTime();
- this.key = entry.getKey();
- }
-
- @Override
- public int compareTo(PostRecord o) {
- int postTimeComparison = Long.compare(this.postTime, o.postTime);
- return postTimeComparison == 0
- ? String.CASE_INSENSITIVE_ORDER.compare(this.key, o.key)
- : postTimeComparison;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- PostRecord that = (PostRecord) o;
- return postTime == that.postTime && key.equals(that.key);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(postTime, key);
- }
- }
-
- /**
- * Represents a notification group in the notification shade.
- */
- public static class NotificationGroup {
- public final String groupKey;
- public final HashMap<String, NotificationEntry> children = new HashMap<>();
- public final TreeSet<PostRecord> postBatchHistory = new TreeSet<>();
- public NotificationEntry summary;
- public boolean expanded;
- /**
- * Is this notification group suppressed, i.e its summary is hidden
- */
- public boolean suppressed;
- /**
- * The child (which is isolated from this group) to which the alert should be transferred,
- * due to priority conversations.
- */
- public NotificationEntry alertOverride;
-
- NotificationGroup(String groupKey) {
- this.groupKey = groupKey;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append(" groupKey: ").append(groupKey);
- sb.append("\n summary:");
- appendEntry(sb, summary);
- sb.append("\n children size: ").append(children.size());
- for (NotificationEntry child : children.values()) {
- appendEntry(sb, child);
- }
- sb.append("\n alertOverride:");
- appendEntry(sb, alertOverride);
- sb.append("\n summary suppressed: ").append(suppressed);
- return sb.toString();
- }
-
- private void appendEntry(StringBuilder sb, NotificationEntry entry) {
- sb.append("\n ").append(entry != null ? entry.getSbn() : "null");
- if (entry != null && entry.getDebugThrowable() != null) {
- sb.append(Log.getStackTraceString(entry.getDebugThrowable()));
- }
- }
- }
-
- /**
- * This class is a toggleable buffer for a subset of events of {@link OnGroupChangeListener}.
- * When buffering, instead of notifying the listeners it will set internal state that will allow
- * it to notify listeners of those events later
- */
- static class GroupEventDispatcher {
- private final Function<String, NotificationGroup> mGroupMapGetter;
- private final ArraySet<OnGroupChangeListener> mGroupChangeListeners = new ArraySet<>();
- private final HashMap<String, NotificationEntry> mOldAlertOverrideByGroup = new HashMap<>();
- private final HashMap<String, Boolean> mOldSuppressedByGroup = new HashMap<>();
- private int mBufferScopeDepth = 0;
- private boolean mDidGroupsChange = false;
-
- GroupEventDispatcher(Function<String, NotificationGroup> groupMapGetter) {
- mGroupMapGetter = requireNonNull(groupMapGetter);
- }
-
- void registerGroupChangeListener(OnGroupChangeListener listener) {
- mGroupChangeListeners.add(listener);
- }
-
- private boolean isBuffering() {
- return mBufferScopeDepth > 0;
- }
-
- void notifyAlertOverrideChanged(NotificationGroup group,
- NotificationEntry oldAlertOverride) {
- if (isBuffering()) {
- // The value in this map is the override before the event. If there is an entry
- // already in the map, then we are effectively coalescing two events, which means
- // we need to preserve the original initial value.
- if (!mOldAlertOverrideByGroup.containsKey(group.groupKey)) {
- mOldAlertOverrideByGroup.put(group.groupKey, oldAlertOverride);
- }
- } else {
- for (OnGroupChangeListener listener : mGroupChangeListeners) {
- listener.onGroupAlertOverrideChanged(group, oldAlertOverride,
- group.alertOverride);
- }
- }
- }
-
- void notifySuppressedChanged(NotificationGroup group) {
- if (isBuffering()) {
- // The value in this map is the 'suppressed' before the event. If there is a value
- // already in the map, then we are effectively coalescing two events, which means
- // we need to preserve the original initial value.
- mOldSuppressedByGroup.putIfAbsent(group.groupKey, !group.suppressed);
- } else {
- for (OnGroupChangeListener listener : mGroupChangeListeners) {
- listener.onGroupSuppressionChanged(group, group.suppressed);
- }
- }
- }
-
- void notifyGroupsChanged() {
- if (isBuffering()) {
- mDidGroupsChange = true;
- } else {
- for (OnGroupChangeListener listener : mGroupChangeListeners) {
- listener.onGroupsChanged();
- }
- }
- }
-
- void notifyGroupCreated(NotificationGroup group) {
- // NOTE: given how this event is used, it doesn't need to be buffered right now
- final String groupKey = group.groupKey;
- for (OnGroupChangeListener listener : mGroupChangeListeners) {
- listener.onGroupCreated(group, groupKey);
- }
- }
-
- void notifyGroupRemoved(NotificationGroup group) {
- // NOTE: given how this event is used, it doesn't need to be buffered right now
- final String groupKey = group.groupKey;
- for (OnGroupChangeListener listener : mGroupChangeListeners) {
- listener.onGroupRemoved(group, groupKey);
- }
- }
-
- void openBufferScope() {
- mBufferScopeDepth++;
- if (SPEW) {
- Log.d(TAG, "openBufferScope: scopeDepth=" + mBufferScopeDepth);
- }
- }
-
- void closeBufferScope() {
- mBufferScopeDepth--;
- if (SPEW) {
- Log.d(TAG, "closeBufferScope: scopeDepth=" + mBufferScopeDepth);
- }
- // Flush buffered events if the last buffer scope has closed
- if (!isBuffering()) {
- flushBuffer();
- }
- }
-
- private void flushBuffer() {
- if (SPEW) {
- Log.d(TAG, "flushBuffer: "
- + " suppressed.size=" + mOldSuppressedByGroup.size()
- + " alertOverride.size=" + mOldAlertOverrideByGroup.size()
- + " mDidGroupsChange=" + mDidGroupsChange);
- }
- // alert all group suppressed changes for groups that were not removed
- for (Map.Entry<String, Boolean> entry : mOldSuppressedByGroup.entrySet()) {
- NotificationGroup group = mGroupMapGetter.apply(entry.getKey());
- if (group == null) {
- // The group can be null if this suppressed changed before the group was
- // permanently removed, meaning that there's no guarantee that listeners will
- // that field clear.
- if (SPEW) {
- Log.d(TAG, "flushBuffer: suppressed:"
- + " cannot report for removed group: " + logKey(entry.getKey()));
- }
- continue;
- }
- boolean oldSuppressed = entry.getValue();
- if (group.suppressed == oldSuppressed) {
- // If the final suppressed equals the initial, it means we coalesced two
- // events which undid the change, so we can drop it entirely.
- if (SPEW) {
- Log.d(TAG, "flushBuffer: suppressed:"
- + " did not change for group: " + logKey(entry.getKey()));
- }
- continue;
- }
- notifySuppressedChanged(group);
- }
- mOldSuppressedByGroup.clear();
- // alert all group alert override changes for groups that were not removed
- for (Map.Entry<String, NotificationEntry> entry : mOldAlertOverrideByGroup.entrySet()) {
- NotificationGroup group = mGroupMapGetter.apply(entry.getKey());
- if (group == null) {
- // The group can be null if this alertOverride changed before the group was
- // permanently removed, meaning that there's no guarantee that listeners will
- // that field clear.
- if (SPEW) {
- Log.d(TAG, "flushBuffer: alertOverride:"
- + " cannot report for removed group: " + entry.getKey());
- }
- continue;
- }
- NotificationEntry oldAlertOverride = entry.getValue();
- if (group.alertOverride == oldAlertOverride) {
- // If the final alertOverride equals the initial, it means we coalesced two
- // events which undid the change, so we can drop it entirely.
- if (SPEW) {
- Log.d(TAG, "flushBuffer: alertOverride:"
- + " did not change for group: " + logKey(entry.getKey()));
- }
- continue;
- }
- notifyAlertOverrideChanged(group, oldAlertOverride);
- }
- mOldAlertOverrideByGroup.clear();
- // alert that groups changed
- if (mDidGroupsChange) {
- notifyGroupsChanged();
- mDidGroupsChange = false;
- }
- }
- }
-
- /**
- * Listener for group changes not including group expansion changes which are handled by
- * {@link OnGroupExpansionChangeListener}.
- */
- public interface OnGroupChangeListener {
- /**
- * A new group has been created.
- *
- * @param group the group that was created
- * @param groupKey the group's key
- */
- default void onGroupCreated(
- NotificationGroup group,
- String groupKey) {}
-
- /**
- * A group has been removed.
- *
- * @param group the group that was removed
- * @param groupKey the group's key
- */
- default void onGroupRemoved(
- NotificationGroup group,
- String groupKey) {}
-
- /**
- * The suppression of a group has changed.
- *
- * @param group the group that has changed
- * @param suppressed true if the group is now suppressed, false o/w
- */
- default void onGroupSuppressionChanged(
- NotificationGroup group,
- boolean suppressed) {}
-
- /**
- * The alert override of a group has changed.
- *
- * @param group the group that has changed
- * @param oldAlertOverride the previous notification to which the group's alerts were sent
- * @param newAlertOverride the notification to which the group's alerts should now be sent
- */
- default void onGroupAlertOverrideChanged(
- NotificationGroup group,
- @Nullable NotificationEntry oldAlertOverride,
- @Nullable NotificationEntry newAlertOverride) {}
-
- /**
- * The groups have changed. This can happen if the isolation of a child has changes or if a
- * group became suppressed / unsuppressed
- */
- default void onGroupsChanged() {}
- }
-}
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 eda2eeca0620..7ef4f8b1e730 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
@@ -24,7 +24,6 @@ import android.os.Handler;
import android.view.accessibility.AccessibilityManager;
import com.android.internal.logging.UiEventLogger;
-import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Background;
@@ -37,9 +36,7 @@ import com.android.systemui.settings.UserContextProvider;
import com.android.systemui.shade.NotifPanelEventsModule;
import com.android.systemui.shade.ShadeController;
import com.android.systemui.statusbar.NotificationListener;
-import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.notification.AssistantFeedbackController;
-import com.android.systemui.statusbar.notification.NotifPipelineFlags;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationEntryManagerLogger;
import com.android.systemui.statusbar.notification.collection.NotifInflaterImpl;
@@ -53,7 +50,6 @@ import com.android.systemui.statusbar.notification.collection.inflation.BindEven
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.OnUserInteractionCallbackImpl;
-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.provider.HighPriorityProvider;
@@ -84,7 +80,6 @@ import com.android.systemui.statusbar.notification.stack.NotificationSectionsMan
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.util.leak.LeakDetector;
import com.android.systemui.wmshell.BubblesManager;
import java.util.Optional;
@@ -118,16 +113,8 @@ public interface NotificationsModule {
@SysUISingleton
@Provides
static NotificationEntryManager provideNotificationEntryManager(
- NotificationEntryManagerLogger logger,
- NotificationGroupManagerLegacy groupManager,
- NotifPipelineFlags notifPipelineFlags,
- Lazy<NotificationRemoteInputManager> notificationRemoteInputManagerLazy,
- LeakDetector leakDetector,
- IStatusBarService statusBarService,
- @Background Executor bgExecutor) {
- return new NotificationEntryManager(
- logger
- );
+ NotificationEntryManagerLogger logger) {
+ return new NotificationEntryManager(logger);
}
/** Provides an instance of {@link NotificationGutsManager} */
@@ -141,7 +128,6 @@ public interface NotificationsModule {
AccessibilityManager accessibilityManager,
HighPriorityProvider highPriorityProvider,
INotificationManager notificationManager,
- NotificationEntryManager notificationEntryManager,
PeopleSpaceWidgetManager peopleSpaceWidgetManager,
LauncherApps launcherApps,
ShortcutManager shortcutManager,
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 3f6586c37b5d..e6eceb555897 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
@@ -87,8 +87,6 @@ import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
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.notifcollection.DismissedByUserStats;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
@@ -633,7 +631,6 @@ public class NotificationStackScrollLayoutController {
NotificationSwipeHelper.Builder notificationSwipeHelperBuilder,
CentralSurfaces centralSurfaces,
ScrimController scrimController,
- NotificationGroupManagerLegacy legacyGroupManager,
GroupExpansionManager groupManager,
@SilentHeader SectionHeaderController silentHeaderController,
NotifPipeline notifPipeline,
@@ -677,12 +674,6 @@ public class NotificationStackScrollLayoutController {
mJankMonitor = jankMonitor;
mNotificationStackSizeCalculator = notificationStackSizeCalculator;
mGroupExpansionManager = groupManager;
- legacyGroupManager.registerGroupChangeListener(new OnGroupChangeListener() {
- @Override
- public void onGroupsChanged() {
- mCentralSurfaces.requestNotificationUpdate("onGroupsChanged");
- }
- });
mSilentHeaderController = silentHeaderController;
mNotifPipeline = notifPipeline;
mNotifCollection = notifCollection;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/legacy/GroupEventDispatcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/legacy/GroupEventDispatcherTest.kt
deleted file mode 100644
index c17fe6f8b7e2..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/legacy/GroupEventDispatcherTest.kt
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.statusbar.notification.collection.legacy
-
-import android.testing.AndroidTestingRunner
-import android.testing.TestableLooper.RunWithLooper
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy.GroupEventDispatcher
-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.phone.NotificationGroupTestHelper
-import com.android.systemui.util.mockito.mock
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.verifyNoMoreInteractions
-
-@SmallTest
-@RunWith(AndroidTestingRunner::class)
-@RunWithLooper
-class GroupEventDispatcherTest : SysuiTestCase() {
- val groupMap = mutableMapOf<String, NotificationGroup>()
- val groupTestHelper = NotificationGroupTestHelper(mContext)
-
- private val dispatcher = GroupEventDispatcher(groupMap::get)
- private val listener: OnGroupChangeListener = mock()
-
- @Before
- fun setup() {
- dispatcher.registerGroupChangeListener(listener)
- }
-
- @Test
- fun testOnGroupsChangedUnbuffered() {
- dispatcher.notifyGroupsChanged()
- verify(listener).onGroupsChanged()
- verifyNoMoreInteractions(listener)
- }
-
- @Test
- fun testOnGroupsChangedBuffered() {
- dispatcher.openBufferScope()
- dispatcher.notifyGroupsChanged()
- verifyNoMoreInteractions(listener)
- dispatcher.closeBufferScope()
- verify(listener).onGroupsChanged()
- verifyNoMoreInteractions(listener)
- }
-
- @Test
- fun testOnGroupsChangedDoubleBuffered() {
- dispatcher.openBufferScope()
- dispatcher.notifyGroupsChanged()
- dispatcher.openBufferScope() // open a nested buffer scope
- dispatcher.notifyGroupsChanged()
- dispatcher.closeBufferScope() // should NOT flush events
- dispatcher.notifyGroupsChanged()
- verifyNoMoreInteractions(listener)
- dispatcher.closeBufferScope() // this SHOULD flush events
- verify(listener).onGroupsChanged()
- verifyNoMoreInteractions(listener)
- }
-
- @Test
- fun testOnGroupsChangedBufferCoalesces() {
- dispatcher.openBufferScope()
- dispatcher.notifyGroupsChanged()
- dispatcher.notifyGroupsChanged()
- verifyNoMoreInteractions(listener)
- dispatcher.closeBufferScope()
- verify(listener).onGroupsChanged()
- verifyNoMoreInteractions(listener)
- }
-
- @Test
- fun testOnGroupCreatedIsNeverBuffered() {
- val group = addGroup(1)
-
- dispatcher.openBufferScope()
- dispatcher.notifyGroupCreated(group)
- verify(listener).onGroupCreated(group, group.groupKey)
- verifyNoMoreInteractions(listener)
-
- dispatcher.closeBufferScope()
- verifyNoMoreInteractions(listener)
- }
-
- @Test
- fun testOnGroupRemovedIsNeverBuffered() {
- val group = addGroup(1)
-
- dispatcher.openBufferScope()
- dispatcher.notifyGroupRemoved(group)
- verify(listener).onGroupRemoved(group, group.groupKey)
- verifyNoMoreInteractions(listener)
-
- dispatcher.closeBufferScope()
- verifyNoMoreInteractions(listener)
- }
-
- @Test
- fun testAlertOverrideAddedUnbuffered() {
- val group = addGroup(1)
- val newAlertEntry = groupTestHelper.createChildNotification()
- group.alertOverride = newAlertEntry
- dispatcher.notifyAlertOverrideChanged(group, null)
- verify(listener).onGroupAlertOverrideChanged(group, null, newAlertEntry)
- verifyNoMoreInteractions(listener)
- }
-
- @Test
- fun testAlertOverrideRemovedUnbuffered() {
- val group = addGroup(1)
- val oldAlertEntry = groupTestHelper.createChildNotification()
- dispatcher.notifyAlertOverrideChanged(group, oldAlertEntry)
- verify(listener).onGroupAlertOverrideChanged(group, oldAlertEntry, null)
- verifyNoMoreInteractions(listener)
- }
-
- @Test
- fun testAlertOverrideChangedUnbuffered() {
- val group = addGroup(1)
- val oldAlertEntry = groupTestHelper.createChildNotification()
- val newAlertEntry = groupTestHelper.createChildNotification()
- group.alertOverride = newAlertEntry
- dispatcher.notifyAlertOverrideChanged(group, oldAlertEntry)
- verify(listener).onGroupAlertOverrideChanged(group, oldAlertEntry, newAlertEntry)
- verifyNoMoreInteractions(listener)
- }
-
- @Test
- fun testAlertOverrideChangedBuffered() {
- dispatcher.openBufferScope()
- val group = addGroup(1)
- val oldAlertEntry = groupTestHelper.createChildNotification()
- val newAlertEntry = groupTestHelper.createChildNotification()
- group.alertOverride = newAlertEntry
- dispatcher.notifyAlertOverrideChanged(group, oldAlertEntry)
- verifyNoMoreInteractions(listener)
- dispatcher.closeBufferScope()
- verify(listener).onGroupAlertOverrideChanged(group, oldAlertEntry, newAlertEntry)
- verifyNoMoreInteractions(listener)
- }
-
- @Test
- fun testAlertOverrideIgnoredIfRemoved() {
- dispatcher.openBufferScope()
- val group = addGroup(1)
- val oldAlertEntry = groupTestHelper.createChildNotification()
- val newAlertEntry = groupTestHelper.createChildNotification()
- group.alertOverride = newAlertEntry
- dispatcher.notifyAlertOverrideChanged(group, oldAlertEntry)
- verifyNoMoreInteractions(listener)
- groupMap.clear()
- dispatcher.closeBufferScope()
- verifyNoMoreInteractions(listener)
- }
-
- @Test
- fun testAlertOverrideMultipleChangesBuffered() {
- dispatcher.openBufferScope()
- val group = addGroup(1)
- val oldAlertEntry = groupTestHelper.createChildNotification()
- val newAlertEntry = groupTestHelper.createChildNotification()
- group.alertOverride = null
- dispatcher.notifyAlertOverrideChanged(group, oldAlertEntry)
- group.alertOverride = newAlertEntry
- dispatcher.notifyAlertOverrideChanged(group, null)
- verifyNoMoreInteractions(listener)
- dispatcher.closeBufferScope()
- verify(listener).onGroupAlertOverrideChanged(group, oldAlertEntry, newAlertEntry)
- verifyNoMoreInteractions(listener)
- }
-
- @Test
- fun testAlertOverrideTemporaryValueSwallowed() {
- dispatcher.openBufferScope()
- val group = addGroup(1)
- val stableAlertEntry = groupTestHelper.createChildNotification()
- group.alertOverride = null
- dispatcher.notifyAlertOverrideChanged(group, stableAlertEntry)
- group.alertOverride = stableAlertEntry
- dispatcher.notifyAlertOverrideChanged(group, null)
- verifyNoMoreInteractions(listener)
- dispatcher.closeBufferScope()
- verifyNoMoreInteractions(listener)
- }
-
- @Test
- fun testAlertOverrideTemporaryNullSwallowed() {
- dispatcher.openBufferScope()
- val group = addGroup(1)
- val temporaryAlertEntry = groupTestHelper.createChildNotification()
- group.alertOverride = temporaryAlertEntry
- dispatcher.notifyAlertOverrideChanged(group, null)
- group.alertOverride = null
- dispatcher.notifyAlertOverrideChanged(group, temporaryAlertEntry)
- verifyNoMoreInteractions(listener)
- dispatcher.closeBufferScope()
- verifyNoMoreInteractions(listener)
- }
-
- @Test
- fun testSuppressOnUnbuffered() {
- val group = addGroup(1)
- group.suppressed = true
- dispatcher.notifySuppressedChanged(group)
- verify(listener).onGroupSuppressionChanged(group, true)
- verifyNoMoreInteractions(listener)
- }
-
- @Test
- fun testSuppressOffUnbuffered() {
- val group = addGroup(1)
- group.suppressed = false
- dispatcher.notifySuppressedChanged(group)
- verify(listener).onGroupSuppressionChanged(group, false)
- verifyNoMoreInteractions(listener)
- }
-
- @Test
- fun testSuppressOnBuffered() {
- dispatcher.openBufferScope()
- val group = addGroup(1)
- group.suppressed = false
- dispatcher.notifySuppressedChanged(group)
- verifyNoMoreInteractions(listener)
- dispatcher.closeBufferScope()
- verify(listener).onGroupSuppressionChanged(group, false)
- verifyNoMoreInteractions(listener)
- }
-
- @Test
- fun testSuppressOnIgnoredIfRemoved() {
- dispatcher.openBufferScope()
- val group = addGroup(1)
- group.suppressed = false
- dispatcher.notifySuppressedChanged(group)
- verifyNoMoreInteractions(listener)
- groupMap.clear()
- dispatcher.closeBufferScope()
- verifyNoMoreInteractions(listener)
- }
-
- @Test
- fun testSuppressOnOffBuffered() {
- dispatcher.openBufferScope()
- val group = addGroup(1)
- group.suppressed = true
- dispatcher.notifySuppressedChanged(group)
- group.suppressed = false
- dispatcher.notifySuppressedChanged(group)
- verifyNoMoreInteractions(listener)
- dispatcher.closeBufferScope()
- verifyNoMoreInteractions(listener)
- }
-
- @Test
- fun testSuppressOnOffOnBuffered() {
- dispatcher.openBufferScope()
- val group = addGroup(1)
- group.suppressed = true
- dispatcher.notifySuppressedChanged(group)
- group.suppressed = false
- dispatcher.notifySuppressedChanged(group)
- group.suppressed = true
- dispatcher.notifySuppressedChanged(group)
- verifyNoMoreInteractions(listener)
- dispatcher.closeBufferScope()
- verify(listener).onGroupSuppressionChanged(group, true)
- verifyNoMoreInteractions(listener)
- }
-
- private fun addGroup(id: Int): NotificationGroup {
- val group = NotificationGroup("group:$id")
- groupMap[group.groupKey] = group
- return group
- }
-}
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 1460e048d234..966e233fa410 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
@@ -34,7 +34,6 @@ import static org.mockito.Mockito.when;
import android.content.res.Resources;
import android.metrics.LogMaker;
import android.testing.AndroidTestingRunner;
-import android.view.LayoutInflater;
import androidx.test.filters.SmallTest;
@@ -42,11 +41,9 @@ import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto;
-import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.FalsingCollectorFake;
import com.android.systemui.classifier.FalsingManagerFake;
-import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.media.KeyguardMediaController;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
@@ -61,12 +58,9 @@ import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.RemoteInputController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
-import com.android.systemui.statusbar.notification.NotifPipelineFlags;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
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;
@@ -112,7 +106,6 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
@Mock private KeyguardMediaController mKeyguardMediaController;
@Mock private SysuiStatusBarStateController mSysuiStatusBarStateController;
@Mock private KeyguardBypassController mKeyguardBypassController;
- @Mock private SysuiColorExtractor mColorExtractor;
@Mock private NotificationLockscreenUserManager mNotificationLockscreenUserManager;
@Mock private MetricsLogger mMetricsLogger;
@Mock private DumpManager mDumpManager;
@@ -122,19 +115,14 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
@Mock private NotificationSwipeHelper mNotificationSwipeHelper;
@Mock private CentralSurfaces mCentralSurfaces;
@Mock private ScrimController mScrimController;
- @Mock private NotificationGroupManagerLegacy mGroupManagerLegacy;
@Mock private GroupExpansionManager mGroupExpansionManager;
@Mock private SectionHeaderController mSilentHeaderController;
- @Mock private NotifPipelineFlags mNotifPipelineFlags;
@Mock private NotifPipeline mNotifPipeline;
@Mock private NotifCollection mNotifCollection;
@Mock private NotificationEntryManager mEntryManager;
- @Mock private IStatusBarService mIStatusBarService;
@Mock private UiEventLogger mUiEventLogger;
@Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
- @Mock private LayoutInflater mLayoutInflater;
@Mock private NotificationRemoteInputManager mRemoteInputManager;
- @Mock private VisualStabilityManager mVisualStabilityManager;
@Mock private ShadeController mShadeController;
@Mock private InteractionJankMonitor mJankMonitor;
@Mock private StackStateLogger mStackLogger;
@@ -176,7 +164,6 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
mNotificationSwipeHelperBuilder,
mCentralSurfaces,
mScrimController,
- mGroupManagerLegacy,
mGroupExpansionManager,
mSilentHeaderController,
mNotifPipeline,