diff options
22 files changed, 404 insertions, 261 deletions
diff --git a/core/java/android/service/notification/NotificationStats.java b/core/java/android/service/notification/NotificationStats.java index 8be114ca321e..2cd8b8ba42d9 100644 --- a/core/java/android/service/notification/NotificationStats.java +++ b/core/java/android/service/notification/NotificationStats.java @@ -73,6 +73,11 @@ public final class NotificationStats implements Parcelable { * Notification has been dismissed from the notification shade. */ public static final int DISMISSAL_SHADE = 3; + /** + * Notification has been dismissed as a bubble. + * @hide + */ + public static final int DISMISSAL_BUBBLE = 3; /** @hide */ @IntDef(prefix = { "DISMISS_SENTIMENT_" }, value = { diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index 434bf49ac878..bb572191fe3c 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -25,6 +25,8 @@ import static android.service.notification.NotificationListenerService.REASON_CA import static android.service.notification.NotificationListenerService.REASON_CANCEL_ALL; import static android.service.notification.NotificationListenerService.REASON_CLICK; import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED; +import static android.service.notification.NotificationStats.DISMISSAL_BUBBLE; +import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static android.view.View.INVISIBLE; @@ -100,8 +102,11 @@ 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.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.coordinator.BubbleCoordinator; +import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; +import com.android.systemui.statusbar.notification.logging.NotificationLogger; import com.android.systemui.statusbar.phone.NotificationGroupManager; import com.android.systemui.statusbar.phone.NotificationShadeWindowController; import com.android.systemui.statusbar.phone.ScrimController; @@ -277,7 +282,10 @@ public class BubbleController implements ConfigurationController.ConfigurationLi * This can happen when an app cancels a bubbled notification or when the user dismisses a * bubble. */ - void removeNotification(@NonNull NotificationEntry entry, int reason); + void removeNotification( + @NonNull NotificationEntry entry, + @NonNull DismissedByUserStats stats, + int reason); /** * Called when a bubbled notification has changed whether it should be @@ -543,6 +551,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi } }); + // The new pipeline takes care of this as a NotifDismissInterceptor BubbleCoordinator mNotificationEntryManager.addNotificationRemoveInterceptor( new NotificationRemoveInterceptor() { @Override @@ -551,7 +560,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi NotificationEntry entry, int dismissReason) { final boolean isClearAll = dismissReason == REASON_CANCEL_ALL; - final boolean isUserDimiss = dismissReason == REASON_CANCEL + final boolean isUserDismiss = dismissReason == REASON_CANCEL || dismissReason == REASON_CLICK; final boolean isAppCancel = dismissReason == REASON_APP_CANCEL || dismissReason == REASON_APP_CANCEL_ALL; @@ -562,7 +571,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi // previously been dismissed & entry.isRowDismissed would still be true boolean userRemovedNotif = (entry != null && entry.isRowDismissed() && !isAppCancel) - || isClearAll || isUserDimiss || isSummaryCancel; + || isClearAll || isUserDismiss || isSummaryCancel; if (userRemovedNotif) { return handleDismissalInterception(entry); @@ -591,8 +600,13 @@ public class BubbleController implements ConfigurationController.ConfigurationLi addNotifCallback(new NotifCallback() { @Override - public void removeNotification(NotificationEntry entry, int reason) { - mNotificationEntryManager.performRemoveNotification(entry.getSbn(), reason); + public void removeNotification( + NotificationEntry entry, + DismissedByUserStats dismissedByUserStats, + int reason + ) { + mNotificationEntryManager.performRemoveNotification(entry.getSbn(), + dismissedByUserStats, reason); } @Override @@ -612,7 +626,9 @@ public class BubbleController implements ConfigurationController.ConfigurationLi mNotificationEntryManager.getActiveNotificationUnfiltered( mBubbleData.getSummaryKey(groupKey)); if (summary != null) { - mNotificationEntryManager.performRemoveNotification(summary.getSbn(), + mNotificationEntryManager.performRemoveNotification( + summary.getSbn(), + getDismissedByUserStats(summary, false), UNDEFINED_DISMISS_REASON); } } @@ -634,7 +650,9 @@ public class BubbleController implements ConfigurationController.ConfigurationLi boolean isSummaryThisNotif = summary.getKey().equals(entry.getKey()); if (!isSummaryThisNotif && (summaryChildren == null || summaryChildren.isEmpty())) { - mNotificationEntryManager.performRemoveNotification(summary.getSbn(), + mNotificationEntryManager.performRemoveNotification( + summary.getSbn(), + getDismissedByUserStats(summary, false), UNDEFINED_DISMISS_REASON); } } @@ -1331,7 +1349,10 @@ public class BubbleController implements ConfigurationController.ConfigurationLi // time to actually remove it for (NotifCallback cb : mCallbacks) { if (entry != null) { - cb.removeNotification(entry, REASON_CANCEL); + cb.removeNotification( + entry, + getDismissedByUserStats(entry, true), + REASON_CANCEL); } } } else { @@ -1487,7 +1508,10 @@ public class BubbleController implements ConfigurationController.ConfigurationLi } else { // non-bubbled children can be removed for (NotifCallback cb : mCallbacks) { - cb.removeNotification(child, REASON_GROUP_SUMMARY_CANCELED); + cb.removeNotification( + child, + getDismissedByUserStats(child, true), + REASON_GROUP_SUMMARY_CANCELED); } } } @@ -1502,6 +1526,25 @@ public class BubbleController implements ConfigurationController.ConfigurationLi } /** + * Gets the DismissedByUserStats used by {@link NotificationEntryManager}. + * Will not be necessary when using the new notification pipeline's {@link NotifCollection}. + * Instead, this is taken care of by {@link BubbleCoordinator}. + */ + private DismissedByUserStats getDismissedByUserStats( + NotificationEntry entry, + boolean isVisible) { + return new DismissedByUserStats( + DISMISSAL_BUBBLE, + DISMISS_SENTIMENT_NEUTRAL, + NotificationVisibility.obtain( + entry.getKey(), + entry.getRanking().getRank(), + mNotificationEntryManager.getActiveNotificationsCount(), + isVisible, + NotificationLogger.getNotificationLocation(entry))); + } + + /** * Updates the visibility of the bubbles based on current state. * Does not un-bubble, just hides or un-hides. * Updates stack description for TalkBack focus. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java index aba9e1005559..e1ff872456eb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java @@ -15,7 +15,6 @@ */ package com.android.systemui.statusbar.notification; -import static android.service.notification.NotificationListenerService.REASON_CANCEL; import static android.service.notification.NotificationListenerService.REASON_ERROR; import static com.android.systemui.statusbar.notification.collection.NotifCollection.REASON_UNKNOWN; @@ -24,14 +23,11 @@ import static com.android.systemui.statusbar.notification.row.NotificationRowCon import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Notification; -import android.content.Context; import android.os.RemoteException; -import android.os.ServiceManager; import android.os.SystemClock; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.NotificationListenerService.RankingMap; -import android.service.notification.NotificationStats; import android.service.notification.StatusBarNotification; import android.util.ArrayMap; import android.util.ArraySet; @@ -41,7 +37,6 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.Dumpable; -import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.NotificationLifetimeExtender; import com.android.systemui.statusbar.NotificationListener; @@ -54,11 +49,11 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationRankingManager; import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder; import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; +import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; import com.android.systemui.statusbar.notification.dagger.NotificationsModule; import com.android.systemui.statusbar.notification.logging.NotificationLogger; import com.android.systemui.statusbar.phone.NotificationGroupManager; -import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.util.Assert; import com.android.systemui.util.leak.LeakDetector; @@ -147,8 +142,6 @@ public class NotificationEntryManager implements private final NotificationRankingManager mRankingManager; private final FeatureFlags mFeatureFlags; private final ForegroundServiceDismissalFeatureController mFgsFeatureController; - private final HeadsUpManager mHeadsUpManager; - private final StatusBarStateController mStatusBarStateController; private NotificationPresenter mPresenter; private RankingMap mLatestRankingMap; @@ -213,8 +206,7 @@ public class NotificationEntryManager implements Lazy<NotificationRemoteInputManager> notificationRemoteInputManagerLazy, LeakDetector leakDetector, ForegroundServiceDismissalFeatureController fgsFeatureController, - HeadsUpManager headsUpManager, - StatusBarStateController statusBarStateController + IStatusBarService statusBarService ) { mLogger = logger; mGroupManager = groupManager; @@ -225,11 +217,7 @@ public class NotificationEntryManager implements mRemoteInputManagerLazy = notificationRemoteInputManagerLazy; mLeakDetector = leakDetector; mFgsFeatureController = fgsFeatureController; - mHeadsUpManager = headsUpManager; - mStatusBarStateController = statusBarStateController; - - mStatusBarService = IStatusBarService.Stub.asInterface( - ServiceManager.checkService(Context.STATUS_BAR_SERVICE)); + mStatusBarService = statusBarService; } /** Once called, the NEM will start processing notification events from system server. */ @@ -284,16 +272,23 @@ public class NotificationEntryManager implements } /** - * Requests a notification to be removed. + * User requests a notification to be removed. * * @param n the notification to remove. * @param reason why it is being removed e.g. {@link NotificationListenerService#REASON_CANCEL}, * or 0 if unknown. */ - public void performRemoveNotification(StatusBarNotification n, int reason) { - final NotificationVisibility nv = obtainVisibility(n.getKey()); + public void performRemoveNotification( + StatusBarNotification n, + @NonNull DismissedByUserStats stats, + int reason + ) { removeNotificationInternal( - n.getKey(), null, nv, false /* forceRemove */, true /* removedByUser */, + n.getKey(), + null, + stats.notificationVisibility, + false /* forceRemove */, + stats, reason); } @@ -337,7 +332,11 @@ public class NotificationEntryManager implements */ private void handleInflationException(StatusBarNotification n, Exception e) { removeNotificationInternal( - n.getKey(), null, null, true /* forceRemove */, false /* removedByUser */, + n.getKey(), + null, + null, + true /* forceRemove */, + null /* dismissedByUserStats */, REASON_ERROR); for (NotificationEntryListener listener : mNotificationEntryListeners) { listener.onInflationError(n, e); @@ -435,19 +434,28 @@ public class NotificationEntryManager implements reapplyFilterAndSort("addVisibleNotification"); } - - public void removeNotification(String key, RankingMap ranking, - int reason) { - removeNotificationInternal(key, ranking, obtainVisibility(key), false /* forceRemove */, - false /* removedByUser */, reason); + @VisibleForTesting + protected void removeNotification(String key, RankingMap ranking, int reason) { + removeNotificationInternal( + key, + ranking, + obtainVisibility(key), + false /* forceRemove */, + null /* dismissedByUserStats */, + reason); } + /** + * Internally remove a notification because system server has reported the notification + * should be removed OR the user has manually dismissed the notification + * @param dismissedByUserStats non-null if the user manually dismissed the notification + */ private void removeNotificationInternal( String key, @Nullable RankingMap ranking, @Nullable NotificationVisibility visibility, boolean forceRemove, - boolean removedByUser, + DismissedByUserStats dismissedByUserStats, int reason) { final NotificationEntry entry = getActiveNotificationUnfiltered(key); @@ -512,11 +520,11 @@ public class NotificationEntryManager implements handleGroupSummaryRemoved(key); removeVisibleNotification(key); updateNotifications("removeNotificationInternal"); - removedByUser |= entryDismissed; + final boolean removedByUser = dismissedByUserStats != null; mLogger.logNotifRemoved(entry.getKey(), removedByUser); if (removedByUser && visibility != null) { - sendNotificationRemovalToServer(entry.getKey(), entry.getSbn(), visibility); + sendNotificationRemovalToServer(entry.getSbn(), dismissedByUserStats); } for (NotificationEntryListener listener : mNotificationEntryListeners) { listener.onEntryRemoved(entry, visibility, removedByUser, reason); @@ -534,30 +542,18 @@ public class NotificationEntryManager implements } private void sendNotificationRemovalToServer( - String key, StatusBarNotification notification, - NotificationVisibility nv) { - final String pkg = notification.getPackageName(); - final String tag = notification.getTag(); - final int id = notification.getId(); - final int userId = notification.getUser().getIdentifier(); + DismissedByUserStats dismissedByUserStats) { try { - int dismissalSurface = NotificationStats.DISMISSAL_SHADE; - if (mHeadsUpManager.isAlerting(key)) { - dismissalSurface = NotificationStats.DISMISSAL_PEEK; - } else if (mStatusBarStateController.isDozing()) { - dismissalSurface = NotificationStats.DISMISSAL_AOD; - } - int dismissalSentiment = NotificationStats.DISMISS_SENTIMENT_NEUTRAL; mStatusBarService.onNotificationClear( - pkg, - tag, - id, - userId, + notification.getPackageName(), + notification.getTag(), + notification.getId(), + notification.getUser().getIdentifier(), notification.getKey(), - dismissalSurface, - dismissalSentiment, - nv); + dismissedByUserStats.dismissalSurface, + dismissedByUserStats.dismissalSentiment, + dismissedByUserStats.notificationVisibility); } catch (RemoteException ex) { // system process is dead if we're here. } @@ -641,11 +637,7 @@ public class NotificationEntryManager implements // Construct the expanded view. if (!mFeatureFlags.isNewNotifPipelineRenderingEnabled()) { - mNotificationRowBinderLazy.get() - .inflateViews( - entry, - () -> performRemoveNotification(notification, REASON_CANCEL), - mInflationCallback); + mNotificationRowBinderLazy.get().inflateViews(entry, mInflationCallback); } mPendingNotifications.put(key, entry); @@ -675,7 +667,7 @@ public class NotificationEntryManager implements final String key = notification.getKey(); abortExistingInflation(key, "updateNotification"); - NotificationEntry entry = getActiveNotificationUnfiltered(key); + final NotificationEntry entry = getActiveNotificationUnfiltered(key); if (entry == null) { return; } @@ -701,11 +693,7 @@ public class NotificationEntryManager implements } if (!mFeatureFlags.isNewNotifPipelineRenderingEnabled()) { - mNotificationRowBinderLazy.get() - .inflateViews( - entry, - () -> performRemoveNotification(notification, REASON_CANCEL), - mInflationCallback); + mNotificationRowBinderLazy.get().inflateViews(entry, mInflationCallback); } updateNotifications("updateNotificationInternal"); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java index d081e114855e..aaf5c4d6594b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java @@ -16,17 +16,10 @@ package com.android.systemui.statusbar.notification.collection; -import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL; - -import android.service.notification.NotificationStats; - import com.android.internal.statusbar.IStatusBarService; -import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.statusbar.notification.InflationException; import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater; import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl; -import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats; -import com.android.systemui.statusbar.notification.logging.NotificationLogger; import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager; import com.android.systemui.statusbar.notification.row.NotificationContentInflater; @@ -81,7 +74,6 @@ public class NotifInflaterImpl implements NotifInflater { try { requireBinder().inflateViews( entry, - getDismissCallback(entry), wrapInflationCallback(callback)); } catch (InflationException e) { mNotifErrorManager.setInflationError(entry, e); @@ -93,30 +85,6 @@ public class NotifInflaterImpl implements NotifInflater { entry.abortTask(); } - private Runnable getDismissCallback(NotificationEntry entry) { - return new Runnable() { - @Override - public void run() { - int dismissalSurface = NotificationStats.DISMISSAL_SHADE; - /* - * TODO: determine dismissal surface (ie: shade / headsup / aod) - * see {@link NotificationLogger#logNotificationClear} - */ - mNotifCollection.dismissNotification( - entry, - new DismissedByUserStats( - dismissalSurface, - DISMISS_SENTIMENT_NEUTRAL, - NotificationVisibility.obtain(entry.getKey(), - entry.getRanking().getRank(), - mNotifPipeline.getShadeListCount(), - true, - NotificationLogger.getNotificationLocation(entry)) - )); - } - }; - } - private NotificationContentInflater.InflationCallback wrapInflationCallback( InflationCallback callback) { return new NotificationContentInflater.InflationCallback() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java index 92426e54ec91..08462c183bd9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java @@ -16,10 +16,6 @@ package com.android.systemui.statusbar.notification.collection.coordinator; -import static android.service.notification.NotificationStats.DISMISSAL_OTHER; -import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL; - -import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.bubbles.BubbleController; import com.android.systemui.statusbar.notification.collection.NotifCollection; import com.android.systemui.statusbar.notification.collection.NotifPipeline; @@ -27,7 +23,6 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter; import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifDismissInterceptor; -import com.android.systemui.statusbar.notification.logging.NotificationLogger; import java.util.HashSet; import java.util.Set; @@ -101,7 +96,6 @@ public class BubbleCoordinator implements Coordinator { @Override public boolean shouldInterceptDismissal(NotificationEntry entry) { - // TODO: b/149041810 add support for intercepting app-cancelled bubble notifications // for experimental bubbles if (mBubbleController.handleDismissalInterception(entry)) { mInterceptedDismissalEntries.add(entry.getKey()); @@ -121,17 +115,21 @@ public class BubbleCoordinator implements Coordinator { private final BubbleController.NotifCallback mNotifCallback = new BubbleController.NotifCallback() { @Override - public void removeNotification(NotificationEntry entry, int reason) { + public void removeNotification( + NotificationEntry entry, + DismissedByUserStats dismissedByUserStats, + int reason + ) { if (isInterceptingDismissal(entry)) { mInterceptedDismissalEntries.remove(entry.getKey()); mOnEndDismissInterception.onEndDismissInterception(mDismissInterceptor, entry, - createDismissedByUserStats(entry)); + dismissedByUserStats); } else if (mNotifPipeline.getAllNotifs().contains(entry)) { // Bubbles are hiding the notifications from the shade, but the bubble was // deleted; therefore, the notification should be cancelled as if it were a user // dismissal (this won't re-enter handleInterceptDimissal because Bubbles // will have already marked it as no longer a bubble) - mNotifCollection.dismissNotification(entry, createDismissedByUserStats(entry)); + mNotifCollection.dismissNotification(entry, dismissedByUserStats); } } @@ -149,16 +147,4 @@ public class BubbleCoordinator implements Coordinator { private boolean isInterceptingDismissal(NotificationEntry entry) { return mInterceptedDismissalEntries.contains(entry.getKey()); } - - private DismissedByUserStats createDismissedByUserStats(NotificationEntry entry) { - return new DismissedByUserStats( - DISMISSAL_OTHER, - DISMISS_SENTIMENT_NEUTRAL, - NotificationVisibility.obtain(entry.getKey(), - entry.getRanking().getRank(), - mNotifPipeline.getShadeListCount(), - true, // was visible as a bubble - NotificationLogger.getNotificationLocation(entry)) - ); - } } 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 710b137d2795..1215ade2abb1 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 @@ -38,7 +38,6 @@ public interface NotificationRowBinder { */ void inflateViews( NotificationEntry entry, - Runnable onDismissRunnable, NotificationRowContentBinder.InflationCallback callback) throws InflationException; 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 85a3bc91dc7e..8849824380d3 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 @@ -32,7 +32,6 @@ import com.android.systemui.statusbar.notification.InflationException; import com.android.systemui.statusbar.notification.NotificationClicker; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.icon.IconManager; -import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController; import com.android.systemui.statusbar.notification.row.NotifBindPipeline; @@ -59,7 +58,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { private final NotificationLockscreenUserManager mNotificationLockscreenUserManager; private final NotifBindPipeline mNotifBindPipeline; private final RowContentBindStage mRowContentBindStage; - private final NotificationInterruptStateProvider mNotificationInterruptStateProvider; private final Provider<RowInflaterTask> mRowInflaterTaskProvider; private final ExpandableNotificationRowComponent.Builder mExpandableNotificationRowComponentBuilder; @@ -79,7 +77,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { NotificationLockscreenUserManager notificationLockscreenUserManager, NotifBindPipeline notifBindPipeline, RowContentBindStage rowContentBindStage, - NotificationInterruptStateProvider notificationInterruptionStateProvider, Provider<RowInflaterTask> rowInflaterTaskProvider, ExpandableNotificationRowComponent.Builder expandableNotificationRowComponentBuilder, IconManager iconManager, @@ -90,7 +87,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { mMessagingUtil = notificationMessagingUtil; mNotificationRemoteInputManager = notificationRemoteInputManager; mNotificationLockscreenUserManager = notificationLockscreenUserManager; - mNotificationInterruptStateProvider = notificationInterruptionStateProvider; mRowInflaterTaskProvider = rowInflaterTaskProvider; mExpandableNotificationRowComponentBuilder = expandableNotificationRowComponentBuilder; mIconManager = iconManager; @@ -120,7 +116,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { @Override public void inflateViews( NotificationEntry entry, - Runnable onDismissRunnable, NotificationRowContentBinder.InflationCallback callback) throws InflationException { ViewGroup parent = mListContainer.getViewParentForNotification(entry); @@ -131,7 +126,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { row.reset(); updateRow(entry, row); inflateContentViews(entry, row, callback); - entry.getRowController().setOnDismissRunnable(onDismissRunnable); } else { mIconManager.createIcons(entry); mRowInflaterTaskProvider.get().inflate(mContext, parent, entry, @@ -141,7 +135,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { mExpandableNotificationRowComponentBuilder .expandableNotificationRow(row) .notificationEntry(entry) - .onDismissRunnable(onDismissRunnable) .onExpandClickListener(mPresenter) .build(); ExpandableNotificationRowController rowController = diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnDismissCallbackImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnDismissCallbackImpl.java new file mode 100644 index 000000000000..36adf9b87674 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnDismissCallbackImpl.java @@ -0,0 +1,83 @@ +/* + * 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.inflation; + +import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL; + +import android.service.notification.NotificationListenerService; +import android.service.notification.NotificationStats; + +import com.android.internal.statusbar.NotificationVisibility; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.notification.collection.NotifCollection; +import com.android.systemui.statusbar.notification.collection.NotifPipeline; +import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats; +import com.android.systemui.statusbar.notification.logging.NotificationLogger; +import com.android.systemui.statusbar.notification.row.OnDismissCallback; +import com.android.systemui.statusbar.policy.HeadsUpManager; + +/** + * Callback used when a user: + * 1. Manually dismisses a notification {@see ExpandableNotificationRow}. + * 2. Clicks on a notification with flag {@link android.app.Notification#FLAG_AUTO_CANCEL}. + * {@see StatusBarNotificationActivityStarter} + */ +public class OnDismissCallbackImpl implements OnDismissCallback { + private final NotifPipeline mNotifPipeline; + private final NotifCollection mNotifCollection; + private final HeadsUpManager mHeadsUpManager; + private final StatusBarStateController mStatusBarStateController; + + public OnDismissCallbackImpl( + NotifPipeline notifPipeline, + NotifCollection notifCollection, + HeadsUpManager headsUpManager, + StatusBarStateController statusBarStateController + ) { + mNotifPipeline = notifPipeline; + mNotifCollection = notifCollection; + mHeadsUpManager = headsUpManager; + mStatusBarStateController = statusBarStateController; + } + + @Override + public void onDismiss( + NotificationEntry entry, + @NotificationListenerService.NotificationCancelReason int cancellationReason + ) { + int dismissalSurface = NotificationStats.DISMISSAL_SHADE; + if (mHeadsUpManager.isAlerting(entry.getKey())) { + dismissalSurface = NotificationStats.DISMISSAL_PEEK; + } else if (mStatusBarStateController.isDozing()) { + dismissalSurface = NotificationStats.DISMISSAL_AOD; + } + + mNotifCollection.dismissNotification( + entry, + new DismissedByUserStats( + dismissalSurface, + DISMISS_SENTIMENT_NEUTRAL, + NotificationVisibility.obtain( + entry.getKey(), + entry.getRanking().getRank(), + mNotifPipeline.getShadeListCount(), + true, + NotificationLogger.getNotificationLocation(entry))) + ); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnDismissCallbackImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnDismissCallbackImpl.java new file mode 100644 index 000000000000..94ffa8f8c5ed --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnDismissCallbackImpl.java @@ -0,0 +1,81 @@ +/* + * 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 static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL; + +import android.service.notification.NotificationListenerService; +import android.service.notification.NotificationStats; + +import com.android.internal.statusbar.NotificationVisibility; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.notification.NotificationEntryManager; +import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats; +import com.android.systemui.statusbar.notification.logging.NotificationLogger; +import com.android.systemui.statusbar.notification.row.OnDismissCallback; +import com.android.systemui.statusbar.policy.HeadsUpManager; + +/** + * Callback used when a user: + * 1. Manually dismisses a notification {@see ExpandableNotificationRow}. + * 2. Clicks on a notification with flag {@link android.app.Notification#FLAG_AUTO_CANCEL}. + * {@see StatusBarNotificationActivityStarter} + */ +public class OnDismissCallbackImpl implements OnDismissCallback { + private final NotificationEntryManager mNotificationEntryManager; + private final HeadsUpManager mHeadsUpManager; + private final StatusBarStateController mStatusBarStateController; + + public OnDismissCallbackImpl( + NotificationEntryManager notificationEntryManager, + HeadsUpManager headsUpManager, + StatusBarStateController statusBarStateController + ) { + mNotificationEntryManager = notificationEntryManager; + mHeadsUpManager = headsUpManager; + mStatusBarStateController = statusBarStateController; + } + + @Override + public void onDismiss( + NotificationEntry entry, + @NotificationListenerService.NotificationCancelReason int cancellationReason + ) { + int dismissalSurface = NotificationStats.DISMISSAL_SHADE; + if (mHeadsUpManager.isAlerting(entry.getKey())) { + dismissalSurface = NotificationStats.DISMISSAL_PEEK; + } else if (mStatusBarStateController.isDozing()) { + dismissalSurface = NotificationStats.DISMISSAL_AOD; + } + + mNotificationEntryManager.performRemoveNotification( + entry.getSbn(), + new DismissedByUserStats( + dismissalSurface, + DISMISS_SENTIMENT_NEUTRAL, + NotificationVisibility.obtain( + entry.getKey(), + entry.getRanking().getRank(), + mNotificationEntryManager.getActiveNotificationsCount(), + true, + NotificationLogger.getNotificationLocation(entry))), + cancellationReason + ); + } +} + 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 ee471c38315e..046dc3c8dce6 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 @@ -25,6 +25,7 @@ import android.view.accessibility.AccessibilityManager; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; +import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.R; import com.android.systemui.bubbles.BubbleController; import com.android.systemui.dagger.qualifiers.Background; @@ -40,11 +41,13 @@ import com.android.systemui.statusbar.notification.ForegroundServiceDismissalFea import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationEntryManagerLogger; import com.android.systemui.statusbar.notification.VisualStabilityManager; +import com.android.systemui.statusbar.notification.collection.NotifCollection; import com.android.systemui.statusbar.notification.collection.NotifInflaterImpl; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotificationRankingManager; import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater; import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder; +import com.android.systemui.statusbar.notification.collection.inflation.OnDismissCallbackImpl; import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider; import com.android.systemui.statusbar.notification.init.NotificationsController; @@ -58,6 +61,7 @@ import com.android.systemui.statusbar.notification.logging.NotificationPanelLogg import com.android.systemui.statusbar.notification.row.ChannelEditorDialogController; import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager; import com.android.systemui.statusbar.notification.row.NotificationGutsManager; +import com.android.systemui.statusbar.notification.row.OnDismissCallback; import com.android.systemui.statusbar.notification.row.PriorityOnboardingDialogController; import com.android.systemui.statusbar.phone.NotificationGroupManager; import com.android.systemui.statusbar.phone.StatusBar; @@ -92,8 +96,7 @@ public interface NotificationsModule { Lazy<NotificationRemoteInputManager> notificationRemoteInputManagerLazy, LeakDetector leakDetector, ForegroundServiceDismissalFeatureController fgsFeatureController, - HeadsUpManager headsUpManager, - StatusBarStateController statusBarStateController) { + IStatusBarService statusBarService) { return new NotificationEntryManager( logger, groupManager, @@ -104,8 +107,7 @@ public interface NotificationsModule { notificationRemoteInputManagerLazy, leakDetector, fgsFeatureController, - headsUpManager, - statusBarStateController); + statusBarService); } /** Provides an instance of {@link NotificationGutsManager} */ @@ -219,6 +221,28 @@ public interface NotificationsModule { return featureFlags.isNewNotifPipelineRenderingEnabled() ? pipeline.get() : entryManager; } + /** + * Provide a dismissal callback that's triggered when a user manually dismissed a notification + * from the notification shade or it gets auto-cancelled by click. + */ + @Provides + @Singleton + static OnDismissCallback provideOnDismissCallback( + FeatureFlags featureFlags, + HeadsUpManager headsUpManager, + StatusBarStateController statusBarStateController, + Lazy<NotifPipeline> pipeline, + Lazy<NotifCollection> notifCollection, + NotificationEntryManager entryManager) { + return featureFlags.isNewNotifPipelineRenderingEnabled() + ? new OnDismissCallbackImpl( + pipeline.get(), notifCollection.get(), headsUpManager, + statusBarStateController) + : new com.android.systemui.statusbar.notification.collection + .legacy.OnDismissCallbackImpl( + entryManager, headsUpManager, statusBarStateController); + } + /** */ @Binds NotificationInterruptStateProvider bindNotificationInterruptStateProvider( diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index 75857401ecb7..22d0357b14c2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.notification.row; +import static android.service.notification.NotificationListenerService.REASON_CANCEL; + import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters; import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_HEADSUP; import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC; @@ -321,7 +323,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView private View mGroupParentWhenDismissed; private boolean mShelfIconVisible; private boolean mAboveShelf; - private Runnable mOnDismissRunnable; + private OnDismissCallback mOnDismissCallback; private boolean mIsLowPriority; private boolean mIsColorized; private boolean mUseIncreasedCollapsedHeight; @@ -1444,10 +1446,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } dismiss(fromAccessibility); if (mEntry.isClearable()) { - // TODO: beverlyt, log dismissal - // TODO: track dismiss sentiment - if (mOnDismissRunnable != null) { - mOnDismissRunnable.run(); + if (mOnDismissCallback != null) { + mOnDismissCallback.onDismiss(mEntry, REASON_CANCEL); } } } @@ -1464,8 +1464,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return mIsBlockingHelperShowing && mNotificationTranslationFinished; } - void setOnDismissRunnable(Runnable onDismissRunnable) { - mOnDismissRunnable = onDismissRunnable; + void setOnDismissCallback(OnDismissCallback onDismissCallback) { + mOnDismissCallback = onDismissCallback; } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java index c9839355b9ba..86a3271c4eac 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java @@ -30,7 +30,6 @@ import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.notification.logging.NotificationLogger; import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier; import com.android.systemui.statusbar.notification.row.dagger.AppName; -import com.android.systemui.statusbar.notification.row.dagger.DismissRunnable; import com.android.systemui.statusbar.notification.row.dagger.NotificationKey; import com.android.systemui.statusbar.notification.row.dagger.NotificationRowScope; import com.android.systemui.statusbar.phone.KeyguardBypassController; @@ -66,7 +65,7 @@ public class ExpandableNotificationRowController { private final ExpandableNotificationRow.CoordinateOnClickListener mOnAppOpsClickListener; private final ExpandableNotificationRow.CoordinateOnClickListener mOnFeedbackClickListener; private final NotificationGutsManager mNotificationGutsManager; - private Runnable mOnDismissRunnable; + private final OnDismissCallback mOnDismissCallback; private final FalsingManager mFalsingManager; private final boolean mAllowLongPress; private final PeopleNotificationIdentifier mPeopleNotificationIdentifier; @@ -84,7 +83,7 @@ public class ExpandableNotificationRowController { StatusBarStateController statusBarStateController, NotificationGutsManager notificationGutsManager, @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowLongPress, - @DismissRunnable Runnable onDismissRunnable, FalsingManager falsingManager, + OnDismissCallback onDismissCallback, FalsingManager falsingManager, PeopleNotificationIdentifier peopleNotificationIdentifier) { mView = view; mActivatableNotificationViewController = activatableNotificationViewController; @@ -101,7 +100,7 @@ public class ExpandableNotificationRowController { mOnExpandClickListener = onExpandClickListener; mStatusBarStateController = statusBarStateController; mNotificationGutsManager = notificationGutsManager; - mOnDismissRunnable = onDismissRunnable; + mOnDismissCallback = onDismissCallback; mOnAppOpsClickListener = mNotificationGutsManager::openGuts; mOnFeedbackClickListener = mNotificationGutsManager::openGuts; mAllowLongPress = allowLongPress; @@ -130,7 +129,7 @@ public class ExpandableNotificationRowController { mStatusBarStateController, mPeopleNotificationIdentifier ); - mView.setOnDismissRunnable(mOnDismissRunnable); + mView.setOnDismissCallback(mOnDismissCallback); mView.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); if (mAllowLongPress) { mView.setLongPressListener((v, x, y, item) -> { @@ -163,10 +162,4 @@ public class ExpandableNotificationRowController { private void logNotificationExpansion(String key, boolean userAction, boolean expanded) { mNotificationLogger.onExpansionChanged(key, userAction, expanded); } - - /** */ - public void setOnDismissRunnable(Runnable onDismissRunnable) { - mOnDismissRunnable = onDismissRunnable; - mView.setOnDismissRunnable(onDismissRunnable); - } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/DismissRunnable.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/OnDismissCallback.java index 433114224289..f1aed899e060 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/DismissRunnable.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/OnDismissCallback.java @@ -14,17 +14,22 @@ * limitations under the License. */ -package com.android.systemui.statusbar.notification.row.dagger; +package com.android.systemui.statusbar.notification.row; -import static java.lang.annotation.RetentionPolicy.RUNTIME; +import android.service.notification.NotificationListenerService; -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; +import com.android.systemui.statusbar.notification.collection.NotificationEntry; -import javax.inject.Qualifier; +/** + * Callback when a user clicks on an auto-cancelled notification or manually swipes to dismiss the + * notification. + */ +public interface OnDismissCallback { -@Qualifier -@Documented -@Retention(RUNTIME) -public @interface DismissRunnable { + /** + * Handle a user interaction that triggers a notification dismissal. + */ + void onDismiss( + NotificationEntry entry, + @NotificationListenerService.NotificationCancelReason int cancellationReason); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java index 321656df504a..28ddf5971bcb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java @@ -54,8 +54,6 @@ public interface ExpandableNotificationRowComponent { @BindsInstance Builder notificationEntry(NotificationEntry entry); @BindsInstance - Builder onDismissRunnable(@DismissRunnable Runnable runnable); - @BindsInstance Builder onExpandClickListener(ExpandableNotificationRow.OnExpandClickListener presenter); ExpandableNotificationRowComponent build(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 9caf0f7dfa4c..66a541a923a4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -11,7 +11,7 @@ * 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 + * limitations under the License. */ package com.android.systemui.statusbar.notification.stack; @@ -6581,40 +6581,25 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd } else { final List<Pair<NotificationEntry, DismissedByUserStats>> entriesWithRowsDismissedFromShade = new ArrayList<>(); - final List<DismissedByUserStats> dismissalUserStats = new ArrayList<>(); final int numVisibleEntries = mNotifPipeline.getShadeListCount(); for (int i = 0; i < viewsToRemove.size(); i++) { final NotificationEntry entry = viewsToRemove.get(i).getEntry(); - final DismissedByUserStats stats = - new DismissedByUserStats( - DISMISSAL_SHADE, - DISMISS_SENTIMENT_NEUTRAL, - NotificationVisibility.obtain( - entry.getKey(), - entry.getRanking().getRank(), - numVisibleEntries, - true, - NotificationLogger.getNotificationLocation(entry))); entriesWithRowsDismissedFromShade.add( - new Pair<NotificationEntry, DismissedByUserStats>(entry, stats)); + new Pair<NotificationEntry, DismissedByUserStats>( + entry, + getDismissedByUserStats(entry, numVisibleEntries))); } mNotifCollection.dismissNotifications(entriesWithRowsDismissedFromShade); } } else { for (ExpandableNotificationRow rowToRemove : viewsToRemove) { if (canChildBeDismissed(rowToRemove)) { - if (selectedRows == ROWS_ALL) { - // TODO: This is a listener method; we shouldn't be calling it. Can we just - // call performRemoveNotification as below? - mEntryManager.removeNotification( - rowToRemove.getEntry().getKey(), - null /* ranking */, - NotificationListenerService.REASON_CANCEL_ALL); - } else { - mEntryManager.performRemoveNotification( - rowToRemove.getEntry().getSbn(), - NotificationListenerService.REASON_CANCEL_ALL); - } + mEntryManager.performRemoveNotification( + rowToRemove.getEntry().getSbn(), + getDismissedByUserStats( + rowToRemove.getEntry(), + mEntryManager.getActiveNotificationsCount()), + NotificationListenerService.REASON_CANCEL_ALL); } else { rowToRemove.resetTranslation(); } @@ -6628,6 +6613,21 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd } } + private DismissedByUserStats getDismissedByUserStats( + NotificationEntry entry, + int numVisibleEntries + ) { + return new DismissedByUserStats( + DISMISSAL_SHADE, + DISMISS_SENTIMENT_NEUTRAL, + NotificationVisibility.obtain( + entry.getKey(), + entry.getRanking().getRank(), + numVisibleEntries, + true, + NotificationLogger.getNotificationLocation(entry))); + } + // ---------------------- DragDownHelper.OnDragDownListener ------------------------------------ @ShadeViewRefactor(RefactorComponent.INPUT) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java index 7bcfb466d7d9..4de648402464 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java @@ -17,7 +17,6 @@ package com.android.systemui.statusbar.phone; import static android.service.notification.NotificationListenerService.REASON_CLICK; -import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL; import static com.android.systemui.statusbar.phone.StatusBar.getActivityOptions; @@ -37,7 +36,6 @@ import android.os.RemoteException; import android.os.UserHandle; import android.provider.Settings; import android.service.dreams.IDreamManager; -import android.service.notification.NotificationStats; import android.service.notification.StatusBarNotification; import android.text.TextUtils; import android.util.EventLog; @@ -71,11 +69,11 @@ 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.NotificationEntry; -import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; import com.android.systemui.statusbar.notification.logging.NotificationLogger; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; +import com.android.systemui.statusbar.notification.row.OnDismissCallback; import com.android.systemui.statusbar.policy.HeadsUpUtil; import com.android.systemui.statusbar.policy.KeyguardStateController; @@ -128,6 +126,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit private final NotificationPresenter mPresenter; private final NotificationPanelViewController mNotificationPanel; private final ActivityLaunchAnimator mActivityLaunchAnimator; + private final OnDismissCallback mOnDismissCallback; private boolean mIsCollapsingToShowActivityOverLockscreen; @@ -162,6 +161,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit FeatureFlags featureFlags, MetricsLogger metricsLogger, StatusBarNotificationActivityStarterLogger logger, + OnDismissCallback onDismissCallback, StatusBar statusBar, NotificationPresenter presenter, @@ -197,6 +197,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit mFeatureFlags = featureFlags; mMetricsLogger = metricsLogger; mLogger = logger; + mOnDismissCallback = onDismissCallback; // TODO: use KeyguardStateController#isOccluded to remove this dependency mStatusBar = statusBar; @@ -574,13 +575,14 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit private void removeNotification(NotificationEntry entry) { // We have to post it to the UI thread for synchronization mMainThreadHandler.post(() -> { - Runnable removeRunnable = createRemoveRunnable(entry); if (mPresenter.isCollapsing()) { // To avoid lags we're only performing the remove // after the shade was collapsed - mShadeController.addPostCollapseAction(removeRunnable); + mShadeController.addPostCollapseAction( + () -> mOnDismissCallback.onDismiss(entry, REASON_CLICK) + ); } else { - removeRunnable.run(); + mOnDismissCallback.onDismiss(entry, REASON_CLICK); } }); } @@ -595,43 +597,6 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit } } - private Runnable createRemoveRunnable(NotificationEntry entry) { - if (mFeatureFlags.isNewNotifPipelineRenderingEnabled()) { - return new Runnable() { - @Override - public void run() { - // see NotificationLogger#logNotificationClear - int dismissalSurface = NotificationStats.DISMISSAL_SHADE; - if (mHeadsUpManager.isAlerting(entry.getKey())) { - dismissalSurface = NotificationStats.DISMISSAL_PEEK; - } else if (mNotificationPanel.hasPulsingNotifications()) { - dismissalSurface = NotificationStats.DISMISSAL_AOD; - } - - mNotifCollection.dismissNotification( - entry, - new DismissedByUserStats( - dismissalSurface, - DISMISS_SENTIMENT_NEUTRAL, - NotificationVisibility.obtain( - entry.getKey(), - entry.getRanking().getRank(), - mNotifPipeline.getShadeListCount(), - true, - NotificationLogger.getNotificationLocation(entry)) - )); - } - }; - } else { - return new Runnable() { - @Override - public void run() { - mEntryManager.performRemoveNotification(entry.getSbn(), REASON_CLICK); - } - }; - } - } - /** * Public builder for {@link StatusBarNotificationActivityStarter}. */ @@ -667,6 +632,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit private final FeatureFlags mFeatureFlags; private final MetricsLogger mMetricsLogger; private final StatusBarNotificationActivityStarterLogger mLogger; + private final OnDismissCallback mOnDismissCallback; private StatusBar mStatusBar; private NotificationPresenter mNotificationPresenter; @@ -704,7 +670,8 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit FeatureFlags featureFlags, MetricsLogger metricsLogger, - StatusBarNotificationActivityStarterLogger logger) { + StatusBarNotificationActivityStarterLogger logger, + OnDismissCallback onDismissCallback) { mContext = context; mCommandQueue = commandQueue; @@ -736,6 +703,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit mFeatureFlags = featureFlags; mMetricsLogger = metricsLogger; mLogger = logger; + mOnDismissCallback = onDismissCallback; } /** Sets the status bar to use as {@link StatusBar}. */ @@ -793,6 +761,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit mFeatureFlags, mMetricsLogger, mLogger, + mOnDismissCallback, mStatusBar, mNotificationPresenter, diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java index 15828b41cc7c..b7589534a770 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java @@ -321,7 +321,7 @@ public class BubbleControllerTest extends SysuiTestCase { Bubble b = mBubbleData.getOverflowBubbleWithKey(mRow.getEntry().getKey()); assertThat(mBubbleData.getOverflowBubbles()).isEqualTo(ImmutableList.of(b)); verify(mNotificationEntryManager, never()).performRemoveNotification( - eq(mRow.getEntry().getSbn()), anyInt()); + eq(mRow.getEntry().getSbn()), any(), anyInt()); assertThat(mRow.getEntry().isBubble()).isFalse(); Bubble b2 = mBubbleData.getBubbleInStackWithKey(mRow2.getEntry().getKey()); @@ -352,7 +352,7 @@ public class BubbleControllerTest extends SysuiTestCase { mBubbleController.removeBubble( mRow.getEntry().getKey(), BubbleController.DISMISS_NOTIF_CANCEL); verify(mNotificationEntryManager, times(1)).performRemoveNotification( - eq(mRow.getEntry().getSbn()), anyInt()); + eq(mRow.getEntry().getSbn()), any(), anyInt()); assertThat(mBubbleData.getOverflowBubbles()).isEmpty(); assertFalse(mRow.getEntry().isBubble()); } @@ -365,7 +365,7 @@ public class BubbleControllerTest extends SysuiTestCase { mBubbleController.removeBubble( mRow.getEntry().getKey(), BubbleController.DISMISS_USER_CHANGED); verify(mNotificationEntryManager, never()).performRemoveNotification( - eq(mRow.getEntry().getSbn()), anyInt()); + eq(mRow.getEntry().getSbn()), any(), anyInt()); assertFalse(mBubbleController.hasBubbles()); assertFalse(mSysUiStateBubblesExpanded); assertTrue(mRow.getEntry().isBubble()); @@ -873,7 +873,7 @@ public class BubbleControllerTest extends SysuiTestCase { mRow2.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE); // Overflow max of 1 is reached; mRow is oldest, so it gets removed verify(mNotificationEntryManager, times(1)).performRemoveNotification( - mRow.getEntry().getSbn(), REASON_CANCEL); + eq(mRow.getEntry().getSbn()), any(), eq(REASON_CANCEL)); assertEquals(mBubbleData.getBubbles().size(), 1); assertEquals(mBubbleData.getOverflowBubbles().size(), 1); } @@ -985,11 +985,13 @@ public class BubbleControllerTest extends SysuiTestCase { // THEN only the NON-bubble children are dismissed List<ExpandableNotificationRow> childrenRows = groupSummary.getAttachedChildren(); verify(mNotificationEntryManager, times(1)).performRemoveNotification( - childrenRows.get(0).getEntry().getSbn(), REASON_GROUP_SUMMARY_CANCELED); + eq(childrenRows.get(0).getEntry().getSbn()), any(), + eq(REASON_GROUP_SUMMARY_CANCELED)); verify(mNotificationEntryManager, times(1)).performRemoveNotification( - childrenRows.get(1).getEntry().getSbn(), REASON_GROUP_SUMMARY_CANCELED); + eq(childrenRows.get(1).getEntry().getSbn()), any(), + eq(REASON_GROUP_SUMMARY_CANCELED)); verify(mNotificationEntryManager, never()).performRemoveNotification( - eq(groupedBubble.getEntry().getSbn()), anyInt()); + eq(groupedBubble.getEntry().getSbn()), any(), anyInt()); // THEN the bubble child is suppressed from the shade assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java index 686a09444ee6..43bf19111049 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java @@ -26,6 +26,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; @@ -301,7 +302,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { assertTrue(mBubbleData.hasOverflowBubbleWithKey(mRow.getEntry().getKey())); // We don't remove the notification since the bubble is still in overflow. - verify(mNotifCallback, never()).removeNotification(eq(mRow.getEntry()), anyInt()); + verify(mNotifCallback, never()).removeNotification(eq(mRow.getEntry()), any(), anyInt()); assertFalse(mBubbleController.hasBubbles()); } @@ -325,7 +326,8 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { // Since the notif is dismissed and not in overflow, once the bubble is removed, // removeNotification gets called to really remove the notif - verify(mNotifCallback, times(1)).removeNotification(eq(mRow.getEntry()), anyInt()); + verify(mNotifCallback, times(1)).removeNotification(eq(mRow.getEntry()), + any(), anyInt()); assertFalse(mBubbleController.hasBubbles()); } @@ -831,10 +833,11 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { // THEN only the NON-bubble children are dismissed List<ExpandableNotificationRow> childrenRows = groupSummary.getAttachedChildren(); verify(mNotifCallback, times(1)).removeNotification( - childrenRows.get(0).getEntry(), REASON_GROUP_SUMMARY_CANCELED); + eq(childrenRows.get(0).getEntry()), any(), eq(REASON_GROUP_SUMMARY_CANCELED)); verify(mNotifCallback, times(1)).removeNotification( - childrenRows.get(1).getEntry(), REASON_GROUP_SUMMARY_CANCELED); - verify(mNotifCallback, never()).removeNotification(eq(groupedBubble.getEntry()), anyInt()); + eq(childrenRows.get(1).getEntry()), any(), eq(REASON_GROUP_SUMMARY_CANCELED)); + verify(mNotifCallback, never()).removeNotification(eq(groupedBubble.getEntry()), + any(), anyInt()); // THEN the bubble child still exists as a bubble and is suppressed from the shade assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey())); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java index 8a49326add25..d4718e7e55fa 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java @@ -57,11 +57,11 @@ import android.util.ArraySet; import androidx.annotation.NonNull; import androidx.test.filters.SmallTest; +import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; -import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.NotificationLifetimeExtender; import com.android.systemui.statusbar.NotificationMediaManager; @@ -75,6 +75,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; import com.android.systemui.statusbar.notification.collection.NotificationRankingManager; import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder; +import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats; import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider; import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; @@ -202,8 +203,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase { () -> mRemoteInputManager, mLeakDetector, mock(ForegroundServiceDismissalFeatureController.class), - mock(HeadsUpManager.class), - mock(StatusBarStateController.class) + mock(IStatusBarService.class) ); mEntryManager.setUpWithPresenter(mPresenter); mEntryManager.addNotificationEntryListener(mEntryListener); @@ -294,7 +294,8 @@ public class NotificationEntryManagerTest extends SysuiTestCase { assertTrue(entriesContainKey(mEntryManager.getAllNotifs(), mSbn.getKey())); // WHEN the uninflated entry is removed - mEntryManager.performRemoveNotification(mSbn, UNDEFINED_DISMISS_REASON); + mEntryManager.performRemoveNotification(mSbn, mock(DismissedByUserStats.class), + UNDEFINED_DISMISS_REASON); // THEN the entry is still removed from the allNotifications list assertFalse(entriesContainKey(mEntryManager.getAllNotifs(), mSbn.getKey())); @@ -470,7 +471,8 @@ public class NotificationEntryManagerTest extends SysuiTestCase { @Test public void testPerformRemoveNotification_removedEntry() { mEntryManager.removeNotification(mSbn.getKey(), null, 0); - mEntryManager.performRemoveNotification(mSbn, REASON_CANCEL); + mEntryManager.performRemoveNotification(mSbn, mock(DismissedByUserStats.class), + REASON_CANCEL); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java index 601df2cb4fc7..a90af87064b5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java @@ -40,6 +40,7 @@ import android.testing.TestableLooper; import androidx.asynclayoutinflater.view.AsyncLayoutInflater; import androidx.test.filters.SmallTest; +import com.android.internal.statusbar.IStatusBarService; import com.android.internal.util.NotificationMessagingUtil; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; @@ -185,8 +186,7 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase { () -> mRemoteInputManager, mLeakDetector, mock(ForegroundServiceDismissalFeatureController.class), - mock(HeadsUpManager.class), - mock(StatusBarStateController.class) + mock(IStatusBarService.class) ); NotifRemoteViewCache cache = new NotifRemoteViewCacheImpl(mEntryManager); @@ -252,7 +252,6 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase { mLockscreenUserManager, pipeline, mRowContentBindStage, - mNotificationInterruptionStateProvider, RowInflaterTask::new, mExpandableNotificationRowComponentBuilder, new IconManager( diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java index 6d411333b220..ddac2ecbd6eb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java @@ -49,13 +49,13 @@ import androidx.test.filters.SmallTest; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.internal.logging.testing.UiEventLoggerFake; +import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.ExpandHelper; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.media.KeyguardMediaController; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; -import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.EmptyShadeView; import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.NotificationLockscreenUserManager; @@ -93,7 +93,6 @@ import com.android.systemui.statusbar.phone.NotificationIconAreaController; import com.android.systemui.statusbar.phone.ScrimController; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.StatusBar; -import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.util.leak.LeakDetector; @@ -193,8 +192,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { () -> mRemoteInputManager, mock(LeakDetector.class), mock(ForegroundServiceDismissalFeatureController.class), - mock(HeadsUpManager.class), - mock(StatusBarStateController.class) + mock(IStatusBarService.class) ); mEntryManager.setUpWithPresenter(mock(NotificationPresenter.class)); when(mFeatureFlags.isNewNotifPipelineRenderingEnabled()).thenReturn(false); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java index acdb2c59dc0c..33067343ba40 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java @@ -73,6 +73,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.NotificationTestHelper; +import com.android.systemui.statusbar.notification.row.OnDismissCallback; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; @@ -131,6 +132,8 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { @Mock private Intent mContentIntentInner; @Mock + private OnDismissCallback mOnDismissCallback; + @Mock private NotificationActivityStarter mNotificationActivityStarter; private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock()); @@ -207,7 +210,8 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { mFeatureFlags, mock(MetricsLogger.class), - mock(StatusBarNotificationActivityStarterLogger.class)) + mock(StatusBarNotificationActivityStarterLogger.class), + mOnDismissCallback) .setStatusBar(mStatusBar) .setNotificationPresenter(mock(NotificationPresenter.class)) .setNotificationPanelViewController(mock(NotificationPanelViewController.class)) @@ -266,8 +270,8 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { verify(mClickNotifier).onNotificationClick( eq(sbn.getKey()), any(NotificationVisibility.class)); - // Notification is removed due to FLAG_AUTO_CANCEL - verify(mEntryManager).performRemoveNotification(eq(sbn), eq(REASON_CLICK)); + // Notification calls dismiss callback to remove notification due to FLAG_AUTO_CANCEL + verify(mOnDismissCallback).onDismiss(mNotificationRow.getEntry(), REASON_CLICK); } @Test @@ -296,7 +300,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { verifyZeroInteractions(mContentIntent); // Notification should not be cancelled. - verify(mEntryManager, never()).performRemoveNotification(eq(sbn), anyInt()); + verify(mOnDismissCallback, never()).onDismiss(eq(mNotificationRow.getEntry()), anyInt()); } @Test @@ -326,7 +330,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { verifyZeroInteractions(mContentIntent); // Notification should not be cancelled. - verify(mEntryManager, never()).performRemoveNotification(eq(sbn), anyInt()); + verify(mEntryManager, never()).performRemoveNotification(eq(sbn), any(), anyInt()); } @Test @@ -358,6 +362,6 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { verifyNoMoreInteractions(mContentIntent); // Notification should not be cancelled. - verify(mEntryManager, never()).performRemoveNotification(eq(sbn), anyInt()); + verify(mEntryManager, never()).performRemoveNotification(eq(sbn), any(), anyInt()); } } |