diff options
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, |