Merge "Inline notif pipeline flag into BubblesManager" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
53044b7a89
@@ -55,8 +55,6 @@ import com.android.systemui.statusbar.CommandQueue;
|
|||||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
|
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
|
||||||
import com.android.systemui.statusbar.NotificationShadeWindowController;
|
import com.android.systemui.statusbar.NotificationShadeWindowController;
|
||||||
import com.android.systemui.statusbar.QsFrameTranslateModule;
|
import com.android.systemui.statusbar.QsFrameTranslateModule;
|
||||||
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
|
||||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||||
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
|
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
|
||||||
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
|
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
|
||||||
@@ -220,11 +218,9 @@ public abstract class SystemUIModule {
|
|||||||
ZenModeController zenModeController,
|
ZenModeController zenModeController,
|
||||||
NotificationLockscreenUserManager notifUserManager,
|
NotificationLockscreenUserManager notifUserManager,
|
||||||
NotificationGroupManagerLegacy groupManager,
|
NotificationGroupManagerLegacy groupManager,
|
||||||
NotificationEntryManager entryManager,
|
|
||||||
CommonNotifCollection notifCollection,
|
CommonNotifCollection notifCollection,
|
||||||
NotifPipeline notifPipeline,
|
NotifPipeline notifPipeline,
|
||||||
SysUiState sysUiState,
|
SysUiState sysUiState,
|
||||||
NotifPipelineFlags notifPipelineFlags,
|
|
||||||
DumpManager dumpManager,
|
DumpManager dumpManager,
|
||||||
@Main Executor sysuiMainExecutor) {
|
@Main Executor sysuiMainExecutor) {
|
||||||
return Optional.ofNullable(BubblesManager.create(context,
|
return Optional.ofNullable(BubblesManager.create(context,
|
||||||
@@ -240,11 +236,9 @@ public abstract class SystemUIModule {
|
|||||||
zenModeController,
|
zenModeController,
|
||||||
notifUserManager,
|
notifUserManager,
|
||||||
groupManager,
|
groupManager,
|
||||||
entryManager,
|
|
||||||
notifCollection,
|
notifCollection,
|
||||||
notifPipeline,
|
notifPipeline,
|
||||||
sysUiState,
|
sysUiState,
|
||||||
notifPipelineFlags,
|
|
||||||
dumpManager,
|
dumpManager,
|
||||||
sysuiMainExecutor));
|
sysuiMainExecutor));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,14 +21,10 @@ import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED;
|
|||||||
import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES;
|
import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES;
|
||||||
import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
|
import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
|
||||||
import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL_ALL;
|
import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL_ALL;
|
||||||
import static android.service.notification.NotificationListenerService.REASON_CANCEL;
|
|
||||||
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.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED;
|
||||||
import static android.service.notification.NotificationStats.DISMISSAL_BUBBLE;
|
import static android.service.notification.NotificationStats.DISMISSAL_BUBBLE;
|
||||||
import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
|
import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
|
||||||
|
|
||||||
import static com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON;
|
|
||||||
import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES;
|
import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES;
|
||||||
import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
|
import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
|
||||||
|
|
||||||
@@ -55,7 +51,6 @@ import androidx.annotation.Nullable;
|
|||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.statusbar.IStatusBarService;
|
import com.android.internal.statusbar.IStatusBarService;
|
||||||
import com.android.internal.statusbar.NotificationVisibility;
|
|
||||||
import com.android.systemui.Dumpable;
|
import com.android.systemui.Dumpable;
|
||||||
import com.android.systemui.dagger.SysUISingleton;
|
import com.android.systemui.dagger.SysUISingleton;
|
||||||
import com.android.systemui.dump.DumpManager;
|
import com.android.systemui.dump.DumpManager;
|
||||||
@@ -63,9 +58,7 @@ import com.android.systemui.model.SysUiState;
|
|||||||
import com.android.systemui.shared.system.QuickStepContract;
|
import com.android.systemui.shared.system.QuickStepContract;
|
||||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
|
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
|
||||||
import com.android.systemui.statusbar.NotificationShadeWindowController;
|
import com.android.systemui.statusbar.NotificationShadeWindowController;
|
||||||
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
|
||||||
import com.android.systemui.statusbar.notification.NotificationChannelHelper;
|
import com.android.systemui.statusbar.notification.NotificationChannelHelper;
|
||||||
import com.android.systemui.statusbar.notification.NotificationEntryListener;
|
|
||||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifCollection;
|
import com.android.systemui.statusbar.notification.collection.NotifCollection;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||||
@@ -114,7 +107,6 @@ public class BubblesManager implements Dumpable {
|
|||||||
private final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
|
private final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
|
||||||
private final NotificationLockscreenUserManager mNotifUserManager;
|
private final NotificationLockscreenUserManager mNotifUserManager;
|
||||||
private final NotificationGroupManagerLegacy mNotificationGroupManager;
|
private final NotificationGroupManagerLegacy mNotificationGroupManager;
|
||||||
private final NotificationEntryManager mNotificationEntryManager;
|
|
||||||
private final CommonNotifCollection mCommonNotifCollection;
|
private final CommonNotifCollection mCommonNotifCollection;
|
||||||
private final NotifPipeline mNotifPipeline;
|
private final NotifPipeline mNotifPipeline;
|
||||||
private final Executor mSysuiMainExecutor;
|
private final Executor mSysuiMainExecutor;
|
||||||
@@ -142,11 +134,9 @@ public class BubblesManager implements Dumpable {
|
|||||||
ZenModeController zenModeController,
|
ZenModeController zenModeController,
|
||||||
NotificationLockscreenUserManager notifUserManager,
|
NotificationLockscreenUserManager notifUserManager,
|
||||||
NotificationGroupManagerLegacy groupManager,
|
NotificationGroupManagerLegacy groupManager,
|
||||||
NotificationEntryManager entryManager,
|
|
||||||
CommonNotifCollection notifCollection,
|
CommonNotifCollection notifCollection,
|
||||||
NotifPipeline notifPipeline,
|
NotifPipeline notifPipeline,
|
||||||
SysUiState sysUiState,
|
SysUiState sysUiState,
|
||||||
NotifPipelineFlags notifPipelineFlags,
|
|
||||||
DumpManager dumpManager,
|
DumpManager dumpManager,
|
||||||
Executor sysuiMainExecutor) {
|
Executor sysuiMainExecutor) {
|
||||||
if (bubblesOptional.isPresent()) {
|
if (bubblesOptional.isPresent()) {
|
||||||
@@ -163,11 +153,9 @@ public class BubblesManager implements Dumpable {
|
|||||||
zenModeController,
|
zenModeController,
|
||||||
notifUserManager,
|
notifUserManager,
|
||||||
groupManager,
|
groupManager,
|
||||||
entryManager,
|
|
||||||
notifCollection,
|
notifCollection,
|
||||||
notifPipeline,
|
notifPipeline,
|
||||||
sysUiState,
|
sysUiState,
|
||||||
notifPipelineFlags,
|
|
||||||
dumpManager,
|
dumpManager,
|
||||||
sysuiMainExecutor);
|
sysuiMainExecutor);
|
||||||
} else {
|
} else {
|
||||||
@@ -189,11 +177,9 @@ public class BubblesManager implements Dumpable {
|
|||||||
ZenModeController zenModeController,
|
ZenModeController zenModeController,
|
||||||
NotificationLockscreenUserManager notifUserManager,
|
NotificationLockscreenUserManager notifUserManager,
|
||||||
NotificationGroupManagerLegacy groupManager,
|
NotificationGroupManagerLegacy groupManager,
|
||||||
NotificationEntryManager entryManager,
|
|
||||||
CommonNotifCollection notifCollection,
|
CommonNotifCollection notifCollection,
|
||||||
NotifPipeline notifPipeline,
|
NotifPipeline notifPipeline,
|
||||||
SysUiState sysUiState,
|
SysUiState sysUiState,
|
||||||
NotifPipelineFlags notifPipelineFlags,
|
|
||||||
DumpManager dumpManager,
|
DumpManager dumpManager,
|
||||||
Executor sysuiMainExecutor) {
|
Executor sysuiMainExecutor) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
@@ -205,7 +191,6 @@ public class BubblesManager implements Dumpable {
|
|||||||
mNotificationInterruptStateProvider = interruptionStateProvider;
|
mNotificationInterruptStateProvider = interruptionStateProvider;
|
||||||
mNotifUserManager = notifUserManager;
|
mNotifUserManager = notifUserManager;
|
||||||
mNotificationGroupManager = groupManager;
|
mNotificationGroupManager = groupManager;
|
||||||
mNotificationEntryManager = entryManager;
|
|
||||||
mCommonNotifCollection = notifCollection;
|
mCommonNotifCollection = notifCollection;
|
||||||
mNotifPipeline = notifPipeline;
|
mNotifPipeline = notifPipeline;
|
||||||
mSysuiMainExecutor = sysuiMainExecutor;
|
mSysuiMainExecutor = sysuiMainExecutor;
|
||||||
@@ -215,11 +200,7 @@ public class BubblesManager implements Dumpable {
|
|||||||
ServiceManager.getService(Context.STATUS_BAR_SERVICE))
|
ServiceManager.getService(Context.STATUS_BAR_SERVICE))
|
||||||
: statusBarService;
|
: statusBarService;
|
||||||
|
|
||||||
if (notifPipelineFlags.isNewPipelineEnabled()) {
|
setupNotifPipeline();
|
||||||
setupNotifPipeline();
|
|
||||||
} else {
|
|
||||||
setupNEM();
|
|
||||||
}
|
|
||||||
|
|
||||||
dumpManager.registerDumpable(TAG, this);
|
dumpManager.registerDumpable(TAG, this);
|
||||||
|
|
||||||
@@ -438,141 +419,6 @@ public class BubblesManager implements Dumpable {
|
|||||||
mBubbles.setSysuiProxy(mSysuiProxy);
|
mBubbles.setSysuiProxy(mSysuiProxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupNEM() {
|
|
||||||
mNotificationEntryManager.addNotificationEntryListener(
|
|
||||||
new NotificationEntryListener() {
|
|
||||||
@Override
|
|
||||||
public void onPendingEntryAdded(NotificationEntry entry) {
|
|
||||||
BubblesManager.this.onEntryAdded(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPreEntryUpdated(NotificationEntry entry) {
|
|
||||||
BubblesManager.this.onEntryUpdated(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEntryRemoved(
|
|
||||||
NotificationEntry entry,
|
|
||||||
@Nullable NotificationVisibility visibility,
|
|
||||||
boolean removedByUser,
|
|
||||||
int reason) {
|
|
||||||
BubblesManager.this.onEntryRemoved(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNotificationRankingUpdated(RankingMap rankingMap) {
|
|
||||||
BubblesManager.this.onRankingUpdate(rankingMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNotificationChannelModified(
|
|
||||||
String pkgName,
|
|
||||||
UserHandle user,
|
|
||||||
NotificationChannel channel,
|
|
||||||
int modificationType) {
|
|
||||||
BubblesManager.this.onNotificationChannelModified(pkgName,
|
|
||||||
user,
|
|
||||||
channel,
|
|
||||||
modificationType);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// The new pipeline takes care of this as a NotifDismissInterceptor BubbleCoordinator
|
|
||||||
mNotificationEntryManager.addNotificationRemoveInterceptor(
|
|
||||||
(key, entry, dismissReason) -> {
|
|
||||||
final boolean isClearAll = dismissReason == REASON_CANCEL_ALL;
|
|
||||||
final boolean isUserDismiss = dismissReason == REASON_CANCEL
|
|
||||||
|| dismissReason == REASON_CLICK;
|
|
||||||
final boolean isAppCancel = dismissReason == REASON_APP_CANCEL
|
|
||||||
|| dismissReason == REASON_APP_CANCEL_ALL;
|
|
||||||
final boolean isSummaryCancel =
|
|
||||||
dismissReason == REASON_GROUP_SUMMARY_CANCELED;
|
|
||||||
|
|
||||||
// Need to check for !appCancel here because the notification may have
|
|
||||||
// previously been dismissed & entry.isRowDismissed would still be true
|
|
||||||
boolean userRemovedNotif =
|
|
||||||
(entry != null && entry.isRowDismissed() && !isAppCancel)
|
|
||||||
|| isClearAll || isUserDismiss || isSummaryCancel;
|
|
||||||
|
|
||||||
if (userRemovedNotif) {
|
|
||||||
return handleDismissalInterception(entry);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
mNotificationGroupManager.registerGroupChangeListener(
|
|
||||||
new NotificationGroupManagerLegacy.OnGroupChangeListener() {
|
|
||||||
@Override
|
|
||||||
public void onGroupSuppressionChanged(
|
|
||||||
NotificationGroupManagerLegacy.NotificationGroup group,
|
|
||||||
boolean suppressed) {
|
|
||||||
// More notifications could be added causing summary to no longer
|
|
||||||
// be suppressed -- in this case need to remove the key.
|
|
||||||
final String groupKey = group.summary != null
|
|
||||||
? group.summary.getSbn().getGroupKey()
|
|
||||||
: null;
|
|
||||||
if (!suppressed && groupKey != null) {
|
|
||||||
mBubbles.removeSuppressedSummaryIfNecessary(groupKey, null, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
addNotifCallback(new NotifCallback() {
|
|
||||||
@Override
|
|
||||||
public void removeNotification(NotificationEntry entry,
|
|
||||||
DismissedByUserStats dismissedByUserStats, int reason) {
|
|
||||||
mNotificationEntryManager.performRemoveNotification(entry.getSbn(),
|
|
||||||
dismissedByUserStats, reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateNotifications(String reason) {
|
|
||||||
mNotificationEntryManager.updateNotifications(reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void maybeCancelSummary(NotificationEntry entry) {
|
|
||||||
// Check if removed bubble has an associated suppressed group summary that needs
|
|
||||||
// to be removed now.
|
|
||||||
final String groupKey = entry.getSbn().getGroupKey();
|
|
||||||
mBubbles.removeSuppressedSummaryIfNecessary(groupKey, (summaryKey) -> {
|
|
||||||
final NotificationEntry summary =
|
|
||||||
mNotificationEntryManager.getActiveNotificationUnfiltered(summaryKey);
|
|
||||||
if (summary != null) {
|
|
||||||
mNotificationEntryManager.performRemoveNotification(
|
|
||||||
summary.getSbn(),
|
|
||||||
getDismissedByUserStats(summary, false),
|
|
||||||
UNDEFINED_DISMISS_REASON);
|
|
||||||
}
|
|
||||||
}, mSysuiMainExecutor);
|
|
||||||
|
|
||||||
// Check if we still need to remove the summary from NoManGroup because the summary
|
|
||||||
// may not be in the mBubbleData.mSuppressedGroupKeys list and removed above.
|
|
||||||
// For example:
|
|
||||||
// 1. Bubbled notifications (group) is posted to shade and are visible bubbles
|
|
||||||
// 2. User expands bubbles so now their respective notifications in the shade are
|
|
||||||
// hidden, including the group summary
|
|
||||||
// 3. User removes all bubbles
|
|
||||||
// 4. We expect all the removed bubbles AND the summary (note: the summary was
|
|
||||||
// never added to the suppressedSummary list in BubbleData, so we add this check)
|
|
||||||
NotificationEntry summary = mNotificationGroupManager.getLogicalGroupSummary(entry);
|
|
||||||
if (summary != null) {
|
|
||||||
ArrayList<NotificationEntry> summaryChildren =
|
|
||||||
mNotificationGroupManager.getLogicalChildren(summary.getSbn());
|
|
||||||
boolean isSummaryThisNotif = summary.getKey().equals(entry.getKey());
|
|
||||||
if (!isSummaryThisNotif && (summaryChildren == null
|
|
||||||
|| summaryChildren.isEmpty())) {
|
|
||||||
mNotificationEntryManager.performRemoveNotification(
|
|
||||||
summary.getSbn(),
|
|
||||||
getDismissedByUserStats(summary, false),
|
|
||||||
UNDEFINED_DISMISS_REASON);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupNotifPipeline() {
|
private void setupNotifPipeline() {
|
||||||
mNotifPipeline.addCollectionListener(new NotifCollectionListener() {
|
mNotifPipeline.addCollectionListener(new NotifCollectionListener() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 The Android Open Source Project
|
* Copyright (C) 2020 The Android Open Source Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -21,12 +21,9 @@ import static android.app.PendingIntent.FLAG_MUTABLE;
|
|||||||
import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED;
|
import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED;
|
||||||
import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED;
|
import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED;
|
||||||
import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
|
import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
|
||||||
import static android.service.notification.NotificationListenerService.REASON_CANCEL;
|
|
||||||
import static android.service.notification.NotificationListenerService.REASON_CANCEL_ALL;
|
|
||||||
import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED;
|
import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED;
|
||||||
|
|
||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
|
||||||
import static com.android.wm.shell.bubbles.Bubbles.DISMISS_NOTIF_CANCEL;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
@@ -62,7 +59,6 @@ import android.graphics.Rect;
|
|||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.graphics.drawable.Icon;
|
import android.graphics.drawable.Icon;
|
||||||
import android.hardware.display.AmbientDisplayConfiguration;
|
import android.hardware.display.AmbientDisplayConfiguration;
|
||||||
import android.hardware.face.FaceManager;
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
@@ -90,18 +86,16 @@ import com.android.systemui.model.SysUiState;
|
|||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
import com.android.systemui.shared.system.QuickStepContract;
|
import com.android.systemui.shared.system.QuickStepContract;
|
||||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
|
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
|
||||||
import com.android.systemui.statusbar.NotificationRemoveInterceptor;
|
|
||||||
import com.android.systemui.statusbar.RankingBuilder;
|
import com.android.systemui.statusbar.RankingBuilder;
|
||||||
import com.android.systemui.statusbar.SysuiStatusBarStateController;
|
import com.android.systemui.statusbar.SysuiStatusBarStateController;
|
||||||
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
||||||
import com.android.systemui.statusbar.notification.NotificationEntryListener;
|
|
||||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
|
||||||
import com.android.systemui.statusbar.notification.NotificationFilter;
|
import com.android.systemui.statusbar.notification.NotificationFilter;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
|
||||||
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
|
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
|
||||||
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
|
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
|
||||||
|
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
|
||||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||||
import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
|
import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
|
||||||
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptLogger;
|
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptLogger;
|
||||||
@@ -118,7 +112,6 @@ import com.android.systemui.statusbar.policy.ConfigurationController;
|
|||||||
import com.android.systemui.statusbar.policy.HeadsUpManager;
|
import com.android.systemui.statusbar.policy.HeadsUpManager;
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||||
import com.android.systemui.statusbar.policy.ZenModeController;
|
import com.android.systemui.statusbar.policy.ZenModeController;
|
||||||
import com.android.wm.shell.R;
|
|
||||||
import com.android.wm.shell.ShellTaskOrganizer;
|
import com.android.wm.shell.ShellTaskOrganizer;
|
||||||
import com.android.wm.shell.TaskViewTransitions;
|
import com.android.wm.shell.TaskViewTransitions;
|
||||||
import com.android.wm.shell.WindowManagerShellWrapper;
|
import com.android.wm.shell.WindowManagerShellWrapper;
|
||||||
@@ -140,8 +133,6 @@ import com.android.wm.shell.common.TaskStackListenerImpl;
|
|||||||
import com.android.wm.shell.draganddrop.DragAndDropController;
|
import com.android.wm.shell.draganddrop.DragAndDropController;
|
||||||
import com.android.wm.shell.onehanded.OneHandedController;
|
import com.android.wm.shell.onehanded.OneHandedController;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -155,22 +146,17 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests the NotificationEntryManager setup with BubbleController.
|
|
||||||
* The {@link NotifPipeline} setup with BubbleController is tested in
|
|
||||||
* {@link NewNotifPipelineBubblesTest}.
|
|
||||||
*/
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWith(AndroidTestingRunner.class)
|
@RunWith(AndroidTestingRunner.class)
|
||||||
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
||||||
public class BubblesTest extends SysuiTestCase {
|
public class BubblesTest extends SysuiTestCase {
|
||||||
@Mock
|
|
||||||
private NotificationEntryManager mNotificationEntryManager;
|
|
||||||
@Mock
|
@Mock
|
||||||
private CommonNotifCollection mCommonNotifCollection;
|
private CommonNotifCollection mCommonNotifCollection;
|
||||||
@Mock
|
@Mock
|
||||||
private NotificationGroupManagerLegacy mNotificationGroupManager;
|
private NotificationGroupManagerLegacy mNotificationGroupManager;
|
||||||
@Mock
|
@Mock
|
||||||
|
private BubblesManager.NotifCallback mNotifCallback;
|
||||||
|
@Mock
|
||||||
private WindowManager mWindowManager;
|
private WindowManager mWindowManager;
|
||||||
@Mock
|
@Mock
|
||||||
private IActivityManager mActivityManager;
|
private IActivityManager mActivityManager;
|
||||||
@@ -183,8 +169,6 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
@Mock
|
@Mock
|
||||||
private ZenModeConfig mZenModeConfig;
|
private ZenModeConfig mZenModeConfig;
|
||||||
@Mock
|
@Mock
|
||||||
private FaceManager mFaceManager;
|
|
||||||
@Mock
|
|
||||||
private NotificationLockscreenUserManager mLockscreenUserManager;
|
private NotificationLockscreenUserManager mLockscreenUserManager;
|
||||||
@Mock
|
@Mock
|
||||||
private SysuiStatusBarStateController mStatusBarStateController;
|
private SysuiStatusBarStateController mStatusBarStateController;
|
||||||
@@ -196,15 +180,17 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
private FloatingContentCoordinator mFloatingContentCoordinator;
|
private FloatingContentCoordinator mFloatingContentCoordinator;
|
||||||
@Mock
|
@Mock
|
||||||
private BubbleDataRepository mDataRepository;
|
private BubbleDataRepository mDataRepository;
|
||||||
|
@Mock
|
||||||
|
private NotificationShadeWindowView mNotificationShadeWindowView;
|
||||||
|
@Mock
|
||||||
|
private AuthController mAuthController;
|
||||||
|
|
||||||
private SysUiState mSysUiState;
|
private SysUiState mSysUiState;
|
||||||
private boolean mSysUiStateBubblesExpanded;
|
private boolean mSysUiStateBubblesExpanded;
|
||||||
private boolean mSysUiStateBubblesManageMenuExpanded;
|
private boolean mSysUiStateBubblesManageMenuExpanded;
|
||||||
|
|
||||||
@Captor
|
@Captor
|
||||||
private ArgumentCaptor<NotificationEntryListener> mEntryListenerCaptor;
|
private ArgumentCaptor<NotifCollectionListener> mNotifListenerCaptor;
|
||||||
@Captor
|
|
||||||
private ArgumentCaptor<NotificationRemoveInterceptor> mRemoveInterceptorCaptor;
|
|
||||||
@Captor
|
@Captor
|
||||||
private ArgumentCaptor<List<Bubble>> mBubbleListCaptor;
|
private ArgumentCaptor<List<Bubble>> mBubbleListCaptor;
|
||||||
@Captor
|
@Captor
|
||||||
@@ -212,22 +198,16 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
@Captor
|
@Captor
|
||||||
private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverArgumentCaptor;
|
private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverArgumentCaptor;
|
||||||
|
|
||||||
|
|
||||||
private BubblesManager mBubblesManager;
|
private BubblesManager mBubblesManager;
|
||||||
// TODO(178618782): Move tests on the controller directly to the shell
|
|
||||||
private TestableBubbleController mBubbleController;
|
private TestableBubbleController mBubbleController;
|
||||||
private NotificationShadeWindowControllerImpl mNotificationShadeWindowController;
|
private NotificationShadeWindowControllerImpl mNotificationShadeWindowController;
|
||||||
private NotificationEntryListener mEntryListener;
|
private NotifCollectionListener mEntryListener;
|
||||||
private NotificationRemoveInterceptor mRemoveInterceptor;
|
|
||||||
|
|
||||||
private NotificationTestHelper mNotificationTestHelper;
|
private NotificationTestHelper mNotificationTestHelper;
|
||||||
private NotificationEntry mRow;
|
private NotificationEntry mRow;
|
||||||
private NotificationEntry mRow2;
|
private NotificationEntry mRow2;
|
||||||
private NotificationEntry mRow3;
|
|
||||||
private ExpandableNotificationRow mNonBubbleNotifRow;
|
private ExpandableNotificationRow mNonBubbleNotifRow;
|
||||||
private BubbleEntry mBubbleEntry;
|
private BubbleEntry mBubbleEntry;
|
||||||
private BubbleEntry mBubbleEntry2;
|
private BubbleEntry mBubbleEntry2;
|
||||||
private BubbleEntry mBubbleEntry3;
|
|
||||||
|
|
||||||
private BubbleEntry mBubbleEntryUser11;
|
private BubbleEntry mBubbleEntryUser11;
|
||||||
private BubbleEntry mBubbleEntry2User11;
|
private BubbleEntry mBubbleEntry2User11;
|
||||||
@@ -245,12 +225,8 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
@Mock
|
@Mock
|
||||||
private NotifPipeline mNotifPipeline;
|
private NotifPipeline mNotifPipeline;
|
||||||
@Mock
|
@Mock
|
||||||
private NotifPipelineFlags mNotifPipelineFlags;
|
|
||||||
@Mock
|
|
||||||
private DumpManager mDumpManager;
|
private DumpManager mDumpManager;
|
||||||
@Mock
|
@Mock
|
||||||
private NotificationShadeWindowView mNotificationShadeWindowView;
|
|
||||||
@Mock
|
|
||||||
private IStatusBarService mStatusBarService;
|
private IStatusBarService mStatusBarService;
|
||||||
@Mock
|
@Mock
|
||||||
private NotificationVisibilityProvider mVisibilityProvider;
|
private NotificationVisibilityProvider mVisibilityProvider;
|
||||||
@@ -269,8 +245,6 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
@Mock
|
@Mock
|
||||||
private ScreenOffAnimationController mScreenOffAnimationController;
|
private ScreenOffAnimationController mScreenOffAnimationController;
|
||||||
@Mock
|
@Mock
|
||||||
private AuthController mAuthController;
|
|
||||||
@Mock
|
|
||||||
private TaskViewTransitions mTaskViewTransitions;
|
private TaskViewTransitions mTaskViewTransitions;
|
||||||
@Mock
|
@Mock
|
||||||
private Optional<OneHandedController> mOneHandedOptional;
|
private Optional<OneHandedController> mOneHandedOptional;
|
||||||
@@ -290,7 +264,6 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
// For the purposes of this test, just run everything synchronously
|
// For the purposes of this test, just run everything synchronously
|
||||||
ShellExecutor syncExecutor = new SyncExecutor();
|
ShellExecutor syncExecutor = new SyncExecutor();
|
||||||
|
|
||||||
mContext.addMockSystemService(FaceManager.class, mFaceManager);
|
|
||||||
when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
|
when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
|
||||||
|
|
||||||
mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl(mContext,
|
mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl(mContext,
|
||||||
@@ -308,11 +281,9 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
TestableLooper.get(this));
|
TestableLooper.get(this));
|
||||||
mRow = mNotificationTestHelper.createBubble(mDeleteIntent);
|
mRow = mNotificationTestHelper.createBubble(mDeleteIntent);
|
||||||
mRow2 = mNotificationTestHelper.createBubble(mDeleteIntent);
|
mRow2 = mNotificationTestHelper.createBubble(mDeleteIntent);
|
||||||
mRow3 = mNotificationTestHelper.createBubble(mDeleteIntent);
|
|
||||||
mNonBubbleNotifRow = mNotificationTestHelper.createRow();
|
mNonBubbleNotifRow = mNotificationTestHelper.createRow();
|
||||||
mBubbleEntry = BubblesManager.notifToBubbleEntry(mRow);
|
mBubbleEntry = BubblesManager.notifToBubbleEntry(mRow);
|
||||||
mBubbleEntry2 = BubblesManager.notifToBubbleEntry(mRow2);
|
mBubbleEntry2 = BubblesManager.notifToBubbleEntry(mRow2);
|
||||||
mBubbleEntry3 = BubblesManager.notifToBubbleEntry(mRow3);
|
|
||||||
|
|
||||||
UserHandle handle = mock(UserHandle.class);
|
UserHandle handle = mock(UserHandle.class);
|
||||||
when(handle.getIdentifier()).thenReturn(11);
|
when(handle.getIdentifier()).thenReturn(11);
|
||||||
@@ -321,9 +292,6 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
mBubbleEntry2User11 = BubblesManager.notifToBubbleEntry(
|
mBubbleEntry2User11 = BubblesManager.notifToBubbleEntry(
|
||||||
mNotificationTestHelper.createBubble(handle));
|
mNotificationTestHelper.createBubble(handle));
|
||||||
|
|
||||||
// Return non-null notification data from the CommonNotifCollection
|
|
||||||
when(mCommonNotifCollection.getEntry(mRow.getKey())).thenReturn(mRow);
|
|
||||||
|
|
||||||
mZenModeConfig.suppressedVisualEffects = 0;
|
mZenModeConfig.suppressedVisualEffects = 0;
|
||||||
when(mZenModeController.getConfig()).thenReturn(mZenModeConfig);
|
when(mZenModeController.getConfig()).thenReturn(mZenModeConfig);
|
||||||
|
|
||||||
@@ -336,7 +304,6 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
(sysUiFlags & QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED) != 0;
|
(sysUiFlags & QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED) != 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: Fix
|
|
||||||
mPositioner = new TestableBubblePositioner(mContext, mWindowManager);
|
mPositioner = new TestableBubblePositioner(mContext, mWindowManager);
|
||||||
mPositioner.setMaxBubbles(5);
|
mPositioner.setMaxBubbles(5);
|
||||||
mBubbleData = new BubbleData(mContext, mBubbleLogger, mPositioner, syncExecutor);
|
mBubbleData = new BubbleData(mContext, mBubbleLogger, mPositioner, syncExecutor);
|
||||||
@@ -355,8 +322,6 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
mock(NotifPipelineFlags.class),
|
mock(NotifPipelineFlags.class),
|
||||||
mock(KeyguardNotificationVisibilityProvider.class)
|
mock(KeyguardNotificationVisibilityProvider.class)
|
||||||
);
|
);
|
||||||
|
|
||||||
when(mNotifPipelineFlags.isNewPipelineEnabled()).thenReturn(false);
|
|
||||||
when(mShellTaskOrganizer.getExecutor()).thenReturn(syncExecutor);
|
when(mShellTaskOrganizer.getExecutor()).thenReturn(syncExecutor);
|
||||||
mBubbleController = new TestableBubbleController(
|
mBubbleController = new TestableBubbleController(
|
||||||
mContext,
|
mContext,
|
||||||
@@ -396,23 +361,17 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
mZenModeController,
|
mZenModeController,
|
||||||
mLockscreenUserManager,
|
mLockscreenUserManager,
|
||||||
mNotificationGroupManager,
|
mNotificationGroupManager,
|
||||||
mNotificationEntryManager,
|
|
||||||
mCommonNotifCollection,
|
mCommonNotifCollection,
|
||||||
mNotifPipeline,
|
mNotifPipeline,
|
||||||
mSysUiState,
|
mSysUiState,
|
||||||
mNotifPipelineFlags,
|
|
||||||
mDumpManager,
|
mDumpManager,
|
||||||
syncExecutor);
|
syncExecutor);
|
||||||
|
mBubblesManager.addNotifCallback(mNotifCallback);
|
||||||
|
|
||||||
// XXX: Does *this* need to be changed?
|
|
||||||
// Get a reference to the BubbleController's entry listener
|
// Get a reference to the BubbleController's entry listener
|
||||||
verify(mNotificationEntryManager, atLeastOnce())
|
verify(mNotifPipeline, atLeastOnce())
|
||||||
.addNotificationEntryListener(mEntryListenerCaptor.capture());
|
.addCollectionListener(mNotifListenerCaptor.capture());
|
||||||
mEntryListener = mEntryListenerCaptor.getValue();
|
mEntryListener = mNotifListenerCaptor.getValue();
|
||||||
// And the remove interceptor
|
|
||||||
verify(mNotificationEntryManager, atLeastOnce())
|
|
||||||
.addNotificationRemoveInterceptor(mRemoveInterceptorCaptor.capture());
|
|
||||||
mRemoveInterceptor = mRemoveInterceptorCaptor.getValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -433,90 +392,75 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testRemoveBubble() {
|
public void testRemoveBubble() {
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
mBubbleController.updateBubble(mBubbleEntry);
|
||||||
assertNotNull(mBubbleData.getBubbleInStackWithKey(mBubbleEntry.getKey()));
|
assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow.getKey()));
|
||||||
assertTrue(mBubbleController.hasBubbles());
|
assertTrue(mBubbleController.hasBubbles());
|
||||||
verify(mNotificationEntryManager).updateNotifications(any());
|
verify(mNotifCallback, times(1)).invalidateNotifications(anyString());
|
||||||
|
|
||||||
mBubbleController.removeBubble(
|
mBubbleController.removeBubble(
|
||||||
mRow.getKey(), Bubbles.DISMISS_USER_GESTURE);
|
mRow.getKey(), Bubbles.DISMISS_USER_GESTURE);
|
||||||
assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getKey()));
|
assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getKey()));
|
||||||
verify(mNotificationEntryManager, times(2)).updateNotifications(anyString());
|
verify(mNotifCallback, times(2)).invalidateNotifications(anyString());
|
||||||
|
|
||||||
assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */);
|
assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPromoteBubble_autoExpand() throws Exception {
|
public void testRemoveBubble_withDismissedNotif_inOverflow() {
|
||||||
mBubbleController.updateBubble(mBubbleEntry2);
|
mEntryListener.onEntryAdded(mRow);
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
mBubbleController.updateBubble(mBubbleEntry);
|
||||||
when(mCommonNotifCollection.getEntry(mRow.getKey())).thenReturn(mRow);
|
|
||||||
when(mCommonNotifCollection.getEntry(mRow2.getKey())).thenReturn(mRow2);
|
|
||||||
mBubbleController.removeBubble(
|
|
||||||
mRow.getKey(), Bubbles.DISMISS_USER_GESTURE);
|
|
||||||
|
|
||||||
Bubble b = mBubbleData.getOverflowBubbleWithKey(mRow.getKey());
|
|
||||||
assertThat(mBubbleData.getOverflowBubbles()).isEqualTo(ImmutableList.of(b));
|
|
||||||
verify(mNotificationEntryManager, never()).performRemoveNotification(
|
|
||||||
eq(mRow.getSbn()), any(), anyInt());
|
|
||||||
assertThat(mRow.isBubble()).isFalse();
|
|
||||||
|
|
||||||
Bubble b2 = mBubbleData.getBubbleInStackWithKey(mRow2.getKey());
|
|
||||||
assertThat(mBubbleData.getSelectedBubble()).isEqualTo(b2);
|
|
||||||
|
|
||||||
mBubbleController.promoteBubbleFromOverflow(b);
|
|
||||||
|
|
||||||
assertThat(b.isBubble()).isTrue();
|
|
||||||
assertThat(b.shouldAutoExpand()).isTrue();
|
|
||||||
int flags = Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE
|
|
||||||
| Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION;
|
|
||||||
verify(mStatusBarService, times(1)).onNotificationBubbleChanged(
|
|
||||||
eq(b.getKey()), eq(true), eq(flags));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCancelOverflowBubble() {
|
|
||||||
mBubbleController.updateBubble(mBubbleEntry2);
|
|
||||||
mBubbleController.updateBubble(mBubbleEntry, /* suppressFlyout */
|
|
||||||
false, /* showInShade */ true);
|
|
||||||
when(mCommonNotifCollection.getEntry(mRow.getKey())).thenReturn(mRow);
|
|
||||||
when(mCommonNotifCollection.getEntry(mRow2.getKey())).thenReturn(mRow2);
|
|
||||||
mBubbleController.removeBubble(
|
|
||||||
mRow.getKey(), Bubbles.DISMISS_USER_GESTURE);
|
|
||||||
|
|
||||||
mBubbleController.removeBubble(
|
|
||||||
mRow.getKey(), DISMISS_NOTIF_CANCEL);
|
|
||||||
verify(mNotificationEntryManager, times(1)).performRemoveNotification(
|
|
||||||
eq(mRow.getSbn()), any(), anyInt());
|
|
||||||
assertThat(mBubbleData.getOverflowBubbles()).isEmpty();
|
|
||||||
assertFalse(mRow.isBubble());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUserChange_doesNotRemoveNotif() {
|
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
|
||||||
assertTrue(mBubbleController.hasBubbles());
|
assertTrue(mBubbleController.hasBubbles());
|
||||||
|
assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry);
|
||||||
|
|
||||||
|
// Make it look like dismissed notif
|
||||||
|
mBubbleData.getBubbleInStackWithKey(mRow.getKey()).setSuppressNotification(true);
|
||||||
|
|
||||||
|
// Now remove the bubble
|
||||||
mBubbleController.removeBubble(
|
mBubbleController.removeBubble(
|
||||||
mRow.getKey(), Bubbles.DISMISS_USER_CHANGED);
|
mRow.getKey(), Bubbles.DISMISS_USER_GESTURE);
|
||||||
verify(mNotificationEntryManager, never()).performRemoveNotification(
|
assertTrue(mBubbleData.hasOverflowBubbleWithKey(mRow.getKey()));
|
||||||
eq(mRow.getSbn()), any(), anyInt());
|
|
||||||
|
// We don't remove the notification since the bubble is still in overflow.
|
||||||
|
verify(mNotifCallback, never()).removeNotification(eq(mRow), any(), anyInt());
|
||||||
|
assertFalse(mBubbleController.hasBubbles());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRemoveBubble_withDismissedNotif_notInOverflow() {
|
||||||
|
mEntryListener.onEntryAdded(mRow);
|
||||||
|
mBubbleController.updateBubble(mBubbleEntry);
|
||||||
|
when(mCommonNotifCollection.getEntry(mRow.getKey())).thenReturn(mRow);
|
||||||
|
|
||||||
|
assertTrue(mBubbleController.hasBubbles());
|
||||||
|
assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry);
|
||||||
|
|
||||||
|
// Make it look like dismissed notif
|
||||||
|
mBubbleData.getBubbleInStackWithKey(mRow.getKey()).setSuppressNotification(true);
|
||||||
|
|
||||||
|
// Now remove the bubble
|
||||||
|
mBubbleController.removeBubble(
|
||||||
|
mRow.getKey(), Bubbles.DISMISS_NOTIF_CANCEL);
|
||||||
|
assertFalse(mBubbleData.hasOverflowBubbleWithKey(mRow.getKey()));
|
||||||
|
|
||||||
|
// 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),
|
||||||
|
any(), anyInt());
|
||||||
assertFalse(mBubbleController.hasBubbles());
|
assertFalse(mBubbleController.hasBubbles());
|
||||||
assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */);
|
|
||||||
assertTrue(mRow.isBubble());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDismissStack() {
|
public void testDismissStack() {
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
mBubbleController.updateBubble(mBubbleEntry);
|
||||||
verify(mNotificationEntryManager, times(1)).updateNotifications(any());
|
verify(mNotifCallback, times(1)).invalidateNotifications(anyString());
|
||||||
assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow.getKey()));
|
assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow.getKey()));
|
||||||
mBubbleController.updateBubble(mBubbleEntry2);
|
mBubbleController.updateBubble(mBubbleEntry2);
|
||||||
verify(mNotificationEntryManager, times(2)).updateNotifications(any());
|
verify(mNotifCallback, times(2)).invalidateNotifications(anyString());
|
||||||
assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow2.getKey()));
|
assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow2.getKey()));
|
||||||
assertTrue(mBubbleController.hasBubbles());
|
assertTrue(mBubbleController.hasBubbles());
|
||||||
|
|
||||||
mBubbleData.dismissAll(Bubbles.DISMISS_USER_GESTURE);
|
mBubbleData.dismissAll(Bubbles.DISMISS_USER_GESTURE);
|
||||||
verify(mNotificationEntryManager, times(3)).updateNotifications(any());
|
verify(mNotifCallback, times(3)).invalidateNotifications(anyString());
|
||||||
assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getKey()));
|
assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getKey()));
|
||||||
assertNull(mBubbleData.getBubbleInStackWithKey(mRow2.getKey()));
|
assertNull(mBubbleData.getBubbleInStackWithKey(mRow2.getKey()));
|
||||||
|
|
||||||
@@ -528,7 +472,7 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
assertStackCollapsed();
|
assertStackCollapsed();
|
||||||
|
|
||||||
// Mark it as a bubble and add it explicitly
|
// Mark it as a bubble and add it explicitly
|
||||||
mEntryListener.onPendingEntryAdded(mRow);
|
mEntryListener.onEntryAdded(mRow);
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
mBubbleController.updateBubble(mBubbleEntry);
|
||||||
|
|
||||||
// We should have bubbles & their notifs should not be suppressed
|
// We should have bubbles & their notifs should not be suppressed
|
||||||
@@ -536,7 +480,6 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry);
|
assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry);
|
||||||
|
|
||||||
// Expand the stack
|
// Expand the stack
|
||||||
BubbleStackView stackView = mBubbleController.getStackView();
|
|
||||||
mBubbleData.setExpanded(true);
|
mBubbleData.setExpanded(true);
|
||||||
assertStackExpanded();
|
assertStackExpanded();
|
||||||
verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getKey());
|
verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getKey());
|
||||||
@@ -556,8 +499,8 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
@Ignore("Currently broken.")
|
@Ignore("Currently broken.")
|
||||||
public void testCollapseAfterChangingExpandedBubble() {
|
public void testCollapseAfterChangingExpandedBubble() {
|
||||||
// Mark it as a bubble and add it explicitly
|
// Mark it as a bubble and add it explicitly
|
||||||
mEntryListener.onPendingEntryAdded(mRow);
|
mEntryListener.onEntryAdded(mRow);
|
||||||
mEntryListener.onPendingEntryAdded(mRow2);
|
mEntryListener.onEntryAdded(mRow2);
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
mBubbleController.updateBubble(mBubbleEntry);
|
||||||
mBubbleController.updateBubble(mBubbleEntry2);
|
mBubbleController.updateBubble(mBubbleEntry2);
|
||||||
|
|
||||||
@@ -593,6 +536,7 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
verify(mBubbleExpandListener, atLeastOnce()).onBubbleExpandChanged(
|
verify(mBubbleExpandListener, atLeastOnce()).onBubbleExpandChanged(
|
||||||
true, mRow.getKey());
|
true, mRow.getKey());
|
||||||
|
|
||||||
|
|
||||||
// Collapse
|
// Collapse
|
||||||
mBubbleController.collapseStack();
|
mBubbleController.collapseStack();
|
||||||
assertStackCollapsed();
|
assertStackCollapsed();
|
||||||
@@ -602,7 +546,7 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testExpansionRemovesShowInShadeAndDot() {
|
public void testExpansionRemovesShowInShadeAndDot() {
|
||||||
// Mark it as a bubble and add it explicitly
|
// Mark it as a bubble and add it explicitly
|
||||||
mEntryListener.onPendingEntryAdded(mRow);
|
mEntryListener.onEntryAdded(mRow);
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
mBubbleController.updateBubble(mBubbleEntry);
|
||||||
|
|
||||||
// We should have bubbles & their notifs should not be suppressed
|
// We should have bubbles & their notifs should not be suppressed
|
||||||
@@ -627,7 +571,7 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testUpdateWhileExpanded_DoesntChangeShowInShadeAndDot() {
|
public void testUpdateWhileExpanded_DoesntChangeShowInShadeAndDot() {
|
||||||
// Mark it as a bubble and add it explicitly
|
// Mark it as a bubble and add it explicitly
|
||||||
mEntryListener.onPendingEntryAdded(mRow);
|
mEntryListener.onEntryAdded(mRow);
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
mBubbleController.updateBubble(mBubbleEntry);
|
||||||
|
|
||||||
// We should have bubbles & their notifs should not be suppressed
|
// We should have bubbles & their notifs should not be suppressed
|
||||||
@@ -649,7 +593,7 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getKey()).showDot());
|
assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getKey()).showDot());
|
||||||
|
|
||||||
// Send update
|
// Send update
|
||||||
mEntryListener.onPreEntryUpdated(mRow);
|
mEntryListener.onEntryUpdated(mRow);
|
||||||
|
|
||||||
// Nothing should have changed
|
// Nothing should have changed
|
||||||
// Notif is suppressed after expansion
|
// Notif is suppressed after expansion
|
||||||
@@ -661,8 +605,8 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testRemoveLastExpanded_collapses() {
|
public void testRemoveLastExpanded_collapses() {
|
||||||
// Mark it as a bubble and add it explicitly
|
// Mark it as a bubble and add it explicitly
|
||||||
mEntryListener.onPendingEntryAdded(mRow);
|
mEntryListener.onEntryAdded(mRow);
|
||||||
mEntryListener.onPendingEntryAdded(mRow2);
|
mEntryListener.onEntryAdded(mRow2);
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
mBubbleController.updateBubble(mBubbleEntry);
|
||||||
mBubbleController.updateBubble(mBubbleEntry2);
|
mBubbleController.updateBubble(mBubbleEntry2);
|
||||||
|
|
||||||
@@ -707,7 +651,7 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testRemoveLastExpandedEmptyOverflow_collapses() {
|
public void testRemoveLastExpandedEmptyOverflow_collapses() {
|
||||||
// Mark it as a bubble and add it explicitly
|
// Mark it as a bubble and add it explicitly
|
||||||
mEntryListener.onPendingEntryAdded(mRow);
|
mEntryListener.onEntryAdded(mRow);
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
mBubbleController.updateBubble(mBubbleEntry);
|
||||||
|
|
||||||
// Expand
|
// Expand
|
||||||
@@ -732,6 +676,7 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */);
|
assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAutoExpand_fails_noFlag() {
|
public void testAutoExpand_fails_noFlag() {
|
||||||
assertStackCollapsed();
|
assertStackCollapsed();
|
||||||
@@ -739,7 +684,7 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE, false /* enableFlag */);
|
Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE, false /* enableFlag */);
|
||||||
|
|
||||||
// Add the auto expand bubble
|
// Add the auto expand bubble
|
||||||
mEntryListener.onPendingEntryAdded(mRow);
|
mEntryListener.onEntryAdded(mRow);
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
mBubbleController.updateBubble(mBubbleEntry);
|
||||||
|
|
||||||
// Expansion shouldn't change
|
// Expansion shouldn't change
|
||||||
@@ -755,7 +700,7 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE, true /* enableFlag */);
|
Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE, true /* enableFlag */);
|
||||||
|
|
||||||
// Add the auto expand bubble
|
// Add the auto expand bubble
|
||||||
mEntryListener.onPendingEntryAdded(mRow);
|
mEntryListener.onEntryAdded(mRow);
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
mBubbleController.updateBubble(mBubbleEntry);
|
||||||
|
|
||||||
// Expansion should change
|
// Expansion should change
|
||||||
@@ -771,7 +716,7 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION, true /* enableFlag */);
|
Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION, true /* enableFlag */);
|
||||||
|
|
||||||
// Add the suppress notif bubble
|
// Add the suppress notif bubble
|
||||||
mEntryListener.onPendingEntryAdded(mRow);
|
mEntryListener.onEntryAdded(mRow);
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
mBubbleController.updateBubble(mBubbleEntry);
|
||||||
|
|
||||||
// Notif should be suppressed because we were foreground
|
// Notif should be suppressed because we were foreground
|
||||||
@@ -804,23 +749,9 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */);
|
assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExpandStackAndSelectBubble_removedFirst() {
|
|
||||||
mEntryListener.onPendingEntryAdded(mRow);
|
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
|
||||||
|
|
||||||
// Simulate notification cancellation.
|
|
||||||
mRemoveInterceptor.onNotificationRemoveRequested(
|
|
||||||
mRow.getKey(), mRow, REASON_APP_CANCEL);
|
|
||||||
|
|
||||||
mBubbleController.expandStackAndSelectBubble(mBubbleEntry);
|
|
||||||
|
|
||||||
assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMarkNewNotificationAsShowInShade() {
|
public void testMarkNewNotificationAsShowInShade() {
|
||||||
mEntryListener.onPendingEntryAdded(mRow);
|
mEntryListener.onEntryAdded(mRow);
|
||||||
assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry);
|
assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry);
|
||||||
|
|
||||||
mTestableLooper.processAllMessages();
|
mTestableLooper.processAllMessages();
|
||||||
@@ -829,8 +760,8 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddNotif_notBubble() {
|
public void testAddNotif_notBubble() {
|
||||||
mEntryListener.onPendingEntryAdded(mNonBubbleNotifRow.getEntry());
|
mEntryListener.onEntryAdded(mNonBubbleNotifRow.getEntry());
|
||||||
mEntryListener.onPreEntryUpdated(mNonBubbleNotifRow.getEntry());
|
mEntryListener.onEntryUpdated(mNonBubbleNotifRow.getEntry());
|
||||||
|
|
||||||
assertThat(mBubbleController.hasBubbles()).isFalse();
|
assertThat(mBubbleController.hasBubbles()).isFalse();
|
||||||
}
|
}
|
||||||
@@ -868,48 +799,33 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
NotificationListenerService.Ranking ranking = new RankingBuilder(
|
NotificationListenerService.Ranking ranking = new RankingBuilder(
|
||||||
mRow.getRanking()).setCanBubble(false).build();
|
mRow.getRanking()).setCanBubble(false).build();
|
||||||
mRow.setRanking(ranking);
|
mRow.setRanking(ranking);
|
||||||
mEntryListener.onPreEntryUpdated(mRow);
|
mEntryListener.onEntryUpdated(mRow);
|
||||||
|
|
||||||
assertFalse(mBubbleController.hasBubbles());
|
assertFalse(mBubbleController.hasBubbles());
|
||||||
verify(mDeleteIntent, never()).send();
|
verify(mDeleteIntent, never()).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRemoveBubble_succeeds_appCancel() {
|
|
||||||
mEntryListener.onPendingEntryAdded(mRow);
|
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
|
||||||
|
|
||||||
assertTrue(mBubbleController.hasBubbles());
|
|
||||||
|
|
||||||
boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
|
|
||||||
mRow.getKey(), mRow, REASON_APP_CANCEL);
|
|
||||||
|
|
||||||
// Cancels always remove so no need to intercept
|
|
||||||
assertFalse(intercepted);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRemoveBubble_entryListenerRemove() {
|
public void testRemoveBubble_entryListenerRemove() {
|
||||||
mEntryListener.onPendingEntryAdded(mRow);
|
mEntryListener.onEntryAdded(mRow);
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
mBubbleController.updateBubble(mBubbleEntry);
|
||||||
|
|
||||||
assertTrue(mBubbleController.hasBubbles());
|
assertTrue(mBubbleController.hasBubbles());
|
||||||
|
|
||||||
// Removes the notification
|
// Removes the notification
|
||||||
mEntryListener.onEntryRemoved(mRow, null, false, REASON_APP_CANCEL);
|
mEntryListener.onEntryRemoved(mRow, REASON_APP_CANCEL);
|
||||||
assertFalse(mBubbleController.hasBubbles());
|
assertFalse(mBubbleController.hasBubbles());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void removeBubble_clearAllIntercepted() {
|
public void removeBubble_intercepted() {
|
||||||
mEntryListener.onPendingEntryAdded(mRow);
|
mEntryListener.onEntryAdded(mRow);
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
mBubbleController.updateBubble(mBubbleEntry);
|
||||||
|
|
||||||
assertTrue(mBubbleController.hasBubbles());
|
assertTrue(mBubbleController.hasBubbles());
|
||||||
assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry);
|
assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry);
|
||||||
|
|
||||||
boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
|
boolean intercepted = mBubblesManager.handleDismissalInterception(mRow);
|
||||||
mRow.getKey(), mRow, REASON_CANCEL_ALL);
|
|
||||||
|
|
||||||
// Intercept!
|
// Intercept!
|
||||||
assertTrue(intercepted);
|
assertTrue(intercepted);
|
||||||
@@ -918,99 +834,51 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void removeBubble_userDismissNotifIntercepted() {
|
public void removeBubble_dismissIntoOverflow_intercepted() {
|
||||||
mEntryListener.onPendingEntryAdded(mRow);
|
mEntryListener.onEntryAdded(mRow);
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
mBubbleController.updateBubble(mBubbleEntry);
|
||||||
|
|
||||||
assertTrue(mBubbleController.hasBubbles());
|
assertTrue(mBubbleController.hasBubbles());
|
||||||
assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry);
|
assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry);
|
||||||
|
|
||||||
boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
|
// Dismiss the bubble
|
||||||
mRow.getKey(), mRow, REASON_CANCEL);
|
mBubbleController.removeBubble(mRow.getKey(), Bubbles.DISMISS_USER_GESTURE);
|
||||||
|
|
||||||
// Intercept!
|
|
||||||
assertTrue(intercepted);
|
|
||||||
// Should update show in shade state
|
|
||||||
assertBubbleNotificationSuppressedFromShade(mBubbleEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void removeNotif_inOverflow_intercepted() {
|
|
||||||
// Get bubble with notif in shade.
|
|
||||||
mEntryListener.onPendingEntryAdded(mRow);
|
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
|
||||||
assertTrue(mBubbleController.hasBubbles());
|
|
||||||
assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry);
|
|
||||||
|
|
||||||
// Dismiss the bubble into overflow.
|
|
||||||
mBubbleController.removeBubble(
|
|
||||||
mRow.getKey(), Bubbles.DISMISS_USER_GESTURE);
|
|
||||||
assertFalse(mBubbleController.hasBubbles());
|
assertFalse(mBubbleController.hasBubbles());
|
||||||
|
|
||||||
boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
|
// Dismiss the notification
|
||||||
mRow.getKey(), mRow, REASON_CANCEL);
|
boolean intercepted = mBubblesManager.handleDismissalInterception(mRow);
|
||||||
|
|
||||||
// Notif is no longer a bubble, but still in overflow, so we intercept removal.
|
// Intercept dismissal since bubble is going into overflow
|
||||||
assertTrue(intercepted);
|
assertTrue(intercepted);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void removeNotif_notInOverflow_notIntercepted() {
|
public void removeBubble_notIntercepted() {
|
||||||
// Get bubble with notif in shade.
|
mEntryListener.onEntryAdded(mRow);
|
||||||
mEntryListener.onPendingEntryAdded(mRow);
|
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
mBubbleController.updateBubble(mBubbleEntry);
|
||||||
|
|
||||||
assertTrue(mBubbleController.hasBubbles());
|
assertTrue(mBubbleController.hasBubbles());
|
||||||
assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry);
|
assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry);
|
||||||
|
|
||||||
mBubbleController.removeBubble(
|
// Dismiss the bubble
|
||||||
mRow.getKey(), Bubbles.DISMISS_NO_LONGER_BUBBLE);
|
mBubbleController.removeBubble(mRow.getKey(), Bubbles.DISMISS_NOTIF_CANCEL);
|
||||||
assertFalse(mBubbleController.hasBubbles());
|
assertFalse(mBubbleController.hasBubbles());
|
||||||
|
|
||||||
boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
|
// Dismiss the notification
|
||||||
mRow.getKey(), mRow, REASON_CANCEL);
|
boolean intercepted = mBubblesManager.handleDismissalInterception(mRow);
|
||||||
|
|
||||||
// Notif is no longer a bubble, so we should not intercept removal.
|
// Not a bubble anymore so we don't intercept dismissal.
|
||||||
assertFalse(intercepted);
|
assertFalse(intercepted);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testOverflowBubble_maxReached_notInShade_bubbleRemoved() {
|
|
||||||
mBubbleController.updateBubble(
|
|
||||||
mBubbleEntry, /* suppressFlyout */ false, /* showInShade */ false);
|
|
||||||
mBubbleController.updateBubble(
|
|
||||||
mBubbleEntry2, /* suppressFlyout */ false, /* showInShade */ false);
|
|
||||||
mBubbleController.updateBubble(
|
|
||||||
mBubbleEntry3, /* suppressFlyout */ false, /* showInShade */ false);
|
|
||||||
when(mCommonNotifCollection.getEntry(mRow.getKey())).thenReturn(mRow);
|
|
||||||
when(mCommonNotifCollection.getEntry(mRow2.getKey())).thenReturn(mRow2);
|
|
||||||
when(mCommonNotifCollection.getEntry(mRow3.getKey())).thenReturn(mRow3);
|
|
||||||
assertEquals(mBubbleData.getBubbles().size(), 3);
|
|
||||||
|
|
||||||
mBubbleData.setMaxOverflowBubbles(1);
|
|
||||||
mBubbleController.removeBubble(
|
|
||||||
mRow.getKey(), Bubbles.DISMISS_USER_GESTURE);
|
|
||||||
assertEquals(mBubbleData.getBubbles().size(), 2);
|
|
||||||
assertEquals(mBubbleData.getOverflowBubbles().size(), 1);
|
|
||||||
|
|
||||||
mBubbleController.removeBubble(
|
|
||||||
mRow2.getKey(), Bubbles.DISMISS_USER_GESTURE);
|
|
||||||
// Overflow max of 1 is reached; mRow is oldest, so it gets removed
|
|
||||||
verify(mNotificationEntryManager, times(1)).performRemoveNotification(
|
|
||||||
eq(mRow.getSbn()), any(), eq(REASON_CANCEL));
|
|
||||||
assertEquals(mBubbleData.getBubbles().size(), 1);
|
|
||||||
assertEquals(mBubbleData.getOverflowBubbles().size(), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNotifyShadeSuppressionChange_notificationDismiss() {
|
public void testNotifyShadeSuppressionChange_notificationDismiss() {
|
||||||
mEntryListener.onPendingEntryAdded(mRow);
|
mEntryListener.onEntryAdded(mRow);
|
||||||
|
|
||||||
assertTrue(mBubbleController.hasBubbles());
|
assertTrue(mBubbleController.hasBubbles());
|
||||||
assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry);
|
assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry);
|
||||||
|
|
||||||
mRemoveInterceptor.onNotificationRemoveRequested(
|
mBubblesManager.handleDismissalInterception(mRow);
|
||||||
mRow.getKey(), mRow, REASON_CANCEL);
|
|
||||||
|
|
||||||
// Should update show in shade state
|
// Should update show in shade state
|
||||||
assertBubbleNotificationSuppressedFromShade(mBubbleEntry);
|
assertBubbleNotificationSuppressedFromShade(mBubbleEntry);
|
||||||
@@ -1022,7 +890,7 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNotifyShadeSuppressionChange_bubbleExpanded() {
|
public void testNotifyShadeSuppressionChange_bubbleExpanded() {
|
||||||
mEntryListener.onPendingEntryAdded(mRow);
|
mEntryListener.onEntryAdded(mRow);
|
||||||
|
|
||||||
assertTrue(mBubbleController.hasBubbles());
|
assertTrue(mBubbleController.hasBubbles());
|
||||||
assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry);
|
assertBubbleNotificationNotSuppressedFromShade(mBubbleEntry);
|
||||||
@@ -1042,9 +910,9 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
// GIVEN a group summary with a bubble child
|
// GIVEN a group summary with a bubble child
|
||||||
ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(0);
|
ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(0);
|
||||||
ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup();
|
ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup();
|
||||||
|
mEntryListener.onEntryAdded(groupedBubble.getEntry());
|
||||||
when(mCommonNotifCollection.getEntry(groupedBubble.getEntry().getKey()))
|
when(mCommonNotifCollection.getEntry(groupedBubble.getEntry().getKey()))
|
||||||
.thenReturn(groupedBubble.getEntry());
|
.thenReturn(groupedBubble.getEntry());
|
||||||
mEntryListener.onPendingEntryAdded(groupedBubble.getEntry());
|
|
||||||
groupSummary.addChildNotification(groupedBubble);
|
groupSummary.addChildNotification(groupedBubble);
|
||||||
assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey()));
|
assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey()));
|
||||||
|
|
||||||
@@ -1054,10 +922,10 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
// THEN the summary and bubbled child are suppressed from the shade
|
// THEN the summary and bubbled child are suppressed from the shade
|
||||||
assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
|
assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
|
||||||
groupedBubble.getEntry().getKey(),
|
groupedBubble.getEntry().getKey(),
|
||||||
groupSummary.getEntry().getSbn().getGroupKey()));
|
groupedBubble.getEntry().getSbn().getGroupKey()));
|
||||||
assertTrue(mBubbleController.getImplCachedState().isBubbleNotificationSuppressedFromShade(
|
assertTrue(mBubbleController.getImplCachedState().isBubbleNotificationSuppressedFromShade(
|
||||||
groupedBubble.getEntry().getKey(),
|
groupedBubble.getEntry().getKey(),
|
||||||
groupSummary.getEntry().getSbn().getGroupKey()));
|
groupedBubble.getEntry().getSbn().getGroupKey()));
|
||||||
assertTrue(mBubbleData.isSummarySuppressed(groupSummary.getEntry().getSbn().getGroupKey()));
|
assertTrue(mBubbleData.isSummarySuppressed(groupSummary.getEntry().getSbn().getGroupKey()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1066,7 +934,7 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
// GIVEN a group summary with a bubble child
|
// GIVEN a group summary with a bubble child
|
||||||
ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(0);
|
ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(0);
|
||||||
ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup();
|
ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup();
|
||||||
mEntryListener.onPendingEntryAdded(groupedBubble.getEntry());
|
mEntryListener.onEntryAdded(groupedBubble.getEntry());
|
||||||
when(mCommonNotifCollection.getEntry(groupedBubble.getEntry().getKey()))
|
when(mCommonNotifCollection.getEntry(groupedBubble.getEntry().getKey()))
|
||||||
.thenReturn(groupedBubble.getEntry());
|
.thenReturn(groupedBubble.getEntry());
|
||||||
groupSummary.addChildNotification(groupedBubble);
|
groupSummary.addChildNotification(groupedBubble);
|
||||||
@@ -1076,7 +944,7 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
mBubblesManager.handleDismissalInterception(groupSummary.getEntry());
|
mBubblesManager.handleDismissalInterception(groupSummary.getEntry());
|
||||||
|
|
||||||
// WHEN the summary is cancelled by the app
|
// WHEN the summary is cancelled by the app
|
||||||
mEntryListener.onEntryRemoved(groupSummary.getEntry(), null, false, REASON_APP_CANCEL);
|
mEntryListener.onEntryRemoved(groupSummary.getEntry(), REASON_APP_CANCEL);
|
||||||
|
|
||||||
// THEN the summary and its children are removed from bubble data
|
// THEN the summary and its children are removed from bubble data
|
||||||
assertFalse(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey()));
|
assertFalse(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey()));
|
||||||
@@ -1085,14 +953,14 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSummaryDismissal_marksBubblesHiddenFromShadeAndDismissesNonBubbledChildren()
|
public void testSummaryDismissalMarksBubblesHiddenFromShadeAndDismissesNonBubbledChildren()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
// GIVEN a group summary with two (non-bubble) children and one bubble child
|
// GIVEN a group summary with two (non-bubble) children and one bubble child
|
||||||
ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(2);
|
ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(2);
|
||||||
ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup();
|
ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup();
|
||||||
|
mEntryListener.onEntryAdded(groupedBubble.getEntry());
|
||||||
when(mCommonNotifCollection.getEntry(groupedBubble.getEntry().getKey()))
|
when(mCommonNotifCollection.getEntry(groupedBubble.getEntry().getKey()))
|
||||||
.thenReturn(groupedBubble.getEntry());
|
.thenReturn(groupedBubble.getEntry());
|
||||||
mEntryListener.onPendingEntryAdded(groupedBubble.getEntry());
|
|
||||||
groupSummary.addChildNotification(groupedBubble);
|
groupSummary.addChildNotification(groupedBubble);
|
||||||
|
|
||||||
// WHEN the summary is dismissed
|
// WHEN the summary is dismissed
|
||||||
@@ -1100,16 +968,15 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
|
|
||||||
// THEN only the NON-bubble children are dismissed
|
// THEN only the NON-bubble children are dismissed
|
||||||
List<ExpandableNotificationRow> childrenRows = groupSummary.getAttachedChildren();
|
List<ExpandableNotificationRow> childrenRows = groupSummary.getAttachedChildren();
|
||||||
verify(mNotificationEntryManager, times(1)).performRemoveNotification(
|
verify(mNotifCallback, times(1)).removeNotification(
|
||||||
eq(childrenRows.get(0).getEntry().getSbn()), any(),
|
eq(childrenRows.get(0).getEntry()), any(), eq(REASON_GROUP_SUMMARY_CANCELED));
|
||||||
eq(REASON_GROUP_SUMMARY_CANCELED));
|
verify(mNotifCallback, times(1)).removeNotification(
|
||||||
verify(mNotificationEntryManager, times(1)).performRemoveNotification(
|
eq(childrenRows.get(1).getEntry()), any(), eq(REASON_GROUP_SUMMARY_CANCELED));
|
||||||
eq(childrenRows.get(1).getEntry().getSbn()), any(),
|
verify(mNotifCallback, never()).removeNotification(eq(groupedBubble.getEntry()),
|
||||||
eq(REASON_GROUP_SUMMARY_CANCELED));
|
any(), anyInt());
|
||||||
verify(mNotificationEntryManager, never()).performRemoveNotification(
|
|
||||||
eq(groupedBubble.getEntry().getSbn()), any(), anyInt());
|
|
||||||
|
|
||||||
// THEN the bubble child is suppressed from the shade
|
// THEN the bubble child still exists as a bubble and is suppressed from the shade
|
||||||
|
assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey()));
|
||||||
assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
|
assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
|
||||||
groupedBubble.getEntry().getKey(),
|
groupedBubble.getEntry().getKey(),
|
||||||
groupedBubble.getEntry().getSbn().getGroupKey()));
|
groupedBubble.getEntry().getSbn().getGroupKey()));
|
||||||
@@ -1117,33 +984,16 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
groupedBubble.getEntry().getKey(),
|
groupedBubble.getEntry().getKey(),
|
||||||
groupedBubble.getEntry().getSbn().getGroupKey()));
|
groupedBubble.getEntry().getSbn().getGroupKey()));
|
||||||
|
|
||||||
// THEN the summary is removed from GroupManager
|
// THEN the summary is also suppressed from the shade
|
||||||
verify(mNotificationGroupManager, times(1)).onEntryRemoved(groupSummary.getEntry());
|
assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
|
||||||
|
groupSummary.getEntry().getKey(),
|
||||||
|
groupSummary.getEntry().getSbn().getGroupKey()));
|
||||||
|
assertTrue(mBubbleController.getImplCachedState().isBubbleNotificationSuppressedFromShade(
|
||||||
|
groupSummary.getEntry().getKey(),
|
||||||
|
groupSummary.getEntry().getSbn().getGroupKey()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verifies that when a non visually interruptive update occurs for a bubble in the overflow,
|
|
||||||
* the that bubble does not get promoted from the overflow.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void test_notVisuallyInterruptive_updateOverflowBubble_notAdded() {
|
|
||||||
// Setup
|
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
|
||||||
mBubbleController.updateBubble(mBubbleEntry2);
|
|
||||||
assertTrue(mBubbleController.hasBubbles());
|
|
||||||
|
|
||||||
// Overflow it
|
|
||||||
mBubbleData.dismissBubbleWithKey(mRow.getKey(),
|
|
||||||
Bubbles.DISMISS_USER_GESTURE);
|
|
||||||
assertThat(mBubbleData.hasBubbleInStackWithKey(mRow.getKey())).isFalse();
|
|
||||||
assertThat(mBubbleData.hasOverflowBubbleWithKey(mRow.getKey())).isTrue();
|
|
||||||
|
|
||||||
// Test
|
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
|
||||||
assertThat(mBubbleData.hasBubbleInStackWithKey(mRow.getKey())).isFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies that when the user changes, the bubbles in the overflow list is cleared. Doesn't
|
* Verifies that when the user changes, the bubbles in the overflow list is cleared. Doesn't
|
||||||
* test the loading from the repository which would be a nice thing to add.
|
* test the loading from the repository which would be a nice thing to add.
|
||||||
@@ -1185,15 +1035,17 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testOverflowLoadedOnce() {
|
public void testOverflowLoadedOnce() {
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
// XXX
|
||||||
mBubbleController.updateBubble(mBubbleEntry2);
|
when(mCommonNotifCollection.getEntry(mRow.getKey())).thenReturn(mRow);
|
||||||
mBubbleData.dismissAll(Bubbles.DISMISS_USER_GESTURE);
|
when(mCommonNotifCollection.getEntry(mRow2.getKey())).thenReturn(mRow2);
|
||||||
assertThat(mBubbleData.getOverflowBubbles().isEmpty()).isFalse();
|
|
||||||
|
|
||||||
mBubbleController.updateBubble(mBubbleEntry);
|
mEntryListener.onEntryAdded(mRow);
|
||||||
mBubbleController.updateBubble(mBubbleEntry2);
|
mEntryListener.onEntryAdded(mRow2);
|
||||||
mBubbleController.removeBubble(mBubbleEntry.getKey(), DISMISS_NOTIF_CANCEL);
|
mBubbleData.dismissAll(Bubbles.DISMISS_USER_GESTURE);
|
||||||
mBubbleController.removeBubble(mBubbleEntry2.getKey(), DISMISS_NOTIF_CANCEL);
|
assertThat(mBubbleData.getOverflowBubbles()).isNotEmpty();
|
||||||
|
|
||||||
|
mEntryListener.onEntryRemoved(mRow, REASON_APP_CANCEL);
|
||||||
|
mEntryListener.onEntryRemoved(mRow2, REASON_APP_CANCEL);
|
||||||
assertThat(mBubbleData.getOverflowBubbles()).isEmpty();
|
assertThat(mBubbleData.getOverflowBubbles()).isEmpty();
|
||||||
|
|
||||||
verify(mDataRepository, times(1)).loadBubbles(anyInt(), any());
|
verify(mDataRepository, times(1)).loadBubbles(anyInt(), any());
|
||||||
@@ -1376,6 +1228,7 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
assertStackCollapsed();
|
assertStackCollapsed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRegisterUnregisterBroadcastListener() {
|
public void testRegisterUnregisterBroadcastListener() {
|
||||||
spyOn(mContext);
|
spyOn(mContext);
|
||||||
@@ -1455,7 +1308,7 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSetShouldAutoExpand_notifiesFlagChanged() {
|
public void testSetShouldAutoExpand_notifiesFlagChanged() {
|
||||||
mEntryListener.onPendingEntryAdded(mRow);
|
mBubbleController.updateBubble(mBubbleEntry);
|
||||||
|
|
||||||
assertTrue(mBubbleController.hasBubbles());
|
assertTrue(mBubbleController.hasBubbles());
|
||||||
Bubble b = mBubbleData.getBubbleInStackWithKey(mBubbleEntry.getKey());
|
Bubble b = mBubbleData.getBubbleInStackWithKey(mBubbleEntry.getKey());
|
||||||
@@ -1551,7 +1404,7 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the bubble metadata flags for this entry. These ]flags are normally set by
|
* Sets the bubble metadata flags for this entry. These flags are normally set by
|
||||||
* NotificationManagerService when the notification is sent, however, these tests do not
|
* NotificationManagerService when the notification is sent, however, these tests do not
|
||||||
* go through that path so we set them explicitly when testing.
|
* go through that path so we set them explicitly when testing.
|
||||||
*/
|
*/
|
||||||
@@ -1570,12 +1423,15 @@ public class BubblesTest extends SysuiTestCase {
|
|||||||
private Notification.BubbleMetadata getMetadata() {
|
private Notification.BubbleMetadata getMetadata() {
|
||||||
Intent target = new Intent(mContext, BubblesTestActivity.class);
|
Intent target = new Intent(mContext, BubblesTestActivity.class);
|
||||||
PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, target, FLAG_MUTABLE);
|
PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, target, FLAG_MUTABLE);
|
||||||
|
return new Notification.BubbleMetadata.Builder(
|
||||||
return new Notification.BubbleMetadata.Builder(bubbleIntent,
|
bubbleIntent,
|
||||||
Icon.createWithResource(mContext, R.drawable.bubble_ic_create_bubble))
|
Icon.createWithResource(
|
||||||
|
mContext,
|
||||||
|
com.android.wm.shell.R.drawable.bubble_ic_create_bubble))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asserts that the bubble stack is expanded and also validates the cached state is updated.
|
* Asserts that the bubble stack is expanded and also validates the cached state is updated.
|
||||||
*/
|
*/
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user