Merge changes from topic "b204183781_notif_vis_provider_master"
* changes: New Pipeline: Update NotificationLogger to use NotifPipeline New Pipeline: LockscreenUserManager now uses the CommonNotifCollection for queries New Pipeline: Add a NotificationVisibilityProvider to support both pipelines
This commit is contained in:
committed by
Android (Google) Code Review
commit
8c6945bd8b
@@ -60,6 +60,7 @@ 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.NotificationRowBinderImpl;
|
||||
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
|
||||
import com.android.systemui.statusbar.notification.people.PeopleHubModule;
|
||||
import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent;
|
||||
@@ -206,7 +207,9 @@ public abstract class SystemUIModule {
|
||||
NotificationShadeWindowController notificationShadeWindowController,
|
||||
StatusBarStateController statusBarStateController, ShadeController shadeController,
|
||||
ConfigurationController configurationController,
|
||||
@Nullable IStatusBarService statusBarService, INotificationManager notificationManager,
|
||||
@Nullable IStatusBarService statusBarService,
|
||||
INotificationManager notificationManager,
|
||||
NotificationVisibilityProvider visibilityProvider,
|
||||
NotificationInterruptStateProvider interruptionStateProvider,
|
||||
ZenModeController zenModeController, NotificationLockscreenUserManager notifUserManager,
|
||||
NotificationGroupManagerLegacy groupManager, NotificationEntryManager entryManager,
|
||||
@@ -215,6 +218,7 @@ public abstract class SystemUIModule {
|
||||
return Optional.ofNullable(BubblesManager.create(context, bubblesOptional,
|
||||
notificationShadeWindowController, statusBarStateController, shadeController,
|
||||
configurationController, statusBarService, notificationManager,
|
||||
visibilityProvider,
|
||||
interruptionStateProvider, zenModeController, notifUserManager,
|
||||
groupManager, entryManager, notifPipeline, sysUiState, featureFlags, dumpManager,
|
||||
sysuiMainExecutor));
|
||||
|
||||
@@ -36,8 +36,9 @@ import com.android.internal.statusbar.IStatusBarService;
|
||||
import com.android.internal.statusbar.NotificationVisibility;
|
||||
import com.android.systemui.people.PeopleSpaceUtils;
|
||||
import com.android.systemui.statusbar.CommandQueue;
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.wmshell.BubblesManager;
|
||||
import com.android.wm.shell.bubbles.Bubble;
|
||||
|
||||
@@ -50,7 +51,8 @@ public class LaunchConversationActivity extends Activity {
|
||||
private static final String TAG = "PeopleSpaceLaunchConv";
|
||||
private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;
|
||||
private UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
|
||||
private NotificationEntryManager mNotificationEntryManager;
|
||||
private NotificationVisibilityProvider mVisibilityProvider;
|
||||
private CommonNotifCollection mCommonNotifCollection;
|
||||
private final Optional<BubblesManager> mBubblesManagerOptional;
|
||||
private final UserManager mUserManager;
|
||||
private boolean mIsForTesting;
|
||||
@@ -60,11 +62,16 @@ public class LaunchConversationActivity extends Activity {
|
||||
private NotificationEntry mEntryToBubble;
|
||||
|
||||
@Inject
|
||||
public LaunchConversationActivity(NotificationEntryManager notificationEntryManager,
|
||||
Optional<BubblesManager> bubblesManagerOptional, UserManager userManager,
|
||||
CommandQueue commandQueue) {
|
||||
public LaunchConversationActivity(
|
||||
NotificationVisibilityProvider visibilityProvider,
|
||||
CommonNotifCollection commonNotifCollection,
|
||||
Optional<BubblesManager> bubblesManagerOptional,
|
||||
UserManager userManager,
|
||||
CommandQueue commandQueue
|
||||
) {
|
||||
super();
|
||||
mNotificationEntryManager = notificationEntryManager;
|
||||
mVisibilityProvider = visibilityProvider;
|
||||
mCommonNotifCollection = commonNotifCollection;
|
||||
mBubblesManagerOptional = bubblesManagerOptional;
|
||||
mUserManager = userManager;
|
||||
mCommandQueue = commandQueue;
|
||||
@@ -128,8 +135,7 @@ public class LaunchConversationActivity extends Activity {
|
||||
// shortcutId, fallback to notificationKey if it exists.
|
||||
if (mBubblesManagerOptional.isPresent()) {
|
||||
mBubble = mBubblesManagerOptional.get().getBubbleWithShortcutId(tileId);
|
||||
NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif(
|
||||
notificationKey);
|
||||
NotificationEntry entry = mCommonNotifCollection.getEntry(notificationKey);
|
||||
if (mBubble != null || (entry != null && entry.canBubble())) {
|
||||
mEntryToBubble = entry;
|
||||
if (DEBUG) {
|
||||
@@ -167,14 +173,14 @@ public class LaunchConversationActivity extends Activity {
|
||||
}
|
||||
|
||||
try {
|
||||
if (mIStatusBarService == null || mNotificationEntryManager == null) {
|
||||
if (mIStatusBarService == null || mCommonNotifCollection == null) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Skipping clear notification: null services, key: " + notifKey);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif(notifKey);
|
||||
NotificationEntry entry = mCommonNotifCollection.getEntry(notifKey);
|
||||
if (entry == null || entry.getRanking() == null) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Skipping clear notification: NotificationEntry or its Ranking"
|
||||
@@ -183,10 +189,8 @@ public class LaunchConversationActivity extends Activity {
|
||||
return;
|
||||
}
|
||||
|
||||
int count = mNotificationEntryManager.getActiveNotificationsCount();
|
||||
int rank = entry.getRanking().getRank();
|
||||
NotificationVisibility notifVisibility = NotificationVisibility.obtain(notifKey,
|
||||
rank, count, true);
|
||||
NotificationVisibility notifVisibility = mVisibilityProvider.obtain(entry, true);
|
||||
int rank = notifVisibility.rank;
|
||||
|
||||
if (DEBUG) Log.d(TAG, "Clearing notification, key: " + notifKey + ", rank: " + rank);
|
||||
mIStatusBarService.onNotificationClear(
|
||||
|
||||
@@ -56,7 +56,8 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController.StateList
|
||||
import com.android.systemui.recents.OverviewProxyService;
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
|
||||
@@ -67,6 +68,8 @@ import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.Lazy;
|
||||
|
||||
/**
|
||||
* Handles keeping track of the current user, profiles, and various things related to hiding
|
||||
* contents, redacting notifications, and the lockscreen.
|
||||
@@ -86,6 +89,8 @@ public class NotificationLockscreenUserManagerImpl implements
|
||||
// Lazy
|
||||
private NotificationEntryManager mEntryManager;
|
||||
|
||||
private final Lazy<NotificationVisibilityProvider> mVisibilityProviderLazy;
|
||||
private final Lazy<CommonNotifCollection> mCommonNotifCollectionLazy;
|
||||
private final DevicePolicyManager mDevicePolicyManager;
|
||||
private final SparseBooleanArray mLockscreenPublicMode = new SparseBooleanArray();
|
||||
private final SparseBooleanArray mUsersWithSeperateWorkChallenge = new SparseBooleanArray();
|
||||
@@ -162,15 +167,8 @@ public class NotificationLockscreenUserManagerImpl implements
|
||||
}
|
||||
}
|
||||
if (notificationKey != null) {
|
||||
NotificationEntry entry =
|
||||
getEntryManager().getActiveNotificationUnfiltered(notificationKey);
|
||||
final int count = getEntryManager().getActiveNotificationsCount();
|
||||
final int rank = entry != null ? entry.getRanking().getRank() : 0;
|
||||
NotificationVisibility.NotificationLocation location =
|
||||
NotificationLogger.getNotificationLocation(entry);
|
||||
final NotificationVisibility nv = NotificationVisibility.obtain(
|
||||
notificationKey,
|
||||
rank, count, true, location);
|
||||
final NotificationVisibility nv = mVisibilityProviderLazy.get()
|
||||
.obtain(notificationKey, true);
|
||||
mClickNotifier.onNotificationClick(notificationKey, nv);
|
||||
}
|
||||
break;
|
||||
@@ -200,6 +198,8 @@ public class NotificationLockscreenUserManagerImpl implements
|
||||
BroadcastDispatcher broadcastDispatcher,
|
||||
DevicePolicyManager devicePolicyManager,
|
||||
UserManager userManager,
|
||||
Lazy<NotificationVisibilityProvider> visibilityProviderLazy,
|
||||
Lazy<CommonNotifCollection> commonNotifCollectionLazy,
|
||||
NotificationClickNotifier clickNotifier,
|
||||
KeyguardManager keyguardManager,
|
||||
StatusBarStateController statusBarStateController,
|
||||
@@ -212,6 +212,8 @@ public class NotificationLockscreenUserManagerImpl implements
|
||||
mDevicePolicyManager = devicePolicyManager;
|
||||
mUserManager = userManager;
|
||||
mCurrentUserId = ActivityManager.getCurrentUser();
|
||||
mVisibilityProviderLazy = visibilityProviderLazy;
|
||||
mCommonNotifCollectionLazy = commonNotifCollectionLazy;
|
||||
mClickNotifier = clickNotifier;
|
||||
statusBarStateController.addCallback(this);
|
||||
mLockPatternUtils = new LockPatternUtils(context);
|
||||
@@ -337,18 +339,18 @@ public class NotificationLockscreenUserManagerImpl implements
|
||||
* package-specific override.
|
||||
*/
|
||||
public boolean shouldHideNotifications(String key) {
|
||||
if (getEntryManager() == null) {
|
||||
Log.wtf(TAG, "mEntryManager was null!", new Throwable());
|
||||
if (mCommonNotifCollectionLazy.get() == null) {
|
||||
Log.wtf(TAG, "mCommonNotifCollectionLazy was null!", new Throwable());
|
||||
return true;
|
||||
}
|
||||
NotificationEntry visibleEntry = getEntryManager().getActiveNotificationUnfiltered(key);
|
||||
NotificationEntry visibleEntry = mCommonNotifCollectionLazy.get().getEntry(key);
|
||||
return isLockscreenPublicMode(mCurrentUserId) && visibleEntry != null
|
||||
&& visibleEntry.getRanking().getLockscreenVisibilityOverride() == VISIBILITY_SECRET;
|
||||
}
|
||||
|
||||
public boolean shouldShowOnKeyguard(NotificationEntry entry) {
|
||||
if (getEntryManager() == null) {
|
||||
Log.wtf(TAG, "mEntryManager was null!", new Throwable());
|
||||
if (mCommonNotifCollectionLazy.get() == null) {
|
||||
Log.wtf(TAG, "mCommonNotifCollectionLazy was null!", new Throwable());
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < mKeyguardSuppressors.size(); i++) {
|
||||
@@ -520,11 +522,11 @@ public class NotificationLockscreenUserManagerImpl implements
|
||||
}
|
||||
|
||||
private boolean packageHasVisibilityOverride(String key) {
|
||||
if (getEntryManager() == null) {
|
||||
if (mCommonNotifCollectionLazy.get() == null) {
|
||||
Log.wtf(TAG, "mEntryManager was null!", new Throwable());
|
||||
return true;
|
||||
}
|
||||
NotificationEntry entry = getEntryManager().getActiveNotificationUnfiltered(key);
|
||||
NotificationEntry entry = mCommonNotifCollectionLazy.get().getEntry(key);
|
||||
return entry != null
|
||||
&& entry.getRanking().getLockscreenVisibilityOverride()
|
||||
== Notification.VISIBILITY_PRIVATE;
|
||||
|
||||
@@ -66,7 +66,7 @@ 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.logging.NotificationLogger;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.statusbar.phone.BiometricUnlockController;
|
||||
import com.android.systemui.statusbar.phone.KeyguardBypassController;
|
||||
import com.android.systemui.statusbar.phone.LockscreenWallpaper;
|
||||
@@ -113,6 +113,7 @@ public class NotificationMediaManager implements Dumpable {
|
||||
PAUSED_MEDIA_STATES.add(PlaybackState.STATE_CONNECTING);
|
||||
}
|
||||
|
||||
private final NotificationVisibilityProvider mVisibilityProvider;
|
||||
private final NotificationEntryManager mEntryManager;
|
||||
private final MediaDataManager mMediaDataManager;
|
||||
private final NotifPipeline mNotifPipeline;
|
||||
@@ -181,6 +182,7 @@ public class NotificationMediaManager implements Dumpable {
|
||||
Context context,
|
||||
Lazy<Optional<StatusBar>> statusBarOptionalLazy,
|
||||
Lazy<NotificationShadeWindowController> notificationShadeWindowController,
|
||||
NotificationVisibilityProvider visibilityProvider,
|
||||
NotificationEntryManager notificationEntryManager,
|
||||
MediaArtworkProcessor mediaArtworkProcessor,
|
||||
KeyguardBypassController keyguardBypassController,
|
||||
@@ -201,6 +203,7 @@ public class NotificationMediaManager implements Dumpable {
|
||||
// TODO: use KeyguardStateController#isOccluded to remove this dependency
|
||||
mStatusBarOptionalLazy = statusBarOptionalLazy;
|
||||
mNotificationShadeWindowController = notificationShadeWindowController;
|
||||
mVisibilityProvider = visibilityProvider;
|
||||
mEntryManager = notificationEntryManager;
|
||||
mMainExecutor = mainExecutor;
|
||||
mMediaDataManager = mediaDataManager;
|
||||
@@ -351,21 +354,10 @@ public class NotificationMediaManager implements Dumpable {
|
||||
}
|
||||
|
||||
private DismissedByUserStats getDismissedByUserStats(NotificationEntry entry) {
|
||||
final int activeNotificationsCount;
|
||||
if (mUsingNotifPipeline) {
|
||||
activeNotificationsCount = mNotifPipeline.getShadeListCount();
|
||||
} else {
|
||||
activeNotificationsCount = mEntryManager.getActiveNotificationsCount();
|
||||
}
|
||||
return new DismissedByUserStats(
|
||||
NotificationStats.DISMISSAL_SHADE, // Add DISMISSAL_MEDIA?
|
||||
NotificationStats.DISMISS_SENTIMENT_NEUTRAL,
|
||||
NotificationVisibility.obtain(
|
||||
entry.getKey(),
|
||||
entry.getRanking().getRank(),
|
||||
activeNotificationsCount,
|
||||
/* visible= */ true,
|
||||
NotificationLogger.getNotificationLocation(entry)));
|
||||
mVisibilityProvider.obtain(entry, /* visible= */ true));
|
||||
}
|
||||
|
||||
private void removeEntry(NotificationEntry entry) {
|
||||
@@ -406,10 +398,7 @@ public class NotificationMediaManager implements Dumpable {
|
||||
return null;
|
||||
}
|
||||
if (mUsingNotifPipeline) {
|
||||
// TODO(b/169655596): Either add O(1) lookup, or cache this icon?
|
||||
return mNotifPipeline.getAllNotifs().stream()
|
||||
.filter(entry -> Objects.equals(entry.getKey(), mMediaNotificationKey))
|
||||
.findAny()
|
||||
return Optional.ofNullable(mNotifPipeline.getEntry(mMediaNotificationKey))
|
||||
.map(entry -> entry.getIcons().getShelfIcon())
|
||||
.map(StatusBarIconView::getSourceIcon)
|
||||
.orElse(null);
|
||||
|
||||
@@ -60,6 +60,7 @@ import com.android.systemui.statusbar.notification.NotificationEntryListener;
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry.EditedSuggestionInfo;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||
import com.android.systemui.statusbar.phone.StatusBar;
|
||||
@@ -95,6 +96,7 @@ public class NotificationRemoteInputManager implements Dumpable {
|
||||
// Dependencies:
|
||||
private final NotificationLockscreenUserManager mLockscreenUserManager;
|
||||
private final SmartReplyController mSmartReplyController;
|
||||
private final NotificationVisibilityProvider mVisibilityProvider;
|
||||
private final NotificationEntryManager mEntryManager;
|
||||
private final Handler mMainHandler;
|
||||
private final ActionClickLogger mLogger;
|
||||
@@ -202,14 +204,7 @@ public class NotificationRemoteInputManager implements Dumpable {
|
||||
ViewGroup actionGroup = (ViewGroup) parent;
|
||||
buttonIndex = actionGroup.indexOfChild(view);
|
||||
}
|
||||
// TODO(b/204183781): get this from the current pipeline
|
||||
final int count = mEntryManager.getActiveNotificationsCount();
|
||||
final int rank = entry.getRanking().getRank();
|
||||
|
||||
NotificationVisibility.NotificationLocation location =
|
||||
NotificationLogger.getNotificationLocation(entry);
|
||||
final NotificationVisibility nv =
|
||||
NotificationVisibility.obtain(key, rank, count, true, location);
|
||||
final NotificationVisibility nv = mVisibilityProvider.obtain(entry, true);
|
||||
mClickNotifier.onNotificationActionClick(key, buttonIndex, action, nv, false);
|
||||
}
|
||||
|
||||
@@ -263,6 +258,7 @@ public class NotificationRemoteInputManager implements Dumpable {
|
||||
FeatureFlags featureFlags,
|
||||
NotificationLockscreenUserManager lockscreenUserManager,
|
||||
SmartReplyController smartReplyController,
|
||||
NotificationVisibilityProvider visibilityProvider,
|
||||
NotificationEntryManager notificationEntryManager,
|
||||
RemoteInputNotificationRebuilder rebuilder,
|
||||
Lazy<Optional<StatusBar>> statusBarOptionalLazy,
|
||||
@@ -276,6 +272,7 @@ public class NotificationRemoteInputManager implements Dumpable {
|
||||
mFeatureFlags = featureFlags;
|
||||
mLockscreenUserManager = lockscreenUserManager;
|
||||
mSmartReplyController = smartReplyController;
|
||||
mVisibilityProvider = visibilityProvider;
|
||||
mEntryManager = notificationEntryManager;
|
||||
mStatusBarOptionalLazy = statusBarOptionalLazy;
|
||||
mMainHandler = mainHandler;
|
||||
|
||||
@@ -26,9 +26,8 @@ import com.android.internal.statusbar.NotificationVisibility;
|
||||
import com.android.systemui.Dumpable;
|
||||
import com.android.systemui.dump.DumpManager;
|
||||
import com.android.systemui.statusbar.dagger.StatusBarModule;
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
@@ -40,7 +39,7 @@ import java.util.Set;
|
||||
*/
|
||||
public class SmartReplyController implements Dumpable {
|
||||
private final IStatusBarService mBarService;
|
||||
private final NotificationEntryManager mEntryManager;
|
||||
private final NotificationVisibilityProvider mVisibilityProvider;
|
||||
private final NotificationClickNotifier mClickNotifier;
|
||||
private final Set<String> mSendingKeys = new ArraySet<>();
|
||||
private Callback mCallback;
|
||||
@@ -50,11 +49,11 @@ public class SmartReplyController implements Dumpable {
|
||||
*/
|
||||
public SmartReplyController(
|
||||
DumpManager dumpManager,
|
||||
NotificationEntryManager entryManager,
|
||||
NotificationVisibilityProvider visibilityProvider,
|
||||
IStatusBarService statusBarService,
|
||||
NotificationClickNotifier clickNotifier) {
|
||||
mBarService = statusBarService;
|
||||
mEntryManager = entryManager;
|
||||
mVisibilityProvider = visibilityProvider;
|
||||
mClickNotifier = clickNotifier;
|
||||
dumpManager.registerDumpable(this);
|
||||
}
|
||||
@@ -84,13 +83,7 @@ public class SmartReplyController implements Dumpable {
|
||||
public void smartActionClicked(
|
||||
NotificationEntry entry, int actionIndex, Notification.Action action,
|
||||
boolean generatedByAssistant) {
|
||||
// TODO(b/204183781): get this from the current pipeline
|
||||
final int count = mEntryManager.getActiveNotificationsCount();
|
||||
final int rank = entry.getRanking().getRank();
|
||||
NotificationVisibility.NotificationLocation location =
|
||||
NotificationLogger.getNotificationLocation(entry);
|
||||
final NotificationVisibility nv = NotificationVisibility.obtain(
|
||||
entry.getKey(), rank, count, true, location);
|
||||
final NotificationVisibility nv = mVisibilityProvider.obtain(entry, true);
|
||||
mClickNotifier.onNotificationActionClick(
|
||||
entry.getKey(), actionIndex, action, nv, generatedByAssistant);
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ import com.android.systemui.statusbar.notification.collection.inflation.LowPrior
|
||||
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
|
||||
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.statusbar.notification.stack.ForegroundServiceSectionController;
|
||||
import com.android.systemui.statusbar.phone.KeyguardBypassController;
|
||||
import com.android.systemui.statusbar.phone.ManagedProfileController;
|
||||
@@ -102,6 +103,7 @@ public interface StatusBarDependenciesModule {
|
||||
FeatureFlags featureFlags,
|
||||
NotificationLockscreenUserManager lockscreenUserManager,
|
||||
SmartReplyController smartReplyController,
|
||||
NotificationVisibilityProvider visibilityProvider,
|
||||
NotificationEntryManager notificationEntryManager,
|
||||
RemoteInputNotificationRebuilder rebuilder,
|
||||
Lazy<Optional<StatusBar>> statusBarOptionalLazy,
|
||||
@@ -116,6 +118,7 @@ public interface StatusBarDependenciesModule {
|
||||
featureFlags,
|
||||
lockscreenUserManager,
|
||||
smartReplyController,
|
||||
visibilityProvider,
|
||||
notificationEntryManager,
|
||||
rebuilder,
|
||||
statusBarOptionalLazy,
|
||||
@@ -134,6 +137,7 @@ public interface StatusBarDependenciesModule {
|
||||
Context context,
|
||||
Lazy<Optional<StatusBar>> statusBarOptionalLazy,
|
||||
Lazy<NotificationShadeWindowController> notificationShadeWindowController,
|
||||
NotificationVisibilityProvider visibilityProvider,
|
||||
NotificationEntryManager notificationEntryManager,
|
||||
MediaArtworkProcessor mediaArtworkProcessor,
|
||||
KeyguardBypassController keyguardBypassController,
|
||||
@@ -147,6 +151,7 @@ public interface StatusBarDependenciesModule {
|
||||
context,
|
||||
statusBarOptionalLazy,
|
||||
notificationShadeWindowController,
|
||||
visibilityProvider,
|
||||
notificationEntryManager,
|
||||
mediaArtworkProcessor,
|
||||
keyguardBypassController,
|
||||
@@ -174,10 +179,14 @@ public interface StatusBarDependenciesModule {
|
||||
@Provides
|
||||
static SmartReplyController provideSmartReplyController(
|
||||
DumpManager dumpManager,
|
||||
NotificationEntryManager entryManager,
|
||||
NotificationVisibilityProvider visibilityProvider,
|
||||
IStatusBarService statusBarService,
|
||||
NotificationClickNotifier clickNotifier) {
|
||||
return new SmartReplyController(dumpManager, entryManager, statusBarService, clickNotifier);
|
||||
return new SmartReplyController(
|
||||
dumpManager,
|
||||
visibilityProvider,
|
||||
statusBarService,
|
||||
clickNotifier);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -721,8 +721,12 @@ public class NotificationEntryManager implements
|
||||
* @param reason why the notifications are updating
|
||||
*/
|
||||
public void updateNotifications(String reason) {
|
||||
if (mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
|
||||
mLogger.logUseWhileNewPipelineActive("updateNotifications", reason);
|
||||
return;
|
||||
}
|
||||
reapplyFilterAndSort(reason);
|
||||
if (mPresenter != null && !mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
|
||||
if (mPresenter != null) {
|
||||
mPresenter.updateNotificationViews(reason);
|
||||
}
|
||||
}
|
||||
@@ -808,11 +812,11 @@ public class NotificationEntryManager implements
|
||||
* notification doesn't exist.
|
||||
*/
|
||||
public NotificationEntry getPendingOrActiveNotif(String key) {
|
||||
if (mPendingNotifications.containsKey(key)) {
|
||||
return mPendingNotifications.get(key);
|
||||
} else {
|
||||
return mActiveNotifications.get(key);
|
||||
NotificationEntry entry = mPendingNotifications.get(key);
|
||||
if (entry != null) {
|
||||
return entry;
|
||||
}
|
||||
return mActiveNotifications.get(key);
|
||||
}
|
||||
|
||||
private void extendLifetime(NotificationEntry entry, NotificationLifetimeExtender extender) {
|
||||
@@ -880,11 +884,19 @@ public class NotificationEntryManager implements
|
||||
|
||||
/** Resorts / filters the current notification set with the current RankingMap */
|
||||
public void reapplyFilterAndSort(String reason) {
|
||||
if (mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
|
||||
mLogger.logUseWhileNewPipelineActive("reapplyFilterAndSort", reason);
|
||||
return;
|
||||
}
|
||||
updateRankingAndSort(mRanker.getRankingMap(), reason);
|
||||
}
|
||||
|
||||
/** Calls to NotificationRankingManager and updates mSortedAndFiltered */
|
||||
private void updateRankingAndSort(@NonNull RankingMap rankingMap, String reason) {
|
||||
if (mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
|
||||
mLogger.logUseWhileNewPipelineActive("updateRankingAndSort", reason);
|
||||
return;
|
||||
}
|
||||
mSortedAndFiltered.clear();
|
||||
mSortedAndFiltered.addAll(mRanker.updateRanking(
|
||||
rankingMap, mActiveNotifications.values(), reason));
|
||||
@@ -892,7 +904,7 @@ public class NotificationEntryManager implements
|
||||
|
||||
/** dump the current active notification list. Called from StatusBar */
|
||||
public void dump(PrintWriter pw, String indent) {
|
||||
pw.println("NotificationEntryManager");
|
||||
pw.println("NotificationEntryManager (Legacy)");
|
||||
int filteredLen = mSortedAndFiltered.size();
|
||||
pw.print(indent);
|
||||
pw.println("active notifications: " + filteredLen);
|
||||
@@ -946,6 +958,12 @@ public class NotificationEntryManager implements
|
||||
return mReadOnlyAllNotifications;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public NotificationEntry getEntry(String key) {
|
||||
return getPendingOrActiveNotif(key);
|
||||
}
|
||||
|
||||
/** @return A count of the active notifications */
|
||||
public int getActiveNotificationsCount() {
|
||||
return mReadOnlyNotifications.size();
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.notification
|
||||
import com.android.systemui.log.LogBuffer
|
||||
import com.android.systemui.log.LogLevel.DEBUG
|
||||
import com.android.systemui.log.LogLevel.INFO
|
||||
import com.android.systemui.log.LogLevel.WARNING
|
||||
import com.android.systemui.log.dagger.NotificationLog
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -95,6 +96,15 @@ class NotificationEntryManagerLogger @Inject constructor(
|
||||
"FILTER AND SORT reason=$str1"
|
||||
})
|
||||
}
|
||||
|
||||
fun logUseWhileNewPipelineActive(method: String, reason: String) {
|
||||
buffer.log(TAG, WARNING, {
|
||||
str1 = method
|
||||
str2 = reason
|
||||
}, {
|
||||
"While running New Pipeline: $str1(reason=$str2)"
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private const val TAG = "NotificationEntryMgr"
|
||||
@@ -13,34 +13,25 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.systemui.statusbar.notification.collection
|
||||
|
||||
package com.android.systemui.statusbar.notification.collection;
|
||||
|
||||
import android.os.Handler;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeFinalizeFilterListener;
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener;
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeSortListener;
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeTransformGroupsListener;
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Invalidator;
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifComparator;
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifStabilityManager;
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.InternalNotifUpdater;
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifDismissInterceptor;
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeFinalizeFilterListener
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeSortListener
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeTransformGroupsListener
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Invalidator
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifComparator
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifStabilityManager
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.InternalNotifUpdater
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifDismissInterceptor
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* The system that constructs the "shade list", the filtered, grouped, and sorted list of
|
||||
@@ -52,42 +43,33 @@ import javax.inject.Inject;
|
||||
* This list differs from the canonical one we receive from system server in a few ways:
|
||||
* - Filtered: Some notifications are filtered out. For example, we filter out notifications whose
|
||||
* views haven't been inflated yet. We also filter out some notifications if we're on the lock
|
||||
* screen and notifications for other users. So participate, see
|
||||
* {@link #addPreGroupFilter} and similar methods.
|
||||
* screen and notifications for other users. To participate, see
|
||||
* [.addPreGroupFilter] and similar methods.
|
||||
* - Grouped: Notifications that are part of the same group are clustered together into a single
|
||||
* GroupEntry. These groups are then transformed in order to remove children or completely split
|
||||
* them apart. To participate, see {@link #addPromoter}.
|
||||
* them apart. To participate, see [.addPromoter].
|
||||
* - Sorted: All top-level notifications are sorted. To participate, see
|
||||
* {@link #setSections} and {@link #setComparators}
|
||||
* [.setSections] and [.setComparators]
|
||||
*
|
||||
* The exact order of all hooks is as follows:
|
||||
* 0. Collection listeners are fired ({@link #addCollectionListener}).
|
||||
* 1. Pre-group filters are fired on each notification ({@link #addPreGroupFilter}).
|
||||
* 0. Collection listeners are fired ([.addCollectionListener]).
|
||||
* 1. Pre-group filters are fired on each notification ([.addPreGroupFilter]).
|
||||
* 2. Initial grouping is performed (NotificationEntries will have their parents set
|
||||
* appropriately).
|
||||
* 3. OnBeforeTransformGroupListeners are fired ({@link #addOnBeforeTransformGroupsListener})
|
||||
* 4. NotifPromoters are called on each notification with a parent ({@link #addPromoter})
|
||||
* 5. OnBeforeSortListeners are fired ({@link #addOnBeforeSortListener})
|
||||
* 6. Top-level entries are assigned sections by NotifSections ({@link #setSections})
|
||||
* 7. Top-level entries within the same section are sorted by NotifComparators
|
||||
* ({@link #setComparators})
|
||||
* 8. Finalize filters are fired on each notification ({@link #addFinalizeFilter})
|
||||
* 9. OnBeforeRenderListListeners are fired ({@link #addOnBeforeRenderListListener})
|
||||
* 9. The list is handed off to the view layer to be rendered
|
||||
* 3. OnBeforeTransformGroupListeners are fired ([.addOnBeforeTransformGroupsListener])
|
||||
* 4. NotifPromoters are called on each notification with a parent ([.addPromoter])
|
||||
* 5. Finalize filters are fired on each notification ([.addFinalizeFilter])
|
||||
* 6. OnBeforeSortListeners are fired ([.addOnBeforeSortListener])
|
||||
* 7. Top-level entries are assigned sections by NotifSections ([.setSections])
|
||||
* 8. Top-level entries within the same section are sorted by NotifComparators ([.setComparators])
|
||||
* 9. OnBeforeRenderListListeners are fired ([.addOnBeforeRenderListListener])
|
||||
* 10. The list is handed off to the view layer to be rendered
|
||||
*/
|
||||
@SysUISingleton
|
||||
public class NotifPipeline implements CommonNotifCollection {
|
||||
private final NotifCollection mNotifCollection;
|
||||
private final ShadeListBuilder mShadeListBuilder;
|
||||
|
||||
@Inject
|
||||
public NotifPipeline(
|
||||
NotifCollection notifCollection,
|
||||
ShadeListBuilder shadeListBuilder) {
|
||||
mNotifCollection = notifCollection;
|
||||
mShadeListBuilder = shadeListBuilder;
|
||||
}
|
||||
|
||||
class NotifPipeline @Inject constructor(
|
||||
private val mNotifCollection: NotifCollection,
|
||||
private val mShadeListBuilder: ShadeListBuilder
|
||||
) : CommonNotifCollection {
|
||||
/**
|
||||
* Returns the list of all known notifications, i.e. the notifications that are currently posted
|
||||
* to the phone. In general, this tracks closely to the list maintained by NotificationManager,
|
||||
@@ -95,38 +77,35 @@ public class NotifPipeline implements CommonNotifCollection {
|
||||
*
|
||||
* The returned collection is read-only, unsorted, unfiltered, and ungrouped.
|
||||
*/
|
||||
@Override
|
||||
public Collection<NotificationEntry> getAllNotifs() {
|
||||
return mNotifCollection.getAllNotifs();
|
||||
override fun getAllNotifs(): Collection<NotificationEntry> {
|
||||
return mNotifCollection.allNotifs
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCollectionListener(NotifCollectionListener listener) {
|
||||
mNotifCollection.addCollectionListener(listener);
|
||||
override fun addCollectionListener(listener: NotifCollectionListener) {
|
||||
mNotifCollection.addCollectionListener(listener)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the NotificationEntry associated with [key].
|
||||
*/
|
||||
@Nullable
|
||||
public NotificationEntry getEntry(String key) {
|
||||
return mNotifCollection.getEntry(key);
|
||||
override fun getEntry(key: String): NotificationEntry? {
|
||||
return mNotifCollection.getEntry(key)
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a lifetime extender. Lifetime extenders can cause notifications that have been
|
||||
* dismissed or retracted by system server to be temporarily retained in the collection.
|
||||
*/
|
||||
public void addNotificationLifetimeExtender(NotifLifetimeExtender extender) {
|
||||
mNotifCollection.addNotificationLifetimeExtender(extender);
|
||||
fun addNotificationLifetimeExtender(extender: NotifLifetimeExtender) {
|
||||
mNotifCollection.addNotificationLifetimeExtender(extender)
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a dismiss interceptor. Dismiss interceptors can cause notifications that have been
|
||||
* dismissed by the user to be retained (won't send a dismissal to system server).
|
||||
*/
|
||||
public void addNotificationDismissInterceptor(NotifDismissInterceptor interceptor) {
|
||||
mNotifCollection.addNotificationDismissInterceptor(interceptor);
|
||||
fun addNotificationDismissInterceptor(interceptor: NotifDismissInterceptor) {
|
||||
mNotifCollection.addNotificationDismissInterceptor(interceptor)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,16 +114,16 @@ public class NotifPipeline implements CommonNotifCollection {
|
||||
* returns true, the notification is removed from the pipeline (and no other filters are
|
||||
* called on that notif).
|
||||
*/
|
||||
public void addPreGroupFilter(NotifFilter filter) {
|
||||
mShadeListBuilder.addPreGroupFilter(filter);
|
||||
fun addPreGroupFilter(filter: NotifFilter) {
|
||||
mShadeListBuilder.addPreGroupFilter(filter)
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after notifications have been filtered and after the initial grouping has been
|
||||
* performed but before NotifPromoters have had a chance to promote children out of groups.
|
||||
*/
|
||||
public void addOnBeforeTransformGroupsListener(OnBeforeTransformGroupsListener listener) {
|
||||
mShadeListBuilder.addOnBeforeTransformGroupsListener(listener);
|
||||
fun addOnBeforeTransformGroupsListener(listener: OnBeforeTransformGroupsListener) {
|
||||
mShadeListBuilder.addOnBeforeTransformGroupsListener(listener)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -154,34 +133,34 @@ public class NotifPipeline implements CommonNotifCollection {
|
||||
* registered. If any promoter returns true, the notification is removed from the group (and no
|
||||
* other promoters are called on it).
|
||||
*/
|
||||
public void addPromoter(NotifPromoter promoter) {
|
||||
mShadeListBuilder.addPromoter(promoter);
|
||||
fun addPromoter(promoter: NotifPromoter) {
|
||||
mShadeListBuilder.addPromoter(promoter)
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after notifs have been filtered and groups have been determined but before sections
|
||||
* have been determined or the notifs have been sorted.
|
||||
*/
|
||||
public void addOnBeforeSortListener(OnBeforeSortListener listener) {
|
||||
mShadeListBuilder.addOnBeforeSortListener(listener);
|
||||
fun addOnBeforeSortListener(listener: OnBeforeSortListener) {
|
||||
mShadeListBuilder.addOnBeforeSortListener(listener)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sections that are used to sort top-level entries. If two entries have the same section,
|
||||
* NotifComparators are consulted. Sections from this list are called in order for each
|
||||
* notification passed through the pipeline. The first NotifSection to return true for
|
||||
* {@link NotifSectioner#isInSection(ListEntry)} sets the entry as part of its Section.
|
||||
* [NotifSectioner.isInSection] sets the entry as part of its Section.
|
||||
*/
|
||||
public void setSections(List<NotifSectioner> sections) {
|
||||
mShadeListBuilder.setSectioners(sections);
|
||||
fun setSections(sections: List<NotifSectioner>) {
|
||||
mShadeListBuilder.setSectioners(sections)
|
||||
}
|
||||
|
||||
/**
|
||||
* StabilityManager that is used to determine whether to suppress group and section changes.
|
||||
* This should only be set once.
|
||||
*/
|
||||
public void setVisualStabilityManager(NotifStabilityManager notifStabilityManager) {
|
||||
mShadeListBuilder.setNotifStabilityManager(notifStabilityManager);
|
||||
fun setVisualStabilityManager(notifStabilityManager: NotifStabilityManager) {
|
||||
mShadeListBuilder.setNotifStabilityManager(notifStabilityManager)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,16 +168,16 @@ public class NotifPipeline implements CommonNotifCollection {
|
||||
* comparators are executed in order until one of them returns a non-zero result. If all return
|
||||
* zero, the pipeline falls back to sorting by rank (and, failing that, Notification.when).
|
||||
*/
|
||||
public void setComparators(List<NotifComparator> comparators) {
|
||||
mShadeListBuilder.setComparators(comparators);
|
||||
fun setComparators(comparators: List<NotifComparator>) {
|
||||
mShadeListBuilder.setComparators(comparators)
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after notifs have been filtered once, grouped, and sorted but before the final
|
||||
* filtering.
|
||||
*/
|
||||
public void addOnBeforeFinalizeFilterListener(OnBeforeFinalizeFilterListener listener) {
|
||||
mShadeListBuilder.addOnBeforeFinalizeFilterListener(listener);
|
||||
fun addOnBeforeFinalizeFilterListener(listener: OnBeforeFinalizeFilterListener) {
|
||||
mShadeListBuilder.addOnBeforeFinalizeFilterListener(listener)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,21 +187,21 @@ public class NotifPipeline implements CommonNotifCollection {
|
||||
* true, the notification is removed from the pipeline (and no other filters are called on that
|
||||
* notif).
|
||||
*/
|
||||
public void addFinalizeFilter(NotifFilter filter) {
|
||||
mShadeListBuilder.addFinalizeFilter(filter);
|
||||
fun addFinalizeFilter(filter: NotifFilter) {
|
||||
mShadeListBuilder.addFinalizeFilter(filter)
|
||||
}
|
||||
|
||||
/**
|
||||
* Called at the end of the pipeline after the notif list has been finalized but before it has
|
||||
* been handed off to the view layer.
|
||||
*/
|
||||
public void addOnBeforeRenderListListener(OnBeforeRenderListListener listener) {
|
||||
mShadeListBuilder.addOnBeforeRenderListListener(listener);
|
||||
fun addOnBeforeRenderListListener(listener: OnBeforeRenderListListener) {
|
||||
mShadeListBuilder.addOnBeforeRenderListListener(listener)
|
||||
}
|
||||
|
||||
/** Registers an invalidator that can be used to invalidate the entire notif list. */
|
||||
public void addPreRenderInvalidator(Invalidator invalidator) {
|
||||
mShadeListBuilder.addPreRenderInvalidator(invalidator);
|
||||
fun addPreRenderInvalidator(invalidator: Invalidator) {
|
||||
mShadeListBuilder.addPreRenderInvalidator(invalidator)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -232,8 +211,8 @@ public class NotifPipeline implements CommonNotifCollection {
|
||||
* @param name the name of the component that will update notifiations
|
||||
* @return an updater
|
||||
*/
|
||||
public InternalNotifUpdater getInternalNotifUpdater(String name) {
|
||||
return mNotifCollection.getInternalNotifUpdater(name);
|
||||
fun getInternalNotifUpdater(name: String?): InternalNotifUpdater {
|
||||
return mNotifCollection.getInternalNotifUpdater(name)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -241,8 +220,20 @@ public class NotifPipeline implements CommonNotifCollection {
|
||||
* are currently present in the shade. If this method is called during pipeline execution it
|
||||
* will return the current state of the list, which will likely be only partially-generated.
|
||||
*/
|
||||
public List<ListEntry> getShadeList() {
|
||||
return mShadeListBuilder.getShadeList();
|
||||
val shadeList: List<ListEntry>
|
||||
get() = mShadeListBuilder.shadeList
|
||||
|
||||
/**
|
||||
* Constructs a flattened representation of the notification tree, where each group will have
|
||||
* the summary (if present) followed by the children.
|
||||
*/
|
||||
fun getFlatShadeList(): List<NotificationEntry> = shadeList.flatMap { entry ->
|
||||
when (entry) {
|
||||
is NotificationEntry -> sequenceOf(entry)
|
||||
is GroupEntry -> (entry.summary?.let { sequenceOf(it) }.orEmpty() +
|
||||
entry.children)
|
||||
else -> throw RuntimeException("Unexpected entry $entry")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -251,20 +242,9 @@ public class NotifPipeline implements CommonNotifCollection {
|
||||
* will return the number of notifications in its current state, which will likely be only
|
||||
* partially-generated.
|
||||
*/
|
||||
public int getShadeListCount() {
|
||||
final List<ListEntry> entries = getShadeList();
|
||||
int numNotifs = 0;
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
final ListEntry entry = entries.get(i);
|
||||
if (entry instanceof GroupEntry) {
|
||||
final GroupEntry parentEntry = (GroupEntry) entry;
|
||||
numNotifs++; // include the summary in the count
|
||||
numNotifs += parentEntry.getChildren().size();
|
||||
} else {
|
||||
numNotifs++;
|
||||
}
|
||||
}
|
||||
|
||||
return numNotifs;
|
||||
fun getShadeListCount(): Int = shadeList.sumOf { entry ->
|
||||
// include the summary in the count
|
||||
if (entry is GroupEntry) 1 + entry.children.size
|
||||
else 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,7 +134,7 @@ public class BubbleCoordinator implements Coordinator {
|
||||
mInterceptedDismissalEntries.remove(entry.getKey());
|
||||
mOnEndDismissInterception.onEndDismissInterception(mDismissInterceptor, entry,
|
||||
dismissedByUserStats);
|
||||
} else if (mNotifPipeline.getAllNotifs().contains(entry)) {
|
||||
} else if (mNotifPipeline.getEntry(entry.getKey()) != null) {
|
||||
// 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
|
||||
|
||||
@@ -23,15 +23,13 @@ import android.os.SystemClock;
|
||||
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.coordinator.VisualStabilityCoordinator;
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
|
||||
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
|
||||
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
|
||||
import com.android.systemui.statusbar.policy.HeadsUpManager;
|
||||
|
||||
@@ -40,7 +38,7 @@ import com.android.systemui.statusbar.policy.HeadsUpManager;
|
||||
* information about the interaction to the notification pipeline.
|
||||
*/
|
||||
public class OnUserInteractionCallbackImpl implements OnUserInteractionCallback {
|
||||
private final NotifPipeline mNotifPipeline;
|
||||
private final NotificationVisibilityProvider mVisibilityProvider;
|
||||
private final NotifCollection mNotifCollection;
|
||||
private final HeadsUpManager mHeadsUpManager;
|
||||
private final StatusBarStateController mStatusBarStateController;
|
||||
@@ -48,14 +46,14 @@ public class OnUserInteractionCallbackImpl implements OnUserInteractionCallback
|
||||
private final GroupMembershipManager mGroupMembershipManager;
|
||||
|
||||
public OnUserInteractionCallbackImpl(
|
||||
NotifPipeline notifPipeline,
|
||||
NotificationVisibilityProvider visibilityProvider,
|
||||
NotifCollection notifCollection,
|
||||
HeadsUpManager headsUpManager,
|
||||
StatusBarStateController statusBarStateController,
|
||||
VisualStabilityCoordinator visualStabilityCoordinator,
|
||||
GroupMembershipManager groupMembershipManager
|
||||
) {
|
||||
mNotifPipeline = notifPipeline;
|
||||
mVisibilityProvider = visibilityProvider;
|
||||
mNotifCollection = notifCollection;
|
||||
mHeadsUpManager = headsUpManager;
|
||||
mStatusBarStateController = statusBarStateController;
|
||||
@@ -91,12 +89,7 @@ public class OnUserInteractionCallbackImpl implements OnUserInteractionCallback
|
||||
new DismissedByUserStats(
|
||||
dismissalSurface,
|
||||
DISMISS_SENTIMENT_NEUTRAL,
|
||||
NotificationVisibility.obtain(
|
||||
entry.getKey(),
|
||||
entry.getRanking().getRank(),
|
||||
mNotifPipeline.getShadeListCount(),
|
||||
true,
|
||||
NotificationLogger.getNotificationLocation(entry)))
|
||||
mVisibilityProvider.obtain(entry, true))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.notification.collection.legacy
|
||||
|
||||
import com.android.internal.statusbar.NotificationVisibility
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider
|
||||
import com.android.systemui.statusbar.notification.logging.NotificationLogger
|
||||
import javax.inject.Inject
|
||||
|
||||
/** Legacy pipeline implementation for getting [NotificationVisibility]. */
|
||||
class LegacyNotificationVisibilityProvider @Inject constructor(
|
||||
private val notifEntryManager: NotificationEntryManager
|
||||
) : NotificationVisibilityProvider {
|
||||
override fun obtain(entry: NotificationEntry, visible: Boolean): NotificationVisibility {
|
||||
val count: Int = notifEntryManager.activeNotificationsCount
|
||||
val rank = entry.ranking.rank
|
||||
val hasRow = entry.row != null
|
||||
val location = NotificationLogger.getNotificationLocation(entry)
|
||||
return NotificationVisibility.obtain(entry.key, rank, count, visible && hasRow, location)
|
||||
}
|
||||
|
||||
override fun obtain(key: String, visible: Boolean): NotificationVisibility {
|
||||
val entry: NotificationEntry? = notifEntryManager.getActiveNotificationUnfiltered(key)
|
||||
val count: Int = notifEntryManager.activeNotificationsCount
|
||||
val rank = entry?.ranking?.rank ?: -1
|
||||
val hasRow = entry?.row != null
|
||||
val location = NotificationLogger.getNotificationLocation(entry)
|
||||
return NotificationVisibility.obtain(key, rank, count, visible && hasRow, location)
|
||||
}
|
||||
|
||||
override fun getLocation(key: String): NotificationVisibility.NotificationLocation =
|
||||
NotificationLogger.getNotificationLocation(
|
||||
notifEntryManager.getActiveNotificationUnfiltered(key))
|
||||
}
|
||||
@@ -22,13 +22,12 @@ import android.annotation.Nullable;
|
||||
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.collection.render.GroupMembershipManager;
|
||||
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
|
||||
import com.android.systemui.statusbar.policy.HeadsUpManager;
|
||||
|
||||
@@ -37,6 +36,7 @@ import com.android.systemui.statusbar.policy.HeadsUpManager;
|
||||
*/
|
||||
public class OnUserInteractionCallbackImplLegacy implements OnUserInteractionCallback {
|
||||
private final NotificationEntryManager mNotificationEntryManager;
|
||||
private final NotificationVisibilityProvider mVisibilityProvider;
|
||||
private final HeadsUpManager mHeadsUpManager;
|
||||
private final StatusBarStateController mStatusBarStateController;
|
||||
private final VisualStabilityManager mVisualStabilityManager;
|
||||
@@ -44,12 +44,14 @@ public class OnUserInteractionCallbackImplLegacy implements OnUserInteractionCal
|
||||
|
||||
public OnUserInteractionCallbackImplLegacy(
|
||||
NotificationEntryManager notificationEntryManager,
|
||||
NotificationVisibilityProvider visibilityProvider,
|
||||
HeadsUpManager headsUpManager,
|
||||
StatusBarStateController statusBarStateController,
|
||||
VisualStabilityManager visualStabilityManager,
|
||||
GroupMembershipManager groupMembershipManager
|
||||
) {
|
||||
mNotificationEntryManager = notificationEntryManager;
|
||||
mVisibilityProvider = visibilityProvider;
|
||||
mHeadsUpManager = headsUpManager;
|
||||
mStatusBarStateController = statusBarStateController;
|
||||
mVisualStabilityManager = visualStabilityManager;
|
||||
@@ -88,12 +90,7 @@ public class OnUserInteractionCallbackImplLegacy implements OnUserInteractionCal
|
||||
new DismissedByUserStats(
|
||||
dismissalSurface,
|
||||
DISMISS_SENTIMENT_NEUTRAL,
|
||||
NotificationVisibility.obtain(
|
||||
entry.getKey(),
|
||||
entry.getRanking().getRank(),
|
||||
mNotificationEntryManager.getActiveNotificationsCount(),
|
||||
true,
|
||||
NotificationLogger.getNotificationLocation(entry))),
|
||||
mVisibilityProvider.obtain(entry, true)),
|
||||
cancellationReason
|
||||
);
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.systemui.statusbar.notification.collection.notifcollection;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
@@ -45,4 +47,10 @@ public interface CommonNotifCollection {
|
||||
* The returned collection is read-only, unsorted, unfiltered, and ungrouped.
|
||||
*/
|
||||
Collection<NotificationEntry> getAllNotifs();
|
||||
|
||||
/**
|
||||
* Returns the notification entry for the given notification key;
|
||||
* the returned entry (if present) may be in any state.
|
||||
*/
|
||||
@Nullable NotificationEntry getEntry(String key);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.notification.collection.render
|
||||
|
||||
import com.android.internal.statusbar.NotificationVisibility
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
||||
|
||||
/**
|
||||
* An interface for getting the current [NotificationVisibility] object for a notification.
|
||||
*/
|
||||
interface NotificationVisibilityProvider {
|
||||
/** Given a notification entry, return the visibility object */
|
||||
fun obtain(entry: NotificationEntry, visible: Boolean): NotificationVisibility
|
||||
/** Given a notification key, return the visibility object */
|
||||
fun obtain(key: String, visible: Boolean): NotificationVisibility
|
||||
/** Given a notification key, return the location */
|
||||
fun getLocation(key: String): NotificationVisibility.NotificationLocation
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.notification.collection.render
|
||||
|
||||
import com.android.internal.statusbar.NotificationVisibility
|
||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
||||
import com.android.systemui.statusbar.notification.logging.NotificationLogger
|
||||
import javax.inject.Inject
|
||||
|
||||
/** New pipeline implementation for getting [NotificationVisibility]. */
|
||||
class NotificationVisibilityProviderImpl @Inject constructor(
|
||||
private val notifPipeline: NotifPipeline
|
||||
) : NotificationVisibilityProvider {
|
||||
override fun obtain(entry: NotificationEntry, visible: Boolean): NotificationVisibility {
|
||||
val count: Int = notifPipeline.getShadeListCount()
|
||||
val rank = entry.ranking.rank
|
||||
val hasRow = entry.row != null
|
||||
val location = NotificationLogger.getNotificationLocation(entry)
|
||||
return NotificationVisibility.obtain(entry.key, rank, count, visible && hasRow, location)
|
||||
}
|
||||
|
||||
override fun obtain(key: String, visible: Boolean): NotificationVisibility =
|
||||
notifPipeline.getEntry(key)?.let { return obtain(it, visible) }
|
||||
?: NotificationVisibility.obtain(key, -1, notifPipeline.getShadeListCount(), false)
|
||||
|
||||
override fun getLocation(key: String): NotificationVisibility.NotificationLocation =
|
||||
NotificationLogger.getNotificationLocation(notifPipeline.getEntry(key))
|
||||
}
|
||||
@@ -52,6 +52,7 @@ import com.android.systemui.statusbar.notification.collection.inflation.NotifInf
|
||||
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
|
||||
import com.android.systemui.statusbar.notification.collection.inflation.OnUserInteractionCallbackImpl;
|
||||
import com.android.systemui.statusbar.notification.collection.legacy.LegacyNotificationPresenterExtensions;
|
||||
import com.android.systemui.statusbar.notification.collection.legacy.LegacyNotificationVisibilityProvider;
|
||||
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
|
||||
import com.android.systemui.statusbar.notification.collection.legacy.OnUserInteractionCallbackImplLegacy;
|
||||
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
|
||||
@@ -63,6 +64,8 @@ import com.android.systemui.statusbar.notification.collection.render.GroupMember
|
||||
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManagerImpl;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewManager;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProviderImpl;
|
||||
import com.android.systemui.statusbar.notification.init.NotificationsController;
|
||||
import com.android.systemui.statusbar.notification.init.NotificationsControllerImpl;
|
||||
import com.android.systemui.statusbar.notification.init.NotificationsControllerStub;
|
||||
@@ -208,14 +211,20 @@ public interface NotificationsModule {
|
||||
static NotificationLogger provideNotificationLogger(
|
||||
NotificationListener notificationListener,
|
||||
@UiBackground Executor uiBgExecutor,
|
||||
FeatureFlags featureFlags,
|
||||
NotificationVisibilityProvider visibilityProvider,
|
||||
NotificationEntryManager entryManager,
|
||||
NotifPipeline notifPipeline,
|
||||
StatusBarStateController statusBarStateController,
|
||||
NotificationLogger.ExpansionStateLogger expansionStateLogger,
|
||||
NotificationPanelLogger notificationPanelLogger) {
|
||||
return new NotificationLogger(
|
||||
notificationListener,
|
||||
uiBgExecutor,
|
||||
featureFlags,
|
||||
visibilityProvider,
|
||||
entryManager,
|
||||
notifPipeline,
|
||||
statusBarStateController,
|
||||
expansionStateLogger,
|
||||
notificationPanelLogger);
|
||||
@@ -277,6 +286,20 @@ public interface NotificationsModule {
|
||||
return featureFlags.isNewNotifPipelineRenderingEnabled() ? pipeline.get() : entryManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide the object which can be used to obtain NotificationVisibility objects.
|
||||
*/
|
||||
@Provides
|
||||
@SysUISingleton
|
||||
static NotificationVisibilityProvider provideNotificationVisibilityProvider(
|
||||
FeatureFlags featureFlags,
|
||||
Lazy<NotificationVisibilityProviderImpl> newProvider,
|
||||
Lazy<LegacyNotificationVisibilityProvider> legacyProvider) {
|
||||
return featureFlags.isNewNotifPipelineRenderingEnabled()
|
||||
? newProvider.get()
|
||||
: legacyProvider.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide the active implementation for presenting notifications.
|
||||
*/
|
||||
@@ -301,15 +324,15 @@ public interface NotificationsModule {
|
||||
FeatureFlags featureFlags,
|
||||
HeadsUpManager headsUpManager,
|
||||
StatusBarStateController statusBarStateController,
|
||||
Lazy<NotifPipeline> pipeline,
|
||||
Lazy<NotifCollection> notifCollection,
|
||||
Lazy<NotificationVisibilityProvider> visibilityProvider,
|
||||
Lazy<VisualStabilityCoordinator> visualStabilityCoordinator,
|
||||
NotificationEntryManager entryManager,
|
||||
VisualStabilityManager visualStabilityManager,
|
||||
Lazy<GroupMembershipManager> groupMembershipManagerLazy) {
|
||||
return featureFlags.isNewNotifPipelineRenderingEnabled()
|
||||
? new OnUserInteractionCallbackImpl(
|
||||
pipeline.get(),
|
||||
visibilityProvider.get(),
|
||||
notifCollection.get(),
|
||||
headsUpManager,
|
||||
statusBarStateController,
|
||||
@@ -317,6 +340,7 @@ public interface NotificationsModule {
|
||||
groupMembershipManagerLazy.get())
|
||||
: new OnUserInteractionCallbackImplLegacy(
|
||||
entryManager,
|
||||
visibilityProvider.get(),
|
||||
headsUpManager,
|
||||
statusBarStateController,
|
||||
visualStabilityManager,
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
@@ -33,13 +34,17 @@ import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.statusbar.IStatusBarService;
|
||||
import com.android.internal.statusbar.NotificationVisibility;
|
||||
import com.android.systemui.dagger.qualifiers.UiBackground;
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
|
||||
import com.android.systemui.statusbar.NotificationListener;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryListener;
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
|
||||
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
|
||||
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
|
||||
@@ -70,7 +75,10 @@ public class NotificationLogger implements StateListener {
|
||||
// Dependencies:
|
||||
private final NotificationListenerService mNotificationListener;
|
||||
private final Executor mUiBgExecutor;
|
||||
private final FeatureFlags mFeatureFlags;
|
||||
private final NotificationVisibilityProvider mVisibilityProvider;
|
||||
private final NotificationEntryManager mEntryManager;
|
||||
private final NotifPipeline mNotifPipeline;
|
||||
private final NotificationPanelLogger mNotificationPanelLogger;
|
||||
private final ExpansionStateLogger mExpansionStateLogger;
|
||||
|
||||
@@ -127,7 +135,7 @@ public class NotificationLogger implements StateListener {
|
||||
// notifications.
|
||||
// 3. Report newly visible and no-longer visible notifications.
|
||||
// 4. Keep currently visible notifications for next report.
|
||||
List<NotificationEntry> activeNotifications = mEntryManager.getVisibleNotifications();
|
||||
List<NotificationEntry> activeNotifications = getVisibleNotifications();
|
||||
int N = activeNotifications.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
NotificationEntry entry = activeNotifications.get(i);
|
||||
@@ -166,6 +174,14 @@ public class NotificationLogger implements StateListener {
|
||||
}
|
||||
};
|
||||
|
||||
private List<NotificationEntry> getVisibleNotifications() {
|
||||
if (mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
|
||||
return mNotifPipeline.getFlatShadeList();
|
||||
} else {
|
||||
return mEntryManager.getVisibleNotifications();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the location of the notification referenced by the given {@link NotificationEntry}.
|
||||
*/
|
||||
@@ -202,13 +218,19 @@ public class NotificationLogger implements StateListener {
|
||||
*/
|
||||
public NotificationLogger(NotificationListener notificationListener,
|
||||
@UiBackground Executor uiBgExecutor,
|
||||
FeatureFlags featureFlags,
|
||||
NotificationVisibilityProvider visibilityProvider,
|
||||
NotificationEntryManager entryManager,
|
||||
NotifPipeline notifPipeline,
|
||||
StatusBarStateController statusBarStateController,
|
||||
ExpansionStateLogger expansionStateLogger,
|
||||
NotificationPanelLogger notificationPanelLogger) {
|
||||
mNotificationListener = notificationListener;
|
||||
mUiBgExecutor = uiBgExecutor;
|
||||
mFeatureFlags = featureFlags;
|
||||
mVisibilityProvider = visibilityProvider;
|
||||
mEntryManager = entryManager;
|
||||
mNotifPipeline = notifPipeline;
|
||||
mBarService = IStatusBarService.Stub.asInterface(
|
||||
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
|
||||
mExpansionStateLogger = expansionStateLogger;
|
||||
@@ -216,7 +238,15 @@ public class NotificationLogger implements StateListener {
|
||||
// Not expected to be destroyed, don't need to unsubscribe
|
||||
statusBarStateController.addCallback(this);
|
||||
|
||||
entryManager.addNotificationEntryListener(new NotificationEntryListener() {
|
||||
if (mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
|
||||
registerNewPipelineListener();
|
||||
} else {
|
||||
registerLegacyListener();
|
||||
}
|
||||
}
|
||||
|
||||
private void registerLegacyListener() {
|
||||
mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
|
||||
@Override
|
||||
public void onEntryRemoved(
|
||||
NotificationEntry entry,
|
||||
@@ -240,6 +270,20 @@ public class NotificationLogger implements StateListener {
|
||||
});
|
||||
}
|
||||
|
||||
private void registerNewPipelineListener() {
|
||||
mNotifPipeline.addCollectionListener(new NotifCollectionListener() {
|
||||
@Override
|
||||
public void onEntryUpdated(@NonNull NotificationEntry entry, boolean fromSystem) {
|
||||
mExpansionStateLogger.onEntryUpdated(entry.getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEntryRemoved(@NonNull NotificationEntry entry, int reason) {
|
||||
mExpansionStateLogger.onEntryRemoved(entry.getKey());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setUpWithContainer(NotificationListContainer listContainer) {
|
||||
mListContainer = listContainer;
|
||||
}
|
||||
@@ -407,8 +451,7 @@ public class NotificationLogger implements StateListener {
|
||||
// Once we know panelExpanded and Dozing, turn logging on & off when appropriate
|
||||
boolean lockscreen = mLockscreen == null ? false : mLockscreen;
|
||||
if (mPanelExpanded && !mDozing) {
|
||||
mNotificationPanelLogger.logPanelShown(lockscreen,
|
||||
mEntryManager.getVisibleNotifications());
|
||||
mNotificationPanelLogger.logPanelShown(lockscreen, getVisibleNotifications());
|
||||
if (DEBUG) {
|
||||
Log.i(TAG, "Notification panel shown, lockscreen=" + lockscreen);
|
||||
}
|
||||
@@ -440,8 +483,7 @@ public class NotificationLogger implements StateListener {
|
||||
* Called when the notification is expanded / collapsed.
|
||||
*/
|
||||
public void onExpansionChanged(String key, boolean isUserAction, boolean isExpanded) {
|
||||
NotificationVisibility.NotificationLocation location =
|
||||
getNotificationLocation(mEntryManager.getActiveNotificationUnfiltered(key));
|
||||
NotificationVisibility.NotificationLocation location = mVisibilityProvider.getLocation(key);
|
||||
mExpansionStateLogger.onExpansionChanged(key, isUserAction, isExpanded, location);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,6 @@ import com.android.internal.logging.UiEvent;
|
||||
import com.android.internal.logging.UiEventLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.statusbar.IStatusBarService;
|
||||
import com.android.internal.statusbar.NotificationVisibility;
|
||||
import com.android.systemui.ExpandHelper;
|
||||
import com.android.systemui.Gefingerpoken;
|
||||
import com.android.systemui.R;
|
||||
@@ -99,6 +98,7 @@ import com.android.systemui.statusbar.notification.collection.legacy.VisualStabi
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
|
||||
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
|
||||
import com.android.systemui.statusbar.notification.dagger.SilentHeader;
|
||||
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
|
||||
@@ -145,6 +145,7 @@ public class NotificationStackScrollLayoutController {
|
||||
|
||||
private final boolean mAllowLongPress;
|
||||
private final NotificationGutsManager mNotificationGutsManager;
|
||||
private final NotificationVisibilityProvider mVisibilityProvider;
|
||||
private final HeadsUpManagerPhone mHeadsUpManager;
|
||||
private final NotificationRoundnessManager mNotificationRoundnessManager;
|
||||
private final TunerService mTunerService;
|
||||
@@ -618,6 +619,7 @@ public class NotificationStackScrollLayoutController {
|
||||
public NotificationStackScrollLayoutController(
|
||||
@Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowLongPress,
|
||||
NotificationGutsManager notificationGutsManager,
|
||||
NotificationVisibilityProvider visibilityProvider,
|
||||
HeadsUpManagerPhone headsUpManager,
|
||||
NotificationRoundnessManager notificationRoundnessManager,
|
||||
TunerService tunerService,
|
||||
@@ -655,6 +657,7 @@ public class NotificationStackScrollLayoutController {
|
||||
ShadeController shadeController) {
|
||||
mAllowLongPress = allowLongPress;
|
||||
mNotificationGutsManager = notificationGutsManager;
|
||||
mVisibilityProvider = visibilityProvider;
|
||||
mHeadsUpManager = headsUpManager;
|
||||
mNotificationRoundnessManager = notificationRoundnessManager;
|
||||
mTunerService = tunerService;
|
||||
@@ -1384,19 +1387,11 @@ public class NotificationStackScrollLayoutController {
|
||||
mView.resetCheckSnoozeLeavebehind();
|
||||
}
|
||||
|
||||
private DismissedByUserStats getDismissedByUserStats(
|
||||
NotificationEntry entry,
|
||||
int numVisibleEntries
|
||||
) {
|
||||
private DismissedByUserStats getDismissedByUserStats(NotificationEntry entry) {
|
||||
return new DismissedByUserStats(
|
||||
DISMISSAL_SHADE,
|
||||
DISMISS_SENTIMENT_NEUTRAL,
|
||||
NotificationVisibility.obtain(
|
||||
entry.getKey(),
|
||||
entry.getRanking().getRank(),
|
||||
numVisibleEntries,
|
||||
true,
|
||||
NotificationLogger.getNotificationLocation(entry)));
|
||||
mVisibilityProvider.obtain(entry, true));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1447,13 +1442,10 @@ public class NotificationStackScrollLayoutController {
|
||||
} else {
|
||||
final List<Pair<NotificationEntry, DismissedByUserStats>>
|
||||
entriesWithRowsDismissedFromShade = new ArrayList<>();
|
||||
final int numVisibleEntries = mNotifPipeline.getShadeListCount();
|
||||
for (ExpandableNotificationRow row : viewsToRemove) {
|
||||
final NotificationEntry entry = row.getEntry();
|
||||
entriesWithRowsDismissedFromShade.add(
|
||||
new Pair<>(
|
||||
entry,
|
||||
getDismissedByUserStats(entry, numVisibleEntries)));
|
||||
new Pair<>(entry, getDismissedByUserStats(entry)));
|
||||
}
|
||||
mNotifCollection.dismissNotifications(entriesWithRowsDismissedFromShade);
|
||||
}
|
||||
@@ -1462,9 +1454,7 @@ public class NotificationStackScrollLayoutController {
|
||||
if (canChildBeDismissed(rowToRemove)) {
|
||||
mNotificationEntryManager.performRemoveNotification(
|
||||
rowToRemove.getEntry().getSbn(),
|
||||
getDismissedByUserStats(
|
||||
rowToRemove.getEntry(),
|
||||
mNotificationEntryManager.getActiveNotificationsCount()),
|
||||
getDismissedByUserStats(rowToRemove.getEntry()),
|
||||
NotificationListenerService.REASON_CANCEL_ALL);
|
||||
} else {
|
||||
rowToRemove.resetTranslation();
|
||||
|
||||
@@ -68,8 +68,8 @@ import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
|
||||
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
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.ExpandableNotificationRowDragController;
|
||||
import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
|
||||
@@ -97,6 +97,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
|
||||
|
||||
private final NotificationEntryManager mEntryManager;
|
||||
private final NotifPipeline mNotifPipeline;
|
||||
private final NotificationVisibilityProvider mVisibilityProvider;
|
||||
private final HeadsUpManagerPhone mHeadsUpManager;
|
||||
private final ActivityStarter mActivityStarter;
|
||||
private final NotificationClickNotifier mClickNotifier;
|
||||
@@ -136,6 +137,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
|
||||
Executor uiBgExecutor,
|
||||
NotificationEntryManager entryManager,
|
||||
NotifPipeline notifPipeline,
|
||||
NotificationVisibilityProvider visibilityProvider,
|
||||
HeadsUpManagerPhone headsUpManager,
|
||||
ActivityStarter activityStarter,
|
||||
NotificationClickNotifier clickNotifier,
|
||||
@@ -171,6 +173,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
|
||||
mUiBgExecutor = uiBgExecutor;
|
||||
mEntryManager = entryManager;
|
||||
mNotifPipeline = notifPipeline;
|
||||
mVisibilityProvider = visibilityProvider;
|
||||
mHeadsUpManager = headsUpManager;
|
||||
mActivityStarter = activityStarter;
|
||||
mClickNotifier = clickNotifier;
|
||||
@@ -366,10 +369,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
|
||||
mAssistManagerLazy.get().hideAssist();
|
||||
}
|
||||
|
||||
NotificationVisibility.NotificationLocation location =
|
||||
NotificationLogger.getNotificationLocation(entry);
|
||||
final NotificationVisibility nv = NotificationVisibility.obtain(entry.getKey(),
|
||||
entry.getRanking().getRank(), getVisibleNotificationsCount(), true, location);
|
||||
final NotificationVisibility nv = mVisibilityProvider.obtain(entry, true);
|
||||
|
||||
// retrieve the group summary to remove with this entry before we tell NMS the
|
||||
// notification was clicked to avoid a race condition
|
||||
@@ -414,10 +414,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
|
||||
public void onDragSuccess(NotificationEntry entry) {
|
||||
// this method is not responsible for intent sending.
|
||||
// will focus follow operation only after drag-and-drop that notification.
|
||||
NotificationVisibility.NotificationLocation location =
|
||||
NotificationLogger.getNotificationLocation(entry);
|
||||
final NotificationVisibility nv = NotificationVisibility.obtain(entry.getKey(),
|
||||
entry.getRanking().getRank(), getVisibleNotificationsCount(), true, location);
|
||||
final NotificationVisibility nv = mVisibilityProvider.obtain(entry, true);
|
||||
|
||||
// retrieve the group summary to remove with this entry before we tell NMS the
|
||||
// notification was clicked to avoid a race condition
|
||||
@@ -681,6 +678,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
|
||||
private final Executor mUiBgExecutor;
|
||||
private final NotificationEntryManager mEntryManager;
|
||||
private final NotifPipeline mNotifPipeline;
|
||||
private final NotificationVisibilityProvider mVisibilityProvider;
|
||||
private final HeadsUpManagerPhone mHeadsUpManager;
|
||||
private final ActivityStarter mActivityStarter;
|
||||
private final NotificationClickNotifier mClickNotifier;
|
||||
@@ -719,6 +717,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
|
||||
@UiBackground Executor uiBgExecutor,
|
||||
NotificationEntryManager entryManager,
|
||||
NotifPipeline notifPipeline,
|
||||
NotificationVisibilityProvider visibilityProvider,
|
||||
HeadsUpManagerPhone headsUpManager,
|
||||
ActivityStarter activityStarter,
|
||||
NotificationClickNotifier clickNotifier,
|
||||
@@ -749,6 +748,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
|
||||
mUiBgExecutor = uiBgExecutor;
|
||||
mEntryManager = entryManager;
|
||||
mNotifPipeline = notifPipeline;
|
||||
mVisibilityProvider = visibilityProvider;
|
||||
mHeadsUpManager = headsUpManager;
|
||||
mActivityStarter = activityStarter;
|
||||
mClickNotifier = clickNotifier;
|
||||
@@ -813,6 +813,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
|
||||
mUiBgExecutor,
|
||||
mEntryManager,
|
||||
mNotifPipeline,
|
||||
mVisibilityProvider,
|
||||
mHeadsUpManager,
|
||||
mActivityStarter,
|
||||
mClickNotifier,
|
||||
|
||||
@@ -76,8 +76,8 @@ import com.android.systemui.statusbar.notification.collection.coordinator.Bubble
|
||||
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
|
||||
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
|
||||
import com.android.systemui.statusbar.phone.ShadeController;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.statusbar.policy.ZenModeController;
|
||||
@@ -109,6 +109,7 @@ public class BubblesManager implements Dumpable {
|
||||
private final ShadeController mShadeController;
|
||||
private final IStatusBarService mBarService;
|
||||
private final INotificationManager mNotificationManager;
|
||||
private final NotificationVisibilityProvider mVisibilityProvider;
|
||||
private final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
|
||||
private final NotificationGroupManagerLegacy mNotificationGroupManager;
|
||||
private final NotificationEntryManager mNotificationEntryManager;
|
||||
@@ -132,6 +133,7 @@ public class BubblesManager implements Dumpable {
|
||||
ConfigurationController configurationController,
|
||||
@Nullable IStatusBarService statusBarService,
|
||||
INotificationManager notificationManager,
|
||||
NotificationVisibilityProvider visibilityProvider,
|
||||
NotificationInterruptStateProvider interruptionStateProvider,
|
||||
ZenModeController zenModeController,
|
||||
NotificationLockscreenUserManager notifUserManager,
|
||||
@@ -146,6 +148,7 @@ public class BubblesManager implements Dumpable {
|
||||
return new BubblesManager(context, bubblesOptional.get(),
|
||||
notificationShadeWindowController, statusBarStateController, shadeController,
|
||||
configurationController, statusBarService, notificationManager,
|
||||
visibilityProvider,
|
||||
interruptionStateProvider, zenModeController, notifUserManager,
|
||||
groupManager, entryManager, notifPipeline, sysUiState, featureFlags,
|
||||
dumpManager, sysuiMainExecutor);
|
||||
@@ -163,6 +166,7 @@ public class BubblesManager implements Dumpable {
|
||||
ConfigurationController configurationController,
|
||||
@Nullable IStatusBarService statusBarService,
|
||||
INotificationManager notificationManager,
|
||||
NotificationVisibilityProvider visibilityProvider,
|
||||
NotificationInterruptStateProvider interruptionStateProvider,
|
||||
ZenModeController zenModeController,
|
||||
NotificationLockscreenUserManager notifUserManager,
|
||||
@@ -178,6 +182,7 @@ public class BubblesManager implements Dumpable {
|
||||
mNotificationShadeWindowController = notificationShadeWindowController;
|
||||
mShadeController = shadeController;
|
||||
mNotificationManager = notificationManager;
|
||||
mVisibilityProvider = visibilityProvider;
|
||||
mNotificationInterruptStateProvider = interruptionStateProvider;
|
||||
mNotificationGroupManager = groupManager;
|
||||
mNotificationEntryManager = entryManager;
|
||||
@@ -598,12 +603,7 @@ public class BubblesManager implements Dumpable {
|
||||
return new DismissedByUserStats(
|
||||
DISMISSAL_BUBBLE,
|
||||
DISMISS_SENTIMENT_NEUTRAL,
|
||||
NotificationVisibility.obtain(
|
||||
entry.getKey(),
|
||||
entry.getRanking().getRank(),
|
||||
mNotificationEntryManager.getActiveNotificationsCount(),
|
||||
isVisible,
|
||||
NotificationLogger.getNotificationLocation(entry)));
|
||||
mVisibilityProvider.obtain(entry, isVisible));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,7 +21,9 @@ import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
@@ -43,8 +45,9 @@ import com.android.internal.statusbar.IStatusBarService;
|
||||
import com.android.internal.statusbar.NotificationVisibility;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.statusbar.CommandQueue;
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.wmshell.BubblesManager;
|
||||
import com.android.wm.shell.bubbles.Bubble;
|
||||
|
||||
@@ -76,7 +79,9 @@ public class LaunchConversationActivityTest extends SysuiTestCase {
|
||||
private LaunchConversationActivity mActivity;
|
||||
|
||||
@Mock
|
||||
private NotificationEntryManager mNotificationEntryManager;
|
||||
private NotificationVisibilityProvider mVisibilityProvider;
|
||||
@Mock
|
||||
private CommonNotifCollection mNotifCollection;
|
||||
@Mock
|
||||
private IStatusBarService mIStatusBarService;
|
||||
@Mock
|
||||
@@ -104,8 +109,13 @@ public class LaunchConversationActivityTest extends SysuiTestCase {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mActivity = new LaunchConversationActivity(mNotificationEntryManager,
|
||||
Optional.of(mBubblesManager), mUserManager, mCommandQueue);
|
||||
mActivity = new LaunchConversationActivity(
|
||||
mVisibilityProvider,
|
||||
mNotifCollection,
|
||||
Optional.of(mBubblesManager),
|
||||
mUserManager,
|
||||
mCommandQueue
|
||||
);
|
||||
verify(mCommandQueue, times(1)).addCallback(mCallbacksCaptor.capture());
|
||||
|
||||
mActivity.setIsForTesting(true, mIStatusBarService);
|
||||
@@ -114,19 +124,26 @@ public class LaunchConversationActivityTest extends SysuiTestCase {
|
||||
mIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_PACKAGE_NAME, PACKAGE_NAME);
|
||||
mIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_USER_HANDLE, USER_HANDLE);
|
||||
|
||||
when(mNotificationEntryManager.getActiveNotificationsCount()).thenReturn(NOTIF_COUNT);
|
||||
when(mNotificationEntryManager.getPendingOrActiveNotif(NOTIF_KEY)).thenReturn(mNotifEntry);
|
||||
when(mNotificationEntryManager.getPendingOrActiveNotif(NOTIF_KEY_NO_ENTRY))
|
||||
.thenReturn(null);
|
||||
when(mNotificationEntryManager.getPendingOrActiveNotif(NOTIF_KEY_NO_RANKING))
|
||||
.thenReturn(mNotifEntryNoRanking);
|
||||
when(mNotificationEntryManager.getPendingOrActiveNotif(NOTIF_KEY_CAN_BUBBLE))
|
||||
.thenReturn(mNotifEntryCanBubble);
|
||||
when(mNotifCollection.getEntry(NOTIF_KEY)).thenReturn(mNotifEntry);
|
||||
when(mNotifCollection.getEntry(NOTIF_KEY_NO_ENTRY)).thenReturn(null);
|
||||
when(mNotifCollection.getEntry(NOTIF_KEY_NO_RANKING)).thenReturn(mNotifEntryNoRanking);
|
||||
when(mNotifCollection.getEntry(NOTIF_KEY_CAN_BUBBLE)).thenReturn(mNotifEntryCanBubble);
|
||||
when(mVisibilityProvider.obtain(anyString(), anyBoolean())).thenAnswer(
|
||||
invocation-> {
|
||||
String key = invocation.getArgument(0);
|
||||
boolean visible = invocation.getArgument(1);
|
||||
return NotificationVisibility.obtain(key, NOTIF_RANK, NOTIF_COUNT, visible);
|
||||
});
|
||||
when(mVisibilityProvider.obtain(any(NotificationEntry.class), anyBoolean())).thenAnswer(
|
||||
invocation-> {
|
||||
String key = invocation.<NotificationEntry>getArgument(0).getKey();
|
||||
boolean visible = invocation.getArgument(1);
|
||||
return NotificationVisibility.obtain(key, NOTIF_RANK, NOTIF_COUNT, visible);
|
||||
});
|
||||
when(mNotifEntry.getRanking()).thenReturn(mRanking);
|
||||
when(mNotifEntryCanBubble.getRanking()).thenReturn(mRanking);
|
||||
when(mNotifEntryCanBubble.canBubble()).thenReturn(true);
|
||||
when(mNotifEntryNoRanking.getRanking()).thenReturn(null);
|
||||
when(mRanking.getRank()).thenReturn(NOTIF_RANK);
|
||||
when(mUserManager.isQuietModeEnabled(any(UserHandle.class))).thenReturn(false);
|
||||
}
|
||||
|
||||
@@ -173,8 +190,12 @@ public class LaunchConversationActivityTest extends SysuiTestCase {
|
||||
assertThat(mActivity.isFinishing()).isTrue();
|
||||
mCallbacksCaptor.getValue().appTransitionFinished(DEFAULT_DISPLAY);
|
||||
|
||||
// Ensure callback removed
|
||||
verify(mCommandQueue).removeCallback(any());
|
||||
// Clear the notification for bubbles.
|
||||
verify(mIStatusBarService, times(1)).onNotificationClear(any(),
|
||||
anyInt(), any(), anyInt(), anyInt(), mNotificationVisibilityCaptor.capture());
|
||||
// Do not select the bubble.
|
||||
verify(mBubblesManager, never()).expandStackAndSelectBubble(any(Bubble.class));
|
||||
verify(mBubblesManager, never()).expandStackAndSelectBubble(any(NotificationEntry.class));
|
||||
|
||||
@@ -194,6 +215,8 @@ public class LaunchConversationActivityTest extends SysuiTestCase {
|
||||
assertThat(mActivity.isFinishing()).isTrue();
|
||||
mCallbacksCaptor.getValue().appTransitionFinished(DEFAULT_DISPLAY);
|
||||
|
||||
// Ensure callback removed
|
||||
verify(mCommandQueue).removeCallback(any());
|
||||
// Don't clear the notification for bubbles.
|
||||
verify(mIStatusBarService, never()).onNotificationClear(any(),
|
||||
anyInt(), any(), anyInt(), anyInt(), any());
|
||||
@@ -211,10 +234,14 @@ public class LaunchConversationActivityTest extends SysuiTestCase {
|
||||
mActivity.onCreate(new Bundle());
|
||||
|
||||
assertThat(mActivity.isFinishing()).isTrue();
|
||||
mCommandQueue.appTransitionFinished(DEFAULT_DISPLAY);
|
||||
mCallbacksCaptor.getValue().appTransitionFinished(DEFAULT_DISPLAY);
|
||||
|
||||
// Ensure callback removed
|
||||
verify(mCommandQueue).removeCallback(any());
|
||||
// Don't clear the notification for bubbles.
|
||||
verify(mIStatusBarService, never()).onNotificationClear(any(),
|
||||
anyInt(), any(), anyInt(), anyInt(), any());
|
||||
// Do not select the bubble.
|
||||
verify(mBubblesManager, never()).expandStackAndSelectBubble(any(Bubble.class));
|
||||
verify(mBubblesManager, never()).expandStackAndSelectBubble(any(NotificationEntry.class));
|
||||
}
|
||||
@@ -233,6 +260,9 @@ public class LaunchConversationActivityTest extends SysuiTestCase {
|
||||
assertThat(mActivity.isFinishing()).isTrue();
|
||||
mCallbacksCaptor.getValue().appTransitionFinished(DEFAULT_DISPLAY);
|
||||
|
||||
// Ensure callback removed
|
||||
verify(mCommandQueue).removeCallback(any());
|
||||
// Select the bubble.
|
||||
verify(mBubblesManager, times(1)).expandStackAndSelectBubble(eq(bubble));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,8 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManager.Keyguard
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
|
||||
@@ -84,8 +86,12 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
|
||||
|
||||
// Dependency mocks:
|
||||
@Mock
|
||||
private NotificationVisibilityProvider mVisibilityProvider;
|
||||
@Mock
|
||||
private NotificationEntryManager mEntryManager;
|
||||
@Mock
|
||||
private CommonNotifCollection mNotifCollection;
|
||||
@Mock
|
||||
private DevicePolicyManager mDevicePolicyManager;
|
||||
@Mock
|
||||
private NotificationClickNotifier mClickNotifier;
|
||||
@@ -419,6 +425,8 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
|
||||
mBroadcastDispatcher,
|
||||
mDevicePolicyManager,
|
||||
mUserManager,
|
||||
(() -> mVisibilityProvider),
|
||||
(() -> mNotifCollection),
|
||||
mClickNotifier,
|
||||
NotificationLockscreenUserManagerTest.this.mKeyguardManager,
|
||||
mStatusBarStateController,
|
||||
|
||||
@@ -47,6 +47,7 @@ import com.android.systemui.statusbar.NotificationRemoteInputManager.LegacyRemot
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||
import com.android.systemui.statusbar.phone.StatusBar;
|
||||
import com.android.systemui.statusbar.policy.RemoteInputUriController;
|
||||
@@ -70,7 +71,7 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase {
|
||||
private static final String TEST_PACKAGE_NAME = "test";
|
||||
private static final int TEST_UID = 0;
|
||||
|
||||
@Mock private NotificationPresenter mPresenter;
|
||||
@Mock private NotificationVisibilityProvider mVisibilityProvider;
|
||||
@Mock private RemoteInputController.Delegate mDelegate;
|
||||
@Mock private NotificationRemoteInputManager.Callback mCallback;
|
||||
@Mock private RemoteInputController mController;
|
||||
@@ -101,6 +102,7 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase {
|
||||
mock(FeatureFlags.class),
|
||||
mLockscreenUserManager,
|
||||
mSmartReplyController,
|
||||
mVisibilityProvider,
|
||||
mEntryManager,
|
||||
mock(RemoteInputNotificationRebuilder.class),
|
||||
() -> Optional.of(mock(StatusBar.class)),
|
||||
@@ -191,6 +193,7 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase {
|
||||
FeatureFlags featureFlags,
|
||||
NotificationLockscreenUserManager lockscreenUserManager,
|
||||
SmartReplyController smartReplyController,
|
||||
NotificationVisibilityProvider visibilityProvider,
|
||||
NotificationEntryManager notificationEntryManager,
|
||||
RemoteInputNotificationRebuilder rebuilder,
|
||||
Lazy<Optional<StatusBar>> statusBarOptionalLazy,
|
||||
@@ -205,6 +208,7 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase {
|
||||
featureFlags,
|
||||
lockscreenUserManager,
|
||||
smartReplyController,
|
||||
visibilityProvider,
|
||||
notificationEntryManager,
|
||||
rebuilder,
|
||||
statusBarOptionalLazy,
|
||||
|
||||
@@ -44,6 +44,7 @@ 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.NotificationEntryBuilder;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.statusbar.phone.StatusBar;
|
||||
import com.android.systemui.statusbar.policy.RemoteInputUriController;
|
||||
|
||||
@@ -71,7 +72,7 @@ public class SmartReplyControllerTest extends SysuiTestCase {
|
||||
private SmartReplyController mSmartReplyController;
|
||||
private NotificationRemoteInputManager mRemoteInputManager;
|
||||
|
||||
@Mock private NotificationPresenter mPresenter;
|
||||
@Mock private NotificationVisibilityProvider mVisibilityProvider;
|
||||
@Mock private RemoteInputController.Delegate mDelegate;
|
||||
@Mock private NotificationRemoteInputManager.Callback mCallback;
|
||||
@Mock private StatusBarNotification mSbn;
|
||||
@@ -89,7 +90,7 @@ public class SmartReplyControllerTest extends SysuiTestCase {
|
||||
|
||||
mSmartReplyController = new SmartReplyController(
|
||||
mock(DumpManager.class),
|
||||
mNotificationEntryManager,
|
||||
mVisibilityProvider,
|
||||
mIStatusBarService,
|
||||
mClickNotifier);
|
||||
mDependency.injectTestDependency(SmartReplyController.class,
|
||||
@@ -97,7 +98,9 @@ public class SmartReplyControllerTest extends SysuiTestCase {
|
||||
|
||||
mRemoteInputManager = new NotificationRemoteInputManager(mContext,
|
||||
mock(FeatureFlags.class),
|
||||
mock(NotificationLockscreenUserManager.class), mSmartReplyController,
|
||||
mock(NotificationLockscreenUserManager.class),
|
||||
mSmartReplyController,
|
||||
mVisibilityProvider,
|
||||
mNotificationEntryManager,
|
||||
new RemoteInputNotificationRebuilder(mContext),
|
||||
() -> Optional.of(mock(StatusBar.class)),
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.notification.collection
|
||||
|
||||
import android.testing.AndroidTestingRunner
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
class NotifPipelineTest : SysuiTestCase() {
|
||||
|
||||
@Mock private lateinit var notifCollection: NotifCollection
|
||||
@Mock private lateinit var shadeListBuilder: ShadeListBuilder
|
||||
private lateinit var notifPipeline: NotifPipeline
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
notifPipeline = NotifPipeline(notifCollection, shadeListBuilder)
|
||||
whenever(shadeListBuilder.shadeList).thenReturn(listOf(
|
||||
NotificationEntryBuilder().setPkg("foo").setId(1).build(),
|
||||
NotificationEntryBuilder().setPkg("foo").setId(2).build(),
|
||||
group(
|
||||
NotificationEntryBuilder().setPkg("bar").setId(1).build(),
|
||||
NotificationEntryBuilder().setPkg("bar").setId(2).build(),
|
||||
NotificationEntryBuilder().setPkg("bar").setId(3).build(),
|
||||
NotificationEntryBuilder().setPkg("bar").setId(4).build()
|
||||
),
|
||||
NotificationEntryBuilder().setPkg("baz").setId(1).build()
|
||||
))
|
||||
}
|
||||
|
||||
private fun group(summary: NotificationEntry, vararg children: NotificationEntry): GroupEntry {
|
||||
return GroupEntry(summary.key, summary.creationTime).also { group ->
|
||||
group.summary = summary
|
||||
for (it in children) {
|
||||
group.addChild(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetShadeListCount() {
|
||||
assertThat(notifPipeline.getShadeListCount()).isEqualTo(7)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetFlatShadeList() {
|
||||
assertThat(notifPipeline.getFlatShadeList().map { it.key }).containsExactly(
|
||||
"0|foo|1|null|0",
|
||||
"0|foo|2|null|0",
|
||||
"0|bar|1|null|0",
|
||||
"0|bar|2|null|0",
|
||||
"0|bar|3|null|0",
|
||||
"0|bar|4|null|0",
|
||||
"0|baz|1|null|0"
|
||||
).inOrder()
|
||||
}
|
||||
}
|
||||
@@ -29,12 +29,12 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.plugga
|
||||
import com.android.systemui.statusbar.notification.collection.render.NodeController
|
||||
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
|
||||
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_PERSON
|
||||
import com.android.systemui.util.mockito.withArgCaptor
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentCaptor
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.MockitoAnnotations
|
||||
@@ -65,9 +65,9 @@ class ConversationCoordinatorTest : SysuiTestCase() {
|
||||
coordinator.attach(pipeline)
|
||||
|
||||
// capture arguments:
|
||||
val notifPromoterCaptor = ArgumentCaptor.forClass(NotifPromoter::class.java)
|
||||
verify(pipeline).addPromoter(notifPromoterCaptor.capture())
|
||||
promoter = notifPromoterCaptor.value
|
||||
promoter = withArgCaptor {
|
||||
verify(pipeline).addPromoter(capture())
|
||||
}
|
||||
|
||||
peopleSectioner = coordinator.sectioner
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.No
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewListener
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewManager
|
||||
import com.android.systemui.statusbar.notification.row.NotificationGuts
|
||||
import com.android.systemui.util.mockito.argumentCaptor
|
||||
import com.android.systemui.util.mockito.withArgCaptor
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
@@ -60,13 +60,11 @@ class GutsCoordinatorTest : SysuiTestCase() {
|
||||
initMocks(this)
|
||||
coordinator = GutsCoordinator(notifGutsViewManager, logger, dumpManager)
|
||||
coordinator.attach(pipeline)
|
||||
notifLifetimeExtender = argumentCaptor<NotifLifetimeExtender>().let {
|
||||
verify(pipeline).addNotificationLifetimeExtender(it.capture())
|
||||
it.value!!
|
||||
notifLifetimeExtender = withArgCaptor {
|
||||
verify(pipeline).addNotificationLifetimeExtender(capture())
|
||||
}
|
||||
notifGutsViewListener = argumentCaptor<NotifGutsViewListener>().let {
|
||||
verify(notifGutsViewManager).setGutsListener(it.capture())
|
||||
it.value!!
|
||||
notifGutsViewListener = withArgCaptor {
|
||||
verify(notifGutsViewManager).setGutsListener(capture())
|
||||
}
|
||||
notifLifetimeExtender.setCallback(lifetimeExtenderCallback)
|
||||
entry1 = NotificationEntryBuilder().setId(1).build()
|
||||
|
||||
@@ -26,7 +26,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
|
||||
import com.android.systemui.util.mockito.argumentCaptor
|
||||
import com.android.systemui.util.mockito.withArgCaptor
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
@@ -56,13 +56,11 @@ class ShadeEventCoordinatorTest : SysuiTestCase() {
|
||||
initMocks(this)
|
||||
coordinator = ShadeEventCoordinator(logger)
|
||||
coordinator.attach(pipeline)
|
||||
notifCollectionListener = argumentCaptor<NotifCollectionListener>().let {
|
||||
verify(pipeline).addCollectionListener(it.capture())
|
||||
it.value!!
|
||||
notifCollectionListener = withArgCaptor {
|
||||
verify(pipeline).addCollectionListener(capture())
|
||||
}
|
||||
onBeforeRenderListListener = argumentCaptor<OnBeforeRenderListListener>().let {
|
||||
verify(pipeline).addOnBeforeRenderListListener(it.capture())
|
||||
it.value!!
|
||||
onBeforeRenderListListener = withArgCaptor {
|
||||
verify(pipeline).addOnBeforeRenderListListener(capture())
|
||||
}
|
||||
coordinator.setNotifRemovedByUserCallback(notifRemovedByUserCallback)
|
||||
coordinator.setShadeEmptiedCallback(shadeEmptiedCallback)
|
||||
|
||||
@@ -35,15 +35,13 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.plugga
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
|
||||
import com.android.systemui.util.concurrency.FakeExecutor
|
||||
import com.android.systemui.util.mockito.capture
|
||||
import com.android.systemui.util.mockito.withArgCaptor
|
||||
import com.android.systemui.util.time.FakeSystemClock
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.ArgumentCaptor
|
||||
import org.mockito.Captor
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.`when`
|
||||
import org.mockito.Mockito.anyString
|
||||
@@ -69,15 +67,6 @@ class SmartspaceDedupingCoordinatorTest : SysuiTestCase() {
|
||||
@Mock
|
||||
private lateinit var pluggableListener: Pluggable.PluggableListener<NotifFilter>
|
||||
|
||||
@Captor
|
||||
private lateinit var filterCaptor: ArgumentCaptor<NotifFilter>
|
||||
@Captor
|
||||
private lateinit var collectionListenerCaptor: ArgumentCaptor<NotifCollectionListener>
|
||||
@Captor
|
||||
private lateinit var stateListenerCaptor: ArgumentCaptor<StatusBarStateController.StateListener>
|
||||
@Captor
|
||||
private lateinit var smartspaceListenerCaptor: ArgumentCaptor<SmartspaceTargetListener>
|
||||
|
||||
private lateinit var filter: NotifFilter
|
||||
private lateinit var collectionListener: NotifCollectionListener
|
||||
private lateinit var statusBarListener: StatusBarStateController.StateListener
|
||||
@@ -118,18 +107,22 @@ class SmartspaceDedupingCoordinatorTest : SysuiTestCase() {
|
||||
// Attach the deduper and capture the listeners/filters that it registers
|
||||
deduper.attach(notifPipeline)
|
||||
|
||||
verify(notifPipeline).addPreGroupFilter(filterCaptor.capture())
|
||||
filter = filterCaptor.value
|
||||
filter = withArgCaptor {
|
||||
verify(notifPipeline).addPreGroupFilter(capture())
|
||||
}
|
||||
filter.setInvalidationListener(pluggableListener)
|
||||
|
||||
verify(notifPipeline).addCollectionListener(capture(collectionListenerCaptor))
|
||||
collectionListener = collectionListenerCaptor.value
|
||||
collectionListener = withArgCaptor {
|
||||
verify(notifPipeline).addCollectionListener(capture())
|
||||
}
|
||||
|
||||
verify(statusBarStateController).addCallback(capture(stateListenerCaptor))
|
||||
statusBarListener = stateListenerCaptor.value
|
||||
statusBarListener = withArgCaptor {
|
||||
verify(statusBarStateController).addCallback(capture())
|
||||
}
|
||||
|
||||
verify(smartspaceController).addListener(capture(smartspaceListenerCaptor))
|
||||
newTargetListener = smartspaceListenerCaptor.value
|
||||
newTargetListener = withArgCaptor {
|
||||
verify(smartspaceController).addListener(capture())
|
||||
}
|
||||
|
||||
// Initialize some test data
|
||||
entry1HasRecentlyAlerted = NotificationEntryBuilder()
|
||||
|
||||
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.notification.logging;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.UserHandle;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.internal.logging.InstanceId;
|
||||
import com.android.internal.statusbar.IStatusBarService;
|
||||
import com.android.internal.statusbar.NotificationVisibility;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.statusbar.NotificationListener;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.statusbar.notification.logging.nano.Notifications;
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||
import com.android.systemui.util.time.FakeSystemClock;
|
||||
|
||||
import com.google.android.collect.Lists;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@TestableLooper.RunWithLooper
|
||||
public class NotificationLoggerLegacyTest extends SysuiTestCase {
|
||||
private static final String TEST_PACKAGE_NAME = "test";
|
||||
private static final int TEST_UID = 0;
|
||||
|
||||
@Mock private NotificationListContainer mListContainer;
|
||||
@Mock private IStatusBarService mBarService;
|
||||
@Mock private ExpandableNotificationRow mRow;
|
||||
@Mock private NotificationLogger.ExpansionStateLogger mExpansionStateLogger;
|
||||
|
||||
// Dependency mocks:
|
||||
@Mock private FeatureFlags mFeatureFlags;
|
||||
@Mock private NotificationVisibilityProvider mVisibilityProvider;
|
||||
@Mock private NotificationEntryManager mEntryManager;
|
||||
@Mock private NotifPipeline mNotifPipeline;
|
||||
@Mock private NotificationListener mListener;
|
||||
|
||||
private NotificationEntry mEntry;
|
||||
private TestableNotificationLogger mLogger;
|
||||
private ConcurrentLinkedQueue<AssertionError> mErrorQueue = new ConcurrentLinkedQueue<>();
|
||||
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
|
||||
private NotificationPanelLoggerFake mNotificationPanelLoggerFake =
|
||||
new NotificationPanelLoggerFake();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mEntry = new NotificationEntryBuilder()
|
||||
.setPkg(TEST_PACKAGE_NAME)
|
||||
.setOpPkg(TEST_PACKAGE_NAME)
|
||||
.setUid(TEST_UID)
|
||||
.setNotification(new Notification())
|
||||
.setUser(UserHandle.CURRENT)
|
||||
.setInstanceId(InstanceId.fakeInstanceId(1))
|
||||
.build();
|
||||
mEntry.setRow(mRow);
|
||||
|
||||
mLogger = new TestableNotificationLogger(
|
||||
mListener,
|
||||
mUiBgExecutor,
|
||||
mFeatureFlags,
|
||||
mVisibilityProvider,
|
||||
mEntryManager,
|
||||
mNotifPipeline,
|
||||
mock(StatusBarStateControllerImpl.class),
|
||||
mBarService,
|
||||
mExpansionStateLogger
|
||||
);
|
||||
mLogger.setUpWithContainer(mListContainer);
|
||||
verify(mEntryManager).addNotificationEntryListener(any());
|
||||
verify(mNotifPipeline, never()).addCollectionListener(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnChildLocationsChangedReportsVisibilityChanged() throws Exception {
|
||||
NotificationVisibility[] newlyVisibleKeys = {
|
||||
NotificationVisibility.obtain(mEntry.getKey(), 0, 1, true)
|
||||
};
|
||||
NotificationVisibility[] noLongerVisibleKeys = {};
|
||||
doAnswer(invocation -> {
|
||||
try {
|
||||
assertArrayEquals(newlyVisibleKeys,
|
||||
(NotificationVisibility[]) invocation.getArguments()[0]);
|
||||
assertArrayEquals(noLongerVisibleKeys,
|
||||
(NotificationVisibility[]) invocation.getArguments()[1]);
|
||||
} catch (AssertionError error) {
|
||||
mErrorQueue.offer(error);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
).when(mBarService).onNotificationVisibilityChanged(any(NotificationVisibility[].class),
|
||||
any(NotificationVisibility[].class));
|
||||
|
||||
when(mListContainer.isInVisibleLocation(any())).thenReturn(true);
|
||||
when(mEntryManager.getVisibleNotifications()).thenReturn(Lists.newArrayList(mEntry));
|
||||
mLogger.getChildLocationsChangedListenerForTest().onChildLocationsChanged();
|
||||
TestableLooper.get(this).processAllMessages();
|
||||
mUiBgExecutor.runAllReady();
|
||||
|
||||
if (!mErrorQueue.isEmpty()) {
|
||||
throw mErrorQueue.poll();
|
||||
}
|
||||
|
||||
// |mEntry| won't change visibility, so it shouldn't be reported again:
|
||||
Mockito.reset(mBarService);
|
||||
mLogger.getChildLocationsChangedListenerForTest().onChildLocationsChanged();
|
||||
TestableLooper.get(this).processAllMessages();
|
||||
mUiBgExecutor.runAllReady();
|
||||
|
||||
verify(mBarService, never()).onNotificationVisibilityChanged(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoppingNotificationLoggingReportsCurrentNotifications()
|
||||
throws Exception {
|
||||
when(mListContainer.isInVisibleLocation(any())).thenReturn(true);
|
||||
when(mEntryManager.getVisibleNotifications()).thenReturn(Lists.newArrayList(mEntry));
|
||||
mLogger.getChildLocationsChangedListenerForTest().onChildLocationsChanged();
|
||||
TestableLooper.get(this).processAllMessages();
|
||||
mUiBgExecutor.runAllReady();
|
||||
Mockito.reset(mBarService);
|
||||
|
||||
setStateAsleep();
|
||||
mLogger.onDozingChanged(false); // Wake to lockscreen
|
||||
mLogger.onDozingChanged(true); // And go back to sleep, turning off logging
|
||||
mUiBgExecutor.runAllReady();
|
||||
// The visibility objects are recycled by NotificationLogger, so we can't use specific
|
||||
// matchers here.
|
||||
verify(mBarService, times(1)).onNotificationVisibilityChanged(any(), any());
|
||||
}
|
||||
|
||||
private void setStateAsleep() {
|
||||
mLogger.onPanelExpandedChanged(true);
|
||||
mLogger.onDozingChanged(true);
|
||||
mLogger.onStateChanged(StatusBarState.KEYGUARD);
|
||||
}
|
||||
|
||||
private void setStateAwake() {
|
||||
mLogger.onPanelExpandedChanged(false);
|
||||
mLogger.onDozingChanged(false);
|
||||
mLogger.onStateChanged(StatusBarState.SHADE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogPanelShownOnWake() {
|
||||
when(mEntryManager.getVisibleNotifications()).thenReturn(Lists.newArrayList(mEntry));
|
||||
setStateAsleep();
|
||||
mLogger.onDozingChanged(false); // Wake to lockscreen
|
||||
assertEquals(1, mNotificationPanelLoggerFake.getCalls().size());
|
||||
assertTrue(mNotificationPanelLoggerFake.get(0).isLockscreen);
|
||||
assertEquals(1, mNotificationPanelLoggerFake.get(0).list.notifications.length);
|
||||
Notifications.Notification n = mNotificationPanelLoggerFake.get(0).list.notifications[0];
|
||||
assertEquals(TEST_PACKAGE_NAME, n.packageName);
|
||||
assertEquals(TEST_UID, n.uid);
|
||||
assertEquals(1, n.instanceId);
|
||||
assertFalse(n.isGroupSummary);
|
||||
assertEquals(Notifications.Notification.SECTION_ALERTING, n.section);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogPanelShownOnShadePull() {
|
||||
when(mEntryManager.getVisibleNotifications()).thenReturn(Lists.newArrayList(mEntry));
|
||||
setStateAwake();
|
||||
// Now expand panel
|
||||
mLogger.onPanelExpandedChanged(true);
|
||||
assertEquals(1, mNotificationPanelLoggerFake.getCalls().size());
|
||||
assertFalse(mNotificationPanelLoggerFake.get(0).isLockscreen);
|
||||
assertEquals(1, mNotificationPanelLoggerFake.get(0).list.notifications.length);
|
||||
Notifications.Notification n = mNotificationPanelLoggerFake.get(0).list.notifications[0];
|
||||
assertEquals(TEST_PACKAGE_NAME, n.packageName);
|
||||
assertEquals(TEST_UID, n.uid);
|
||||
assertEquals(1, n.instanceId);
|
||||
assertFalse(n.isGroupSummary);
|
||||
assertEquals(Notifications.Notification.SECTION_ALERTING, n.section);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLogPanelShownHandlesNullInstanceIds() {
|
||||
// Construct a NotificationEntry like mEntry, but with a null instance id.
|
||||
NotificationEntry entry = new NotificationEntryBuilder()
|
||||
.setPkg(TEST_PACKAGE_NAME)
|
||||
.setOpPkg(TEST_PACKAGE_NAME)
|
||||
.setUid(TEST_UID)
|
||||
.setNotification(new Notification())
|
||||
.setUser(UserHandle.CURRENT)
|
||||
.build();
|
||||
entry.setRow(mRow);
|
||||
|
||||
when(mEntryManager.getVisibleNotifications()).thenReturn(Lists.newArrayList(entry));
|
||||
setStateAsleep();
|
||||
mLogger.onDozingChanged(false); // Wake to lockscreen
|
||||
assertEquals(1, mNotificationPanelLoggerFake.getCalls().size());
|
||||
assertEquals(1, mNotificationPanelLoggerFake.get(0).list.notifications.length);
|
||||
Notifications.Notification n = mNotificationPanelLoggerFake.get(0).list.notifications[0];
|
||||
assertEquals(0, n.instanceId);
|
||||
}
|
||||
|
||||
private class TestableNotificationLogger extends NotificationLogger {
|
||||
|
||||
TestableNotificationLogger(NotificationListener notificationListener,
|
||||
Executor uiBgExecutor,
|
||||
FeatureFlags featureFlags,
|
||||
NotificationVisibilityProvider visibilityProvider,
|
||||
NotificationEntryManager entryManager,
|
||||
NotifPipeline notifPipeline,
|
||||
StatusBarStateControllerImpl statusBarStateController,
|
||||
IStatusBarService barService,
|
||||
ExpansionStateLogger expansionStateLogger) {
|
||||
super(
|
||||
notificationListener,
|
||||
uiBgExecutor,
|
||||
featureFlags,
|
||||
visibilityProvider,
|
||||
entryManager,
|
||||
notifPipeline,
|
||||
statusBarStateController,
|
||||
expansionStateLogger,
|
||||
mNotificationPanelLoggerFake
|
||||
);
|
||||
mBarService = barService;
|
||||
// Make this on the current thread so we can wait for it during tests.
|
||||
mHandler = Handler.createAsync(Looper.myLooper());
|
||||
}
|
||||
|
||||
OnChildLocationsChangedListener getChildLocationsChangedListenerForTest() {
|
||||
return mNotificationLocationsChangedListener;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,13 +41,15 @@ import com.android.internal.logging.InstanceId;
|
||||
import com.android.internal.statusbar.IStatusBarService;
|
||||
import com.android.internal.statusbar.NotificationVisibility;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.statusbar.NotificationListener;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryListener;
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.statusbar.notification.logging.nano.Notifications;
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
|
||||
@@ -59,8 +61,6 @@ import com.google.android.collect.Lists;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
@@ -81,9 +81,11 @@ public class NotificationLoggerTest extends SysuiTestCase {
|
||||
@Mock private NotificationLogger.ExpansionStateLogger mExpansionStateLogger;
|
||||
|
||||
// Dependency mocks:
|
||||
@Mock private FeatureFlags mFeatureFlags;
|
||||
@Mock private NotificationVisibilityProvider mVisibilityProvider;
|
||||
@Mock private NotificationEntryManager mEntryManager;
|
||||
@Mock private NotifPipeline mNotifPipeline;
|
||||
@Mock private NotificationListener mListener;
|
||||
@Captor private ArgumentCaptor<NotificationEntryListener> mEntryListenerCaptor;
|
||||
|
||||
private NotificationEntry mEntry;
|
||||
private TestableNotificationLogger mLogger;
|
||||
@@ -95,8 +97,7 @@ public class NotificationLoggerTest extends SysuiTestCase {
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
|
||||
mDependency.injectTestDependency(NotificationListener.class, mListener);
|
||||
when(mFeatureFlags.isNewNotifPipelineRenderingEnabled()).thenReturn(true);
|
||||
|
||||
mEntry = new NotificationEntryBuilder()
|
||||
.setPkg(TEST_PACKAGE_NAME)
|
||||
@@ -108,11 +109,20 @@ public class NotificationLoggerTest extends SysuiTestCase {
|
||||
.build();
|
||||
mEntry.setRow(mRow);
|
||||
|
||||
mLogger = new TestableNotificationLogger(mListener, mUiBgExecutor,
|
||||
mEntryManager, mock(StatusBarStateControllerImpl.class), mBarService,
|
||||
mExpansionStateLogger);
|
||||
mLogger = new TestableNotificationLogger(
|
||||
mListener,
|
||||
mUiBgExecutor,
|
||||
mFeatureFlags,
|
||||
mVisibilityProvider,
|
||||
mEntryManager,
|
||||
mNotifPipeline,
|
||||
mock(StatusBarStateControllerImpl.class),
|
||||
mBarService,
|
||||
mExpansionStateLogger
|
||||
);
|
||||
mLogger.setUpWithContainer(mListContainer);
|
||||
verify(mEntryManager).addNotificationEntryListener(mEntryListenerCaptor.capture());
|
||||
verify(mEntryManager, never()).addNotificationEntryListener(any());
|
||||
verify(mNotifPipeline).addCollectionListener(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -136,12 +146,12 @@ public class NotificationLoggerTest extends SysuiTestCase {
|
||||
any(NotificationVisibility[].class));
|
||||
|
||||
when(mListContainer.isInVisibleLocation(any())).thenReturn(true);
|
||||
when(mEntryManager.getVisibleNotifications()).thenReturn(Lists.newArrayList(mEntry));
|
||||
when(mNotifPipeline.getFlatShadeList()).thenReturn(Lists.newArrayList(mEntry));
|
||||
mLogger.getChildLocationsChangedListenerForTest().onChildLocationsChanged();
|
||||
TestableLooper.get(this).processAllMessages();
|
||||
mUiBgExecutor.runAllReady();
|
||||
|
||||
if(!mErrorQueue.isEmpty()) {
|
||||
if (!mErrorQueue.isEmpty()) {
|
||||
throw mErrorQueue.poll();
|
||||
}
|
||||
|
||||
@@ -158,7 +168,7 @@ public class NotificationLoggerTest extends SysuiTestCase {
|
||||
public void testStoppingNotificationLoggingReportsCurrentNotifications()
|
||||
throws Exception {
|
||||
when(mListContainer.isInVisibleLocation(any())).thenReturn(true);
|
||||
when(mEntryManager.getVisibleNotifications()).thenReturn(Lists.newArrayList(mEntry));
|
||||
when(mNotifPipeline.getFlatShadeList()).thenReturn(Lists.newArrayList(mEntry));
|
||||
mLogger.getChildLocationsChangedListenerForTest().onChildLocationsChanged();
|
||||
TestableLooper.get(this).processAllMessages();
|
||||
mUiBgExecutor.runAllReady();
|
||||
@@ -187,7 +197,7 @@ public class NotificationLoggerTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void testLogPanelShownOnWake() {
|
||||
when(mEntryManager.getVisibleNotifications()).thenReturn(Lists.newArrayList(mEntry));
|
||||
when(mNotifPipeline.getFlatShadeList()).thenReturn(Lists.newArrayList(mEntry));
|
||||
setStateAsleep();
|
||||
mLogger.onDozingChanged(false); // Wake to lockscreen
|
||||
assertEquals(1, mNotificationPanelLoggerFake.getCalls().size());
|
||||
@@ -203,7 +213,7 @@ public class NotificationLoggerTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void testLogPanelShownOnShadePull() {
|
||||
when(mEntryManager.getVisibleNotifications()).thenReturn(Lists.newArrayList(mEntry));
|
||||
when(mNotifPipeline.getFlatShadeList()).thenReturn(Lists.newArrayList(mEntry));
|
||||
setStateAwake();
|
||||
// Now expand panel
|
||||
mLogger.onPanelExpandedChanged(true);
|
||||
@@ -231,7 +241,7 @@ public class NotificationLoggerTest extends SysuiTestCase {
|
||||
.build();
|
||||
entry.setRow(mRow);
|
||||
|
||||
when(mEntryManager.getVisibleNotifications()).thenReturn(Lists.newArrayList(entry));
|
||||
when(mNotifPipeline.getFlatShadeList()).thenReturn(Lists.newArrayList(entry));
|
||||
setStateAsleep();
|
||||
mLogger.onDozingChanged(false); // Wake to lockscreen
|
||||
assertEquals(1, mNotificationPanelLoggerFake.getCalls().size());
|
||||
@@ -244,19 +254,30 @@ public class NotificationLoggerTest extends SysuiTestCase {
|
||||
|
||||
TestableNotificationLogger(NotificationListener notificationListener,
|
||||
Executor uiBgExecutor,
|
||||
FeatureFlags featureFlags,
|
||||
NotificationVisibilityProvider visibilityProvider,
|
||||
NotificationEntryManager entryManager,
|
||||
NotifPipeline notifPipeline,
|
||||
StatusBarStateControllerImpl statusBarStateController,
|
||||
IStatusBarService barService,
|
||||
ExpansionStateLogger expansionStateLogger) {
|
||||
super(notificationListener, uiBgExecutor, entryManager, statusBarStateController,
|
||||
expansionStateLogger, mNotificationPanelLoggerFake);
|
||||
super(
|
||||
notificationListener,
|
||||
uiBgExecutor,
|
||||
featureFlags,
|
||||
visibilityProvider,
|
||||
entryManager,
|
||||
notifPipeline,
|
||||
statusBarStateController,
|
||||
expansionStateLogger,
|
||||
mNotificationPanelLoggerFake
|
||||
);
|
||||
mBarService = barService;
|
||||
// Make this on the current thread so we can wait for it during tests.
|
||||
mHandler = Handler.createAsync(Looper.myLooper());
|
||||
}
|
||||
|
||||
OnChildLocationsChangedListener
|
||||
getChildLocationsChangedListenerForTest() {
|
||||
OnChildLocationsChangedListener getChildLocationsChangedListenerForTest() {
|
||||
return mNotificationLocationsChangedListener;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ import com.android.systemui.statusbar.notification.collection.NotifCollection;
|
||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
|
||||
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||
import com.android.systemui.statusbar.notification.row.ForegroundServiceDungeonView;
|
||||
@@ -97,6 +98,7 @@ import org.mockito.MockitoAnnotations;
|
||||
public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
|
||||
|
||||
@Mock private NotificationGutsManager mNotificationGutsManager;
|
||||
@Mock private NotificationVisibilityProvider mVisibilityProvider;
|
||||
@Mock private HeadsUpManagerPhone mHeadsUpManager;
|
||||
@Mock private NotificationRoundnessManager mNotificationRoundnessManager;
|
||||
@Mock private TunerService mTunerService;
|
||||
@@ -151,6 +153,7 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
|
||||
mController = new NotificationStackScrollLayoutController(
|
||||
true,
|
||||
mNotificationGutsManager,
|
||||
mVisibilityProvider,
|
||||
mHeadsUpManager,
|
||||
mNotificationRoundnessManager,
|
||||
mTunerService,
|
||||
|
||||
@@ -22,6 +22,7 @@ import static org.mockito.AdditionalAnswers.answerVoid;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
@@ -68,6 +69,7 @@ import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorCon
|
||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
|
||||
@@ -123,6 +125,8 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
|
||||
private FeatureFlags mFeatureFlags;
|
||||
@Mock
|
||||
private NotifPipeline mNotifPipeline;
|
||||
@Mock
|
||||
private NotificationVisibilityProvider mVisibilityProvider;
|
||||
|
||||
@Mock
|
||||
private ActivityIntentHelper mActivityIntentHelper;
|
||||
@@ -179,6 +183,11 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
|
||||
when(mFeatureFlags.isNewNotifPipelineRenderingEnabled()).thenReturn(false);
|
||||
when(mOnUserInteractionCallback.getGroupSummaryToDismiss(mNotificationRow.getEntry()))
|
||||
.thenReturn(null);
|
||||
when(mVisibilityProvider.obtain(anyString(), anyBoolean())).thenAnswer(
|
||||
invocation-> NotificationVisibility.obtain(invocation.getArgument(0), 0, 1, false));
|
||||
when(mVisibilityProvider.obtain(any(NotificationEntry.class), anyBoolean())).thenAnswer(
|
||||
invocation-> NotificationVisibility.obtain(
|
||||
invocation.<NotificationEntry>getArgument(0).getKey(), 0, 1, false));
|
||||
|
||||
HeadsUpManagerPhone headsUpManager = mock(HeadsUpManagerPhone.class);
|
||||
NotificationLaunchAnimatorControllerProvider notificationAnimationProvider =
|
||||
@@ -195,6 +204,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
|
||||
mUiBgExecutor,
|
||||
mEntryManager,
|
||||
mNotifPipeline,
|
||||
mVisibilityProvider,
|
||||
headsUpManager,
|
||||
mActivityStarter,
|
||||
mClickNotifier,
|
||||
|
||||
@@ -117,10 +117,12 @@ import com.android.systemui.statusbar.notification.DynamicPrivacyController;
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
import com.android.systemui.statusbar.notification.NotificationFilter;
|
||||
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
|
||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
|
||||
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.statusbar.notification.init.NotificationsController;
|
||||
import com.android.systemui.statusbar.notification.interruption.BypassHeadsUpNotifier;
|
||||
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl;
|
||||
@@ -264,6 +266,7 @@ public class StatusBarTest extends SysuiTestCase {
|
||||
@Mock private StatusBarIconController mIconController;
|
||||
@Mock private LockscreenShadeTransitionController mLockscreenTransitionController;
|
||||
@Mock private FeatureFlags mFeatureFlags;
|
||||
@Mock private NotificationVisibilityProvider mVisibilityProvider;
|
||||
@Mock private WallpaperManager mWallpaperManager;
|
||||
@Mock private IWallpaperManager mIWallpaperManager;
|
||||
@Mock private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
|
||||
@@ -301,9 +304,17 @@ public class StatusBarTest extends SysuiTestCase {
|
||||
mContext.addMockSystemService(FingerprintManager.class, mock(FingerprintManager.class));
|
||||
|
||||
mMetricsLogger = new FakeMetricsLogger();
|
||||
NotificationLogger notificationLogger = new NotificationLogger(mNotificationListener,
|
||||
mUiBgExecutor, mock(NotificationEntryManager.class), mStatusBarStateController,
|
||||
mExpansionStateLogger, new NotificationPanelLoggerFake());
|
||||
NotificationLogger notificationLogger = new NotificationLogger(
|
||||
mNotificationListener,
|
||||
mUiBgExecutor,
|
||||
mFeatureFlags,
|
||||
mVisibilityProvider,
|
||||
mock(NotificationEntryManager.class),
|
||||
mock(NotifPipeline.class),
|
||||
mStatusBarStateController,
|
||||
mExpansionStateLogger,
|
||||
new NotificationPanelLoggerFake()
|
||||
);
|
||||
notificationLogger.setVisibilityReporter(mock(Runnable.class));
|
||||
|
||||
when(mCommandQueue.asBinder()).thenReturn(new Binder());
|
||||
|
||||
@@ -66,6 +66,27 @@ inline fun <reified T : Any> argumentCaptor(): ArgumentCaptor<T> =
|
||||
*/
|
||||
inline fun <reified T : Any> mock(): T = Mockito.mock(T::class.java)
|
||||
|
||||
/**
|
||||
* A kotlin implemented wrapper of [ArgumentCaptor] which prevents the following exception when
|
||||
* kotlin tests are mocking kotlin objects and the methods take non-null parameters:
|
||||
*
|
||||
* java.lang.NullPointerException: capture() must not be null
|
||||
*/
|
||||
class KotlinArgumentCaptor<T> constructor(clazz: Class<T>) {
|
||||
private val wrapped: ArgumentCaptor<T> = ArgumentCaptor.forClass(clazz)
|
||||
fun capture(): T = wrapped.capture()
|
||||
val value: T
|
||||
get() = wrapped.value
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for creating an argumentCaptor in kotlin.
|
||||
*
|
||||
* Generic T is nullable because implicitly bounded by Any?.
|
||||
*/
|
||||
inline fun <reified T : Any> kotlinArgumentCaptor(): KotlinArgumentCaptor<T> =
|
||||
KotlinArgumentCaptor(T::class.java)
|
||||
|
||||
/**
|
||||
* Helper function for creating and using a single-use ArgumentCaptor in kotlin.
|
||||
*
|
||||
@@ -76,6 +97,8 @@ inline fun <reified T : Any> mock(): T = Mockito.mock(T::class.java)
|
||||
* becomes:
|
||||
*
|
||||
* val captured = withArgCaptor<Foo> { verify(...).someMethod(capture()) }
|
||||
*
|
||||
* NOTE: this uses the KotlinArgumentCaptor to avoid the NullPointerException.
|
||||
*/
|
||||
inline fun <reified T : Any> withArgCaptor(block: ArgumentCaptor<T>.() -> Unit): T =
|
||||
argumentCaptor<T>().apply { block() }.value
|
||||
inline fun <reified T : Any> withArgCaptor(block: KotlinArgumentCaptor<T>.() -> Unit): T =
|
||||
kotlinArgumentCaptor<T>().apply { block() }.value
|
||||
|
||||
@@ -92,6 +92,7 @@ import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
|
||||
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
|
||||
import com.android.systemui.statusbar.phone.DozeParameters;
|
||||
@@ -228,6 +229,8 @@ public class BubblesTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private IStatusBarService mStatusBarService;
|
||||
@Mock
|
||||
private NotificationVisibilityProvider mVisibilityProvider;
|
||||
@Mock
|
||||
private LauncherApps mLauncherApps;
|
||||
@Mock
|
||||
private WindowManagerShellWrapper mWindowManagerShellWrapper;
|
||||
@@ -354,6 +357,7 @@ public class BubblesTest extends SysuiTestCase {
|
||||
mConfigurationController,
|
||||
mStatusBarService,
|
||||
mock(INotificationManager.class),
|
||||
mVisibilityProvider,
|
||||
interruptionStateProvider,
|
||||
mZenModeController,
|
||||
mLockscreenUserManager,
|
||||
|
||||
@@ -78,6 +78,7 @@ import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
|
||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
|
||||
import com.android.systemui.statusbar.phone.DozeParameters;
|
||||
@@ -204,6 +205,8 @@ public class NewNotifPipelineBubblesTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private IStatusBarService mStatusBarService;
|
||||
@Mock
|
||||
private NotificationVisibilityProvider mVisibilityProvider;
|
||||
@Mock
|
||||
private LauncherApps mLauncherApps;
|
||||
@Mock
|
||||
private WindowManagerShellWrapper mWindowManagerShellWrapper;
|
||||
@@ -319,6 +322,7 @@ public class NewNotifPipelineBubblesTest extends SysuiTestCase {
|
||||
mConfigurationController,
|
||||
mStatusBarService,
|
||||
mock(INotificationManager.class),
|
||||
mVisibilityProvider,
|
||||
interruptionStateProvider,
|
||||
mZenModeController,
|
||||
mLockscreenUserManager,
|
||||
|
||||
Reference in New Issue
Block a user