Create a shim for StatusBarManager click methods
`StatusBarManager#onNotificationClick` and
`StatusBarManager#onNotificationActionClick` are signals we send to
system server about notification clicks. This CL adds a shim so that we
can have an in-process callback about the exact same events.
This CL also adds NotificationInteractionTracker, which basically just
merges the NotificationClickNotifier callbacks with the notification
collection and will be able to answer the question "has the user
interacted with this notification"
Lastly, this modifies the logic in ForegroundServiceLifetimeExtender
which now checks the interaction flag for notifications. So if a user
tapped on a notification action (for instance) which _then_ triggers a
notification cancel, it will succeed. It _does not_ as of yet release
the notification from lifetime extension upon interaction. So if a
notification is canceled and then interacted with, it will still live
the full amount of time.
Test: atest SystemUITests
Bug: 144324894
Change-Id: I42201d6e7b7ffe9ad4f19c774b638a36a51750ef
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender.java
index e17d4e6..77abffc 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender.java
@@ -23,10 +23,13 @@
import android.util.ArraySet;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.statusbar.NotificationInteractionTracker;
import com.android.systemui.statusbar.NotificationLifetimeExtender;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.util.time.SystemClock;
+import javax.inject.Inject;
+
/**
* Extends the lifetime of foreground notification services such that they show for at least
* five seconds
@@ -41,9 +44,14 @@
private ArraySet<NotificationEntry> mManagedEntries = new ArraySet<>();
private Handler mHandler = new Handler(Looper.getMainLooper());
private final SystemClock mSystemClock;
+ private final NotificationInteractionTracker mInteractionTracker;
- public ForegroundServiceLifetimeExtender(SystemClock systemClock) {
+ @Inject
+ public ForegroundServiceLifetimeExtender(
+ NotificationInteractionTracker interactionTracker,
+ SystemClock systemClock) {
mSystemClock = systemClock;
+ mInteractionTracker = interactionTracker;
}
@Override
@@ -58,8 +66,9 @@
return false;
}
- long currentTime = mSystemClock.uptimeMillis();
- return currentTime - entry.getCreationTime() < MIN_FGS_TIME_MS;
+ boolean hasInteracted = mInteractionTracker.hasUserInteractedWith(entry.getKey());
+ long aliveTime = mSystemClock.uptimeMillis() - entry.getCreationTime();
+ return aliveTime < MIN_FGS_TIME_MS && !hasInteracted;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
index ef1f4e0..650b9a7 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
@@ -51,6 +51,7 @@
ForegroundServiceController foregroundServiceController,
NotificationEntryManager notificationEntryManager,
NotifPipeline notifPipeline,
+ ForegroundServiceLifetimeExtender fgsLifetimeExtender,
SystemClock systemClock) {
mContext = context;
mForegroundServiceController = foregroundServiceController;
@@ -78,8 +79,7 @@
removeNotification(entry.getSbn());
}
});
- mEntryManager.addNotificationLifetimeExtender(
- new ForegroundServiceLifetimeExtender(systemClock));
+ mEntryManager.addNotificationLifetimeExtender(fgsLifetimeExtender);
notifPipeline.addCollectionListener(new NotifCollectionListener() {
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationClickNotifier.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationClickNotifier.kt
new file mode 100644
index 0000000..8248fc9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationClickNotifier.kt
@@ -0,0 +1,87 @@
+package com.android.systemui.statusbar
+
+import android.app.Notification
+import android.os.RemoteException
+import com.android.internal.statusbar.IStatusBarService
+import com.android.internal.statusbar.NotificationVisibility
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.util.Assert
+import java.util.concurrent.Executor
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/**
+ * Class to shim calls to IStatusBarManager#onNotificationClick/#onNotificationActionClick that
+ * allow an in-process notification to go out (e.g., for tracking interactions) as well as
+ * sending the messages along to system server.
+ *
+ * NOTE: this class eats exceptions from system server, as no current client of these APIs cares
+ * about errors
+ */
+@Singleton
+public class NotificationClickNotifier @Inject constructor(
+ val barService: IStatusBarService,
+ @Main val mainExecutor: Executor
+) {
+ val listeners = mutableListOf<NotificationInteractionListener>()
+
+ fun addNotificationInteractionListener(listener: NotificationInteractionListener) {
+ Assert.isMainThread()
+ listeners.add(listener)
+ }
+
+ fun removeNotificationInteractionListener(listener: NotificationInteractionListener) {
+ Assert.isMainThread()
+ listeners.remove(listener)
+ }
+
+ private fun notifyListenersAboutInteraction(key: String) {
+ for (l in listeners) {
+ l.onNotificationInteraction(key)
+ }
+ }
+
+ fun onNotificationActionClick(
+ key: String,
+ actionIndex: Int,
+ action: Notification.Action,
+ visibility: NotificationVisibility,
+ generatedByAssistant: Boolean
+ ) {
+ try {
+ barService.onNotificationActionClick(
+ key, actionIndex, action, visibility, generatedByAssistant)
+ } catch (e: RemoteException) {
+ // nothing
+ }
+
+ mainExecutor.execute {
+ notifyListenersAboutInteraction(key)
+ }
+ }
+
+ fun onNotificationClick(
+ key: String,
+ visibility: NotificationVisibility
+ ) {
+ try {
+ barService.onNotificationClick(key, visibility)
+ } catch (e: RemoteException) {
+ // nothing
+ }
+
+ mainExecutor.execute {
+ notifyListenersAboutInteraction(key)
+ }
+ }
+}
+
+/**
+ * Interface for listeners to get notified when a notification is interacted with via a click or
+ * interaction with remote input or actions
+ */
+interface NotificationInteractionListener {
+ fun onNotificationInteraction(key: String)
+}
+
+private const val TAG = "NotificationClickNotifier"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInteractionTracker.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInteractionTracker.kt
new file mode 100644
index 0000000..2ed04eb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInteractionTracker.kt
@@ -0,0 +1,40 @@
+package com.android.systemui.statusbar
+
+import com.android.systemui.statusbar.notification.NotificationEntryManager
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/**
+ * Class to track user interaction with notifications. It's a glorified map of key : bool that can
+ * merge multiple "user interacted with notification" signals into a single place.
+ */
+@Singleton
+class NotificationInteractionTracker @Inject constructor(
+ private val clicker: NotificationClickNotifier,
+ private val entryManager: NotificationEntryManager
+) : NotifCollectionListener, NotificationInteractionListener {
+ private val interactions = mutableMapOf<String, Boolean>()
+
+ init {
+ clicker.addNotificationInteractionListener(this)
+ entryManager.addCollectionListener(this)
+ }
+
+ fun hasUserInteractedWith(key: String): Boolean = key in interactions
+
+ override fun onEntryAdded(entry: NotificationEntry) {
+ interactions[entry.key] = false
+ }
+
+ override fun onEntryCleanUp(entry: NotificationEntry) {
+ interactions.remove(entry.key)
+ }
+
+ override fun onNotificationInteraction(key: String) {
+ interactions[key] = true
+ }
+}
+
+private const val TAG = "NotificationInteractionTracker"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index 2baab61..03424c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -35,7 +35,6 @@
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.os.Handler;
-import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
@@ -43,7 +42,6 @@
import android.util.SparseArray;
import android.util.SparseBooleanArray;
-import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -92,9 +90,9 @@
private final SparseBooleanArray mUsersAllowingPrivateNotifications = new SparseBooleanArray();
private final SparseBooleanArray mUsersAllowingNotifications = new SparseBooleanArray();
private final UserManager mUserManager;
- private final IStatusBarService mBarService;
private final List<UserChangedListener> mListeners = new ArrayList<>();
private final BroadcastDispatcher mBroadcastDispatcher;
+ private final NotificationClickNotifier mClickNotifier;
private boolean mShowLockscreenNotifications;
private boolean mAllowLockscreenRemoteInput;
@@ -170,11 +168,7 @@
final NotificationVisibility nv = NotificationVisibility.obtain(
notificationKey,
rank, count, true, location);
- try {
- mBarService.onNotificationClick(notificationKey, nv);
- } catch (RemoteException exception) {
- /* ignore */
- }
+ mClickNotifier.onNotificationClick(notificationKey, nv);
}
break;
}
@@ -203,7 +197,7 @@
BroadcastDispatcher broadcastDispatcher,
DevicePolicyManager devicePolicyManager,
UserManager userManager,
- IStatusBarService iStatusBarService,
+ NotificationClickNotifier clickNotifier,
KeyguardManager keyguardManager,
StatusBarStateController statusBarStateController,
@Main Handler mainHandler,
@@ -214,7 +208,7 @@
mDevicePolicyManager = devicePolicyManager;
mUserManager = userManager;
mCurrentUserId = ActivityManager.getCurrentUser();
- mBarService = iStatusBarService;
+ mClickNotifier = clickNotifier;
statusBarStateController.addCallback(this);
mLockPatternUtils = new LockPatternUtils(context);
mKeyguardManager = keyguardManager;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index 9181c69..a81c7d3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -123,6 +123,7 @@
private final KeyguardManager mKeyguardManager;
private final StatusBarStateController mStatusBarStateController;
private final RemoteInputUriController mRemoteInputUriController;
+ private final NotificationClickNotifier mClickNotifier;
protected RemoteInputController mRemoteInputController;
protected NotificationLifetimeExtender.NotificationSafeToRemoveCallback
@@ -214,11 +215,7 @@
mEntryManager.getActiveNotificationUnfiltered(key));
final NotificationVisibility nv =
NotificationVisibility.obtain(key, rank, count, true, location);
- try {
- mBarService.onNotificationActionClick(key, buttonIndex, action, nv, false);
- } catch (RemoteException e) {
- // Ignore
- }
+ mClickNotifier.onNotificationActionClick(key, buttonIndex, action, nv, false);
}
private NotificationEntry getNotificationForParent(ViewParent parent) {
@@ -275,6 +272,7 @@
StatusBarStateController statusBarStateController,
@Main Handler mainHandler,
RemoteInputUriController remoteInputUriController,
+ NotificationClickNotifier clickNotifier,
ActionClickLogger logger) {
mContext = context;
mLockscreenUserManager = lockscreenUserManager;
@@ -290,6 +288,7 @@
mKeyguardManager = context.getSystemService(KeyguardManager.class);
mStatusBarStateController = statusBarStateController;
mRemoteInputUriController = remoteInputUriController;
+ mClickNotifier = clickNotifier;
notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java b/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java
index bb96f42..7fc18b7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java
@@ -35,6 +35,7 @@
public class SmartReplyController {
private final IStatusBarService mBarService;
private final NotificationEntryManager mEntryManager;
+ private final NotificationClickNotifier mClickNotifier;
private Set<String> mSendingKeys = new ArraySet<>();
private Callback mCallback;
@@ -42,9 +43,11 @@
* Injected constructor. See {@link StatusBarModule}.
*/
public SmartReplyController(NotificationEntryManager entryManager,
- IStatusBarService statusBarService) {
+ IStatusBarService statusBarService,
+ NotificationClickNotifier clickNotifier) {
mBarService = statusBarService;
mEntryManager = entryManager;
+ mClickNotifier = clickNotifier;
}
public void setCallback(Callback callback) {
@@ -78,12 +81,8 @@
NotificationLogger.getNotificationLocation(entry);
final NotificationVisibility nv = NotificationVisibility.obtain(
entry.getKey(), rank, count, true, location);
- try {
- mBarService.onNotificationActionClick(
- entry.getKey(), actionIndex, action, nv, generatedByAssistant);
- } catch (RemoteException e) {
- // Nothing to do, system going down
- }
+ mClickNotifier.onNotificationActionClick(
+ entry.getKey(), actionIndex, action, nv, generatedByAssistant);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java
index b08eb9f..176e426 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java
@@ -28,6 +28,7 @@
import com.android.systemui.statusbar.ActionClickLogger;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.MediaArtworkProcessor;
+import com.android.systemui.statusbar.NotificationClickNotifier;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationMediaManager;
@@ -75,6 +76,7 @@
StatusBarStateController statusBarStateController,
Handler mainHandler,
RemoteInputUriController remoteInputUriController,
+ NotificationClickNotifier clickNotifier,
ActionClickLogger actionClickLogger) {
return new NotificationRemoteInputManager(
context,
@@ -85,6 +87,7 @@
statusBarStateController,
mainHandler,
remoteInputUriController,
+ clickNotifier,
actionClickLogger);
}
@@ -128,8 +131,10 @@
@Singleton
@Provides
static SmartReplyController provideSmartReplyController(
- NotificationEntryManager entryManager, IStatusBarService statusBarService) {
- return new SmartReplyController(entryManager, statusBarService);
+ NotificationEntryManager entryManager,
+ IStatusBarService statusBarService,
+ NotificationClickNotifier clickNotifier) {
+ return new SmartReplyController(entryManager, statusBarService, clickNotifier);
}
/** */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java
index 2beceb2..97ae83e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java
@@ -90,7 +90,7 @@
* @param removedByUser true if the notification was removed by a user action
*/
default void onEntryRemoved(
- NotificationEntry entry,
+ @NonNull NotificationEntry entry,
@Nullable NotificationVisibility visibility,
boolean removedByUser,
int reason) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java
index 0caf0dc..97c1523 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java
@@ -19,6 +19,8 @@
import static com.android.systemui.statusbar.notification.collection.NotifCollection.REASON_NOT_CANCELED;
import static com.android.systemui.statusbar.notification.collection.NotificationEntry.DismissState.NOT_DISMISSED;
+import com.android.systemui.statusbar.NotificationInteractionTracker;
+
import java.util.Arrays;
import java.util.List;
@@ -35,6 +37,7 @@
*/
public static String dumpTree(
List<ListEntry> entries,
+ NotificationInteractionTracker interactionTracker,
boolean includeRecordKeeping,
String indent) {
StringBuilder sb = new StringBuilder();
@@ -46,7 +49,8 @@
indent,
sb,
true,
- includeRecordKeeping);
+ includeRecordKeeping,
+ interactionTracker.hasUserInteractedWith(entry.getKey()));
if (entry instanceof GroupEntry) {
GroupEntry ge = (GroupEntry) entry;
List<NotificationEntry> children = ge.getChildren();
@@ -56,7 +60,8 @@
childEntryIndent,
sb,
true,
- includeRecordKeeping);
+ includeRecordKeeping,
+ interactionTracker.hasUserInteractedWith(entry.getKey()));
}
}
}
@@ -80,7 +85,8 @@
indent,
sb,
false,
- includeRecordKeeping);
+ includeRecordKeeping,
+ false);
}
return sb.toString();
}
@@ -91,7 +97,9 @@
String indent,
StringBuilder sb,
boolean includeParent,
- boolean includeRecordKeeping) {
+ boolean includeRecordKeeping,
+ boolean hasBeenInteractedWith
+ ) {
sb.append(indent)
.append("[").append(index).append("] ")
.append(entry.getKey());
@@ -157,6 +165,8 @@
.append(" ");
}
+ rksb.append("interacted=").append(hasBeenInteractedWith ? "yes" : "no").append(" ");
+
String rkString = rksb.toString();
if (!rkString.isEmpty()) {
sb.append("\n\t")
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
index 4cec383..9d81d35 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
@@ -36,6 +36,7 @@
import com.android.systemui.Dumpable;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.statusbar.NotificationInteractionTracker;
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;
@@ -73,6 +74,7 @@
public class ShadeListBuilder implements Dumpable {
private final SystemClock mSystemClock;
private final ShadeListBuilderLogger mLogger;
+ private final NotificationInteractionTracker mInteractionTracker;
private List<ListEntry> mNotifList = new ArrayList<>();
private List<ListEntry> mNewNotifList = new ArrayList<>();
@@ -105,10 +107,12 @@
public ShadeListBuilder(
SystemClock systemClock,
ShadeListBuilderLogger logger,
- DumpManager dumpManager) {
+ DumpManager dumpManager,
+ NotificationInteractionTracker interactionTracker) {
Assert.isMainThread();
mSystemClock = systemClock;
mLogger = logger;
+ mInteractionTracker = interactionTracker;
dumpManager.registerDumpable(TAG, this);
}
@@ -821,6 +825,7 @@
pw.println(ListDumper.dumpTree(
getShadeList(),
+ mInteractionTracker,
true,
"\t\t"));
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionListener.java
index 3fab6f7..75d772e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionListener.java
@@ -77,7 +77,7 @@
* the entry during this call. Instead, use {@link #onEntryRemoved} which will be called before
* deletion.
*/
- default void onEntryCleanUp(NotificationEntry entry) {
+ default void onEntryCleanUp(@NonNull NotificationEntry entry) {
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index 7924348..64e5f0a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -45,7 +45,6 @@
import android.view.View;
import com.android.internal.logging.MetricsLogger;
-import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.ActivityIntentHelper;
@@ -59,6 +58,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags;
+import com.android.systemui.statusbar.NotificationClickNotifier;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
@@ -103,7 +103,7 @@
private final NotifCollection mNotifCollection;
private final HeadsUpManagerPhone mHeadsUpManager;
private final ActivityStarter mActivityStarter;
- private final IStatusBarService mBarService;
+ private final NotificationClickNotifier mClickNotifier;
private final StatusBarStateController mStatusBarStateController;
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private final KeyguardManager mKeyguardManager;
@@ -142,7 +142,7 @@
NotifCollection notifCollection,
HeadsUpManagerPhone headsUpManager,
ActivityStarter activityStarter,
- IStatusBarService statusBarService,
+ NotificationClickNotifier clickNotifier,
StatusBarStateController statusBarStateController,
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
KeyguardManager keyguardManager,
@@ -177,7 +177,7 @@
mNotifCollection = notifCollection;
mHeadsUpManager = headsUpManager;
mActivityStarter = activityStarter;
- mBarService = statusBarService;
+ mClickNotifier = clickNotifier;
mStatusBarStateController = statusBarStateController;
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
mKeyguardManager = keyguardManager;
@@ -379,11 +379,7 @@
NotificationLogger.getNotificationLocation(entry);
final NotificationVisibility nv = NotificationVisibility.obtain(notificationKey,
rank, count, true, location);
- try {
- mBarService.onNotificationClick(notificationKey, nv);
- } catch (RemoteException ex) {
- // system process is dead if we're here.
- }
+ mClickNotifier.onNotificationClick(notificationKey, nv);
if (!isBubble) {
if (parentToCancelFinal != null) {
@@ -651,7 +647,7 @@
private final NotifCollection mNotifCollection;
private final HeadsUpManagerPhone mHeadsUpManager;
private final ActivityStarter mActivityStarter;
- private final IStatusBarService mStatusBarService;
+ private final NotificationClickNotifier mClickNotifier;
private final StatusBarStateController mStatusBarStateController;
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private final KeyguardManager mKeyguardManager;
@@ -689,7 +685,7 @@
NotifCollection notifCollection,
HeadsUpManagerPhone headsUpManager,
ActivityStarter activityStarter,
- IStatusBarService statusBarService,
+ NotificationClickNotifier clickNotifier,
StatusBarStateController statusBarStateController,
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
KeyguardManager keyguardManager,
@@ -720,7 +716,7 @@
mNotifCollection = notifCollection;
mHeadsUpManager = headsUpManager;
mActivityStarter = activityStarter;
- mStatusBarService = statusBarService;
+ mClickNotifier = clickNotifier;
mStatusBarStateController = statusBarStateController;
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
mKeyguardManager = keyguardManager;
@@ -777,7 +773,7 @@
mNotifCollection,
mHeadsUpManager,
mActivityStarter,
- mStatusBarService,
+ mClickNotifier,
mStatusBarStateController,
mStatusBarKeyguardViewManager,
mKeyguardManager,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
index 45f9437..805254c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
@@ -85,7 +85,8 @@
mFsc = new ForegroundServiceController(
mEntryManager, mAppOpsController, mMainHandler);
mListener = new ForegroundServiceNotificationListener(
- mContext, mFsc, mEntryManager, mNotifPipeline, mClock);
+ mContext, mFsc, mEntryManager, mNotifPipeline,
+ mock(ForegroundServiceLifetimeExtender.class), mClock);
ArgumentCaptor<NotificationEntryListener> entryListenerCaptor =
ArgumentCaptor.forClass(NotificationEntryListener.class);
verify(mEntryManager).addNotificationEntryListener(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceNotificationListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceNotificationListenerTest.java
index bca8dee..050b553 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceNotificationListenerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceNotificationListenerTest.java
@@ -26,6 +26,7 @@
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.systemui.statusbar.NotificationInteractionTracker;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.util.time.FakeSystemClock;
@@ -33,6 +34,8 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
@RunWith(AndroidJUnit4.class)
@SmallTest
@@ -42,9 +45,13 @@
private Notification mNotif;
private final FakeSystemClock mClock = new FakeSystemClock();
+ @Mock
+ private NotificationInteractionTracker mInteractionTracker;
+
@Before
public void setup() {
- mExtender = new ForegroundServiceLifetimeExtender(mClock);
+ MockitoAnnotations.initMocks(this);
+ mExtender = new ForegroundServiceLifetimeExtender(mInteractionTracker, mClock);
mNotif = new Notification.Builder(mContext, "")
.setSmallIcon(R.drawable.ic_person)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
index a24fa84..808f17b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
@@ -52,7 +52,6 @@
import androidx.test.filters.SmallTest;
-import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.Dependency;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -86,7 +85,7 @@
@Mock
private DevicePolicyManager mDevicePolicyManager;
@Mock
- private IStatusBarService mIStatusBarService;
+ private NotificationClickNotifier mClickNotifier;
@Mock
private KeyguardManager mKeyguardManager;
@Mock
@@ -397,7 +396,7 @@
extends NotificationLockscreenUserManagerImpl {
public TestNotificationLockscreenUserManager(Context context) {
super(context, mBroadcastDispatcher, mDevicePolicyManager, mUserManager,
- mIStatusBarService, NotificationLockscreenUserManagerTest.this.mKeyguardManager,
+ mClickNotifier, NotificationLockscreenUserManagerTest.this.mKeyguardManager,
mStatusBarStateController, Handler.createAsync(Looper.myLooper()),
mDeviceProvisionedController, mKeyguardStateController);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
index 5a7dea4..eaef43d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
@@ -62,6 +62,7 @@
@Mock private ExpandableNotificationRow mRow;
@Mock private StatusBarStateController mStateController;
@Mock private RemoteInputUriController mRemoteInputUriController;
+ @Mock private NotificationClickNotifier mClickNotifier;
// Dependency mocks:
@Mock private NotificationEntryManager mEntryManager;
@@ -83,6 +84,7 @@
mStateController,
Handler.createAsync(Looper.myLooper()),
mRemoteInputUriController,
+ mClickNotifier,
mock(ActionClickLogger.class));
mEntry = new NotificationEntryBuilder()
.setPkg(TEST_PACKAGE_NAME)
@@ -266,6 +268,7 @@
StatusBarStateController statusBarStateController,
Handler mainHandler,
RemoteInputUriController remoteInputUriController,
+ NotificationClickNotifier clickNotifier,
ActionClickLogger actionClickLogger) {
super(
context,
@@ -276,6 +279,7 @@
statusBarStateController,
mainHandler,
remoteInputUriController,
+ clickNotifier,
actionClickLogger);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
index 79507e9..7cbc4e4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
@@ -75,6 +75,7 @@
@Mock private IStatusBarService mIStatusBarService;
@Mock private StatusBarStateController mStatusBarStateController;
@Mock private RemoteInputUriController mRemoteInputUriController;
+ @Mock private NotificationClickNotifier mClickNotifier;
@Before
public void setUp() {
@@ -83,7 +84,7 @@
mNotificationEntryManager);
mSmartReplyController = new SmartReplyController(mNotificationEntryManager,
- mIStatusBarService);
+ mIStatusBarService, mClickNotifier);
mDependency.injectTestDependency(SmartReplyController.class,
mSmartReplyController);
@@ -93,6 +94,7 @@
mStatusBarStateController,
Handler.createAsync(Looper.myLooper()),
mRemoteInputUriController,
+ mClickNotifier,
mock(ActionClickLogger.class));
mRemoteInputManager.setUpWithCallback(mCallback, mDelegate);
mNotification = new Notification.Builder(mContext, "")
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java
index a93b54a..6fa5055 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java
@@ -44,6 +44,7 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.statusbar.NotificationInteractionTracker;
import com.android.systemui.statusbar.notification.collection.ShadeListBuilder.OnRenderListListener;
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeFinalizeFilterListener;
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener;
@@ -86,6 +87,7 @@
@Mock private ShadeListBuilderLogger mLogger;
@Mock private NotifCollection mNotifCollection;
+ @Mock private NotificationInteractionTracker mInteractionTracker;
@Spy private OnBeforeTransformGroupsListener mOnBeforeTransformGroupsListener;
@Spy private OnBeforeSortListener mOnBeforeSortListener;
@Spy private OnBeforeFinalizeFilterListener mOnBeforeFinalizeFilterListener;
@@ -107,7 +109,8 @@
MockitoAnnotations.initMocks(this);
allowTestableLooperAsMainThread();
- mListBuilder = new ShadeListBuilder(mSystemClock, mLogger, mock(DumpManager.class));
+ mListBuilder = new ShadeListBuilder(
+ mSystemClock, mLogger, mock(DumpManager.class), mInteractionTracker);
mListBuilder.setOnRenderListListener(mOnRenderListListener);
mListBuilder.attach(mNotifCollection);
@@ -1280,7 +1283,7 @@
} catch (AssertionError err) {
throw new AssertionError(
"List under test failed verification:\n" + dumpTree(mBuiltList,
- true, ""), err);
+ mInteractionTracker, true, ""), err);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index 1afe132..53a1773 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -48,7 +48,6 @@
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
-import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.ActivityIntentHelper;
@@ -59,6 +58,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags;
+import com.android.systemui.statusbar.NotificationClickNotifier;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
@@ -98,7 +98,7 @@
@Mock
private ActivityStarter mActivityStarter;
@Mock
- private IStatusBarService mStatusBarService;
+ private NotificationClickNotifier mClickNotifier;
@Mock
private StatusBarStateController mStatusBarStateController;
@Mock
@@ -188,7 +188,7 @@
mNotifCollection,
mock(HeadsUpManagerPhone.class),
mActivityStarter,
- mStatusBarService,
+ mClickNotifier,
mock(StatusBarStateController.class),
mStatusBarKeyguardViewManager,
mock(KeyguardManager.class),
@@ -263,7 +263,7 @@
verify(mAssistManager).hideAssist();
- verify(mStatusBarService).onNotificationClick(
+ verify(mClickNotifier).onNotificationClick(
eq(sbn.getKey()), any(NotificationVisibility.class));
// Notification is removed due to FLAG_AUTO_CANCEL
@@ -289,7 +289,7 @@
verify(mAssistManager).hideAssist();
- verify(mStatusBarService).onNotificationClick(
+ verify(mClickNotifier).onNotificationClick(
eq(sbn.getKey()), any(NotificationVisibility.class));
// The content intent should NOT be sent on click.
@@ -319,7 +319,7 @@
verify(mAssistManager).hideAssist();
- verify(mStatusBarService).onNotificationClick(
+ verify(mClickNotifier).onNotificationClick(
eq(sbn.getKey()), any(NotificationVisibility.class));
// The content intent should NOT be sent on click.
@@ -349,7 +349,7 @@
verify(mAssistManager).hideAssist();
- verify(mStatusBarService).onNotificationClick(
+ verify(mClickNotifier).onNotificationClick(
eq(sbn.getKey()), any(NotificationVisibility.class));
// The content intent should NOT be sent on click.