summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationClickNotifier.kt87
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationInteractionTracker.kt40
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionListener.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java22
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceNotificationListenerTest.java9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java14
20 files changed, 224 insertions, 64 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender.java
index e17d4e69093a..77abffc82d68 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.os.Looper;
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 @@ public class ForegroundServiceLifetimeExtender implements NotificationLifetimeEx
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 @@ public class ForegroundServiceLifetimeExtender implements NotificationLifetimeEx
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 ef1f4e0afede..650b9a7f9c0c 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
@@ -51,6 +51,7 @@ public class ForegroundServiceNotificationListener {
ForegroundServiceController foregroundServiceController,
NotificationEntryManager notificationEntryManager,
NotifPipeline notifPipeline,
+ ForegroundServiceLifetimeExtender fgsLifetimeExtender,
SystemClock systemClock) {
mContext = context;
mForegroundServiceController = foregroundServiceController;
@@ -78,8 +79,7 @@ public class ForegroundServiceNotificationListener {
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 000000000000..8248fc9f5844
--- /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 000000000000..2ed04eb088a3
--- /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 2baab61d861b..03424c4956ad 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.IntentSender;
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.Log;
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 @@ public class NotificationLockscreenUserManagerImpl implements
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 @@ public class NotificationLockscreenUserManagerImpl implements
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 @@ public class NotificationLockscreenUserManagerImpl implements
BroadcastDispatcher broadcastDispatcher,
DevicePolicyManager devicePolicyManager,
UserManager userManager,
- IStatusBarService iStatusBarService,
+ NotificationClickNotifier clickNotifier,
KeyguardManager keyguardManager,
StatusBarStateController statusBarStateController,
@Main Handler mainHandler,
@@ -214,7 +208,7 @@ public class NotificationLockscreenUserManagerImpl implements
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 9181c69e3722..a81c7d35c902 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 @@ public class NotificationRemoteInputManager implements Dumpable {
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 @@ public class NotificationRemoteInputManager implements Dumpable {
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 @@ public class NotificationRemoteInputManager implements Dumpable {
StatusBarStateController statusBarStateController,
@Main Handler mainHandler,
RemoteInputUriController remoteInputUriController,
+ NotificationClickNotifier clickNotifier,
ActionClickLogger logger) {
mContext = context;
mLockscreenUserManager = lockscreenUserManager;
@@ -290,6 +288,7 @@ public class NotificationRemoteInputManager implements Dumpable {
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 bb96f42758e6..7fc18b753d40 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 @@ import java.util.Set;
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 @@ public class SmartReplyController {
* 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 @@ public class SmartReplyController {
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 b08eb9fafe41..176e42667ab5 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.plugins.statusbar.StatusBarStateController;
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 @@ public interface StatusBarDependenciesModule {
StatusBarStateController statusBarStateController,
Handler mainHandler,
RemoteInputUriController remoteInputUriController,
+ NotificationClickNotifier clickNotifier,
ActionClickLogger actionClickLogger) {
return new NotificationRemoteInputManager(
context,
@@ -85,6 +87,7 @@ public interface StatusBarDependenciesModule {
statusBarStateController,
mainHandler,
remoteInputUriController,
+ clickNotifier,
actionClickLogger);
}
@@ -128,8 +131,10 @@ public interface StatusBarDependenciesModule {
@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 2beceb2c5e0a..97ae83ef3f6a 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 @@ public interface NotificationEntryListener {
* @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 0caf0dc4a3a3..97c1523887ad 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 @@ package com.android.systemui.statusbar.notification.collection;
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 class ListDumper {
*/
public static String dumpTree(
List<ListEntry> entries,
+ NotificationInteractionTracker interactionTracker,
boolean includeRecordKeeping,
String indent) {
StringBuilder sb = new StringBuilder();
@@ -46,7 +49,8 @@ public class ListDumper {
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 @@ public class ListDumper {
childEntryIndent,
sb,
true,
- includeRecordKeeping);
+ includeRecordKeeping,
+ interactionTracker.hasUserInteractedWith(entry.getKey()));
}
}
}
@@ -80,7 +85,8 @@ public class ListDumper {
indent,
sb,
false,
- includeRecordKeeping);
+ includeRecordKeeping,
+ false);
}
return sb.toString();
}
@@ -91,7 +97,9 @@ public class ListDumper {
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 @@ public class ListDumper {
.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 4cec383776b2..9d81d3563ebb 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 androidx.annotation.NonNull;
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 @@ import javax.inject.Singleton;
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 class ShadeListBuilder implements Dumpable {
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 @@ public class ShadeListBuilder implements Dumpable {
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 3fab6f7c3857..75d772e8a1c5 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 @@ public interface NotifCollectionListener {
* 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 7924348d34d4..64e5f0a8184e 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.RemoteAnimationAdapter;
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.ActivityStarter;
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 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
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 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
NotifCollection notifCollection,
HeadsUpManagerPhone headsUpManager,
ActivityStarter activityStarter,
- IStatusBarService statusBarService,
+ NotificationClickNotifier clickNotifier,
StatusBarStateController statusBarStateController,
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
KeyguardManager keyguardManager,
@@ -177,7 +177,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mNotifCollection = notifCollection;
mHeadsUpManager = headsUpManager;
mActivityStarter = activityStarter;
- mBarService = statusBarService;
+ mClickNotifier = clickNotifier;
mStatusBarStateController = statusBarStateController;
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
mKeyguardManager = keyguardManager;
@@ -379,11 +379,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
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 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
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 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
NotifCollection notifCollection,
HeadsUpManagerPhone headsUpManager,
ActivityStarter activityStarter,
- IStatusBarService statusBarService,
+ NotificationClickNotifier clickNotifier,
StatusBarStateController statusBarStateController,
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
KeyguardManager keyguardManager,
@@ -720,7 +716,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mNotifCollection = notifCollection;
mHeadsUpManager = headsUpManager;
mActivityStarter = activityStarter;
- mStatusBarService = statusBarService;
+ mClickNotifier = clickNotifier;
mStatusBarStateController = statusBarStateController;
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
mKeyguardManager = keyguardManager;
@@ -777,7 +773,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
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 45f9437efc15..805254cda175 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 @@ public class ForegroundServiceControllerTest extends SysuiTestCase {
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 bca8deeafd34..050b5538773d 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 android.app.Notification;
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 com.android.systemui.util.time.FakeSystemClock;
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 @@ public class ForegroundServiceNotificationListenerTest extends SysuiTestCase {
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 a24fa842eca7..808f17b8ba70 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 android.testing.TestableLooper;
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 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
@Mock
private DevicePolicyManager mDevicePolicyManager;
@Mock
- private IStatusBarService mIStatusBarService;
+ private NotificationClickNotifier mClickNotifier;
@Mock
private KeyguardManager mKeyguardManager;
@Mock
@@ -397,7 +396,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
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 5a7dea4de29c..eaef43d133af 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 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase {
@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 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase {
mStateController,
Handler.createAsync(Looper.myLooper()),
mRemoteInputUriController,
+ mClickNotifier,
mock(ActionClickLogger.class));
mEntry = new NotificationEntryBuilder()
.setPkg(TEST_PACKAGE_NAME)
@@ -266,6 +268,7 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase {
StatusBarStateController statusBarStateController,
Handler mainHandler,
RemoteInputUriController remoteInputUriController,
+ NotificationClickNotifier clickNotifier,
ActionClickLogger actionClickLogger) {
super(
context,
@@ -276,6 +279,7 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase {
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 79507e96ae02..7cbc4e4e2c62 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 @@ public class SmartReplyControllerTest extends SysuiTestCase {
@Mock private IStatusBarService mIStatusBarService;
@Mock private StatusBarStateController mStatusBarStateController;
@Mock private RemoteInputUriController mRemoteInputUriController;
+ @Mock private NotificationClickNotifier mClickNotifier;
@Before
public void setUp() {
@@ -83,7 +84,7 @@ public class SmartReplyControllerTest extends SysuiTestCase {
mNotificationEntryManager);
mSmartReplyController = new SmartReplyController(mNotificationEntryManager,
- mIStatusBarService);
+ mIStatusBarService, mClickNotifier);
mDependency.injectTestDependency(SmartReplyController.class,
mSmartReplyController);
@@ -93,6 +94,7 @@ public class SmartReplyControllerTest extends SysuiTestCase {
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 a93b54ac1009..6fa5055c875d 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 androidx.test.filters.SmallTest;
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 @@ public class ShadeListBuilderTest extends SysuiTestCase {
@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 @@ public class ShadeListBuilderTest extends SysuiTestCase {
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 @@ public class ShadeListBuilderTest extends SysuiTestCase {
} 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 1afe132f00a9..53a1773b1bd1 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 android.testing.TestableLooper;
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.ActivityStarter;
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 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
@Mock
private ActivityStarter mActivityStarter;
@Mock
- private IStatusBarService mStatusBarService;
+ private NotificationClickNotifier mClickNotifier;
@Mock
private StatusBarStateController mStatusBarStateController;
@Mock
@@ -188,7 +188,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
mNotifCollection,
mock(HeadsUpManagerPhone.class),
mActivityStarter,
- mStatusBarService,
+ mClickNotifier,
mock(StatusBarStateController.class),
mStatusBarKeyguardViewManager,
mock(KeyguardManager.class),
@@ -263,7 +263,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
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 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
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 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
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 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
verify(mAssistManager).hideAssist();
- verify(mStatusBarService).onNotificationClick(
+ verify(mClickNotifier).onNotificationClick(
eq(sbn.getKey()), any(NotificationVisibility.class));
// The content intent should NOT be sent on click.