Merge "Create a shim for StatusBarManager click methods" into rvc-dev am: a01520b395

Change-Id: I8ce3b663edce9350718a4daa1ce20c7ab5105f6c
This commit is contained in:
TreeHugger Robot
2020-05-20 21:00:50 +00:00
committed by Automerger Merge Worker
20 changed files with 224 additions and 64 deletions

View File

@@ -23,10 +23,13 @@ import android.os.Looper;
import android.util.ArraySet; import android.util.ArraySet;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.statusbar.NotificationInteractionTracker;
import com.android.systemui.statusbar.NotificationLifetimeExtender; import com.android.systemui.statusbar.NotificationLifetimeExtender;
import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.util.time.SystemClock; 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 * Extends the lifetime of foreground notification services such that they show for at least
* five seconds * five seconds
@@ -41,9 +44,14 @@ public class ForegroundServiceLifetimeExtender implements NotificationLifetimeEx
private ArraySet<NotificationEntry> mManagedEntries = new ArraySet<>(); private ArraySet<NotificationEntry> mManagedEntries = new ArraySet<>();
private Handler mHandler = new Handler(Looper.getMainLooper()); private Handler mHandler = new Handler(Looper.getMainLooper());
private final SystemClock mSystemClock; private final SystemClock mSystemClock;
private final NotificationInteractionTracker mInteractionTracker;
public ForegroundServiceLifetimeExtender(SystemClock systemClock) { @Inject
public ForegroundServiceLifetimeExtender(
NotificationInteractionTracker interactionTracker,
SystemClock systemClock) {
mSystemClock = systemClock; mSystemClock = systemClock;
mInteractionTracker = interactionTracker;
} }
@Override @Override
@@ -58,8 +66,9 @@ public class ForegroundServiceLifetimeExtender implements NotificationLifetimeEx
return false; return false;
} }
long currentTime = mSystemClock.uptimeMillis(); boolean hasInteracted = mInteractionTracker.hasUserInteractedWith(entry.getKey());
return currentTime - entry.getCreationTime() < MIN_FGS_TIME_MS; long aliveTime = mSystemClock.uptimeMillis() - entry.getCreationTime();
return aliveTime < MIN_FGS_TIME_MS && !hasInteracted;
} }
@Override @Override

View File

@@ -51,6 +51,7 @@ public class ForegroundServiceNotificationListener {
ForegroundServiceController foregroundServiceController, ForegroundServiceController foregroundServiceController,
NotificationEntryManager notificationEntryManager, NotificationEntryManager notificationEntryManager,
NotifPipeline notifPipeline, NotifPipeline notifPipeline,
ForegroundServiceLifetimeExtender fgsLifetimeExtender,
SystemClock systemClock) { SystemClock systemClock) {
mContext = context; mContext = context;
mForegroundServiceController = foregroundServiceController; mForegroundServiceController = foregroundServiceController;
@@ -78,8 +79,7 @@ public class ForegroundServiceNotificationListener {
removeNotification(entry.getSbn()); removeNotification(entry.getSbn());
} }
}); });
mEntryManager.addNotificationLifetimeExtender( mEntryManager.addNotificationLifetimeExtender(fgsLifetimeExtender);
new ForegroundServiceLifetimeExtender(systemClock));
notifPipeline.addCollectionListener(new NotifCollectionListener() { notifPipeline.addCollectionListener(new NotifCollectionListener() {
@Override @Override

View File

@@ -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"

View File

@@ -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"

View File

@@ -35,7 +35,6 @@ import android.content.IntentSender;
import android.content.pm.UserInfo; import android.content.pm.UserInfo;
import android.database.ContentObserver; import android.database.ContentObserver;
import android.os.Handler; import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
import android.provider.Settings; import android.provider.Settings;
@@ -43,7 +42,6 @@ import android.util.Log;
import android.util.SparseArray; import android.util.SparseArray;
import android.util.SparseBooleanArray; import android.util.SparseBooleanArray;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility; import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitor;
@@ -92,9 +90,9 @@ public class NotificationLockscreenUserManagerImpl implements
private final SparseBooleanArray mUsersAllowingPrivateNotifications = new SparseBooleanArray(); private final SparseBooleanArray mUsersAllowingPrivateNotifications = new SparseBooleanArray();
private final SparseBooleanArray mUsersAllowingNotifications = new SparseBooleanArray(); private final SparseBooleanArray mUsersAllowingNotifications = new SparseBooleanArray();
private final UserManager mUserManager; private final UserManager mUserManager;
private final IStatusBarService mBarService;
private final List<UserChangedListener> mListeners = new ArrayList<>(); private final List<UserChangedListener> mListeners = new ArrayList<>();
private final BroadcastDispatcher mBroadcastDispatcher; private final BroadcastDispatcher mBroadcastDispatcher;
private final NotificationClickNotifier mClickNotifier;
private boolean mShowLockscreenNotifications; private boolean mShowLockscreenNotifications;
private boolean mAllowLockscreenRemoteInput; private boolean mAllowLockscreenRemoteInput;
@@ -170,11 +168,7 @@ public class NotificationLockscreenUserManagerImpl implements
final NotificationVisibility nv = NotificationVisibility.obtain( final NotificationVisibility nv = NotificationVisibility.obtain(
notificationKey, notificationKey,
rank, count, true, location); rank, count, true, location);
try { mClickNotifier.onNotificationClick(notificationKey, nv);
mBarService.onNotificationClick(notificationKey, nv);
} catch (RemoteException exception) {
/* ignore */
}
} }
break; break;
} }
@@ -203,7 +197,7 @@ public class NotificationLockscreenUserManagerImpl implements
BroadcastDispatcher broadcastDispatcher, BroadcastDispatcher broadcastDispatcher,
DevicePolicyManager devicePolicyManager, DevicePolicyManager devicePolicyManager,
UserManager userManager, UserManager userManager,
IStatusBarService iStatusBarService, NotificationClickNotifier clickNotifier,
KeyguardManager keyguardManager, KeyguardManager keyguardManager,
StatusBarStateController statusBarStateController, StatusBarStateController statusBarStateController,
@Main Handler mainHandler, @Main Handler mainHandler,
@@ -214,7 +208,7 @@ public class NotificationLockscreenUserManagerImpl implements
mDevicePolicyManager = devicePolicyManager; mDevicePolicyManager = devicePolicyManager;
mUserManager = userManager; mUserManager = userManager;
mCurrentUserId = ActivityManager.getCurrentUser(); mCurrentUserId = ActivityManager.getCurrentUser();
mBarService = iStatusBarService; mClickNotifier = clickNotifier;
statusBarStateController.addCallback(this); statusBarStateController.addCallback(this);
mLockPatternUtils = new LockPatternUtils(context); mLockPatternUtils = new LockPatternUtils(context);
mKeyguardManager = keyguardManager; mKeyguardManager = keyguardManager;

View File

@@ -124,6 +124,7 @@ public class NotificationRemoteInputManager implements Dumpable {
private final KeyguardManager mKeyguardManager; private final KeyguardManager mKeyguardManager;
private final StatusBarStateController mStatusBarStateController; private final StatusBarStateController mStatusBarStateController;
private final RemoteInputUriController mRemoteInputUriController; private final RemoteInputUriController mRemoteInputUriController;
private final NotificationClickNotifier mClickNotifier;
protected RemoteInputController mRemoteInputController; protected RemoteInputController mRemoteInputController;
protected NotificationLifetimeExtender.NotificationSafeToRemoveCallback protected NotificationLifetimeExtender.NotificationSafeToRemoveCallback
@@ -215,11 +216,7 @@ public class NotificationRemoteInputManager implements Dumpable {
mEntryManager.getActiveNotificationUnfiltered(key)); mEntryManager.getActiveNotificationUnfiltered(key));
final NotificationVisibility nv = final NotificationVisibility nv =
NotificationVisibility.obtain(key, rank, count, true, location); NotificationVisibility.obtain(key, rank, count, true, location);
try { mClickNotifier.onNotificationActionClick(key, buttonIndex, action, nv, false);
mBarService.onNotificationActionClick(key, buttonIndex, action, nv, false);
} catch (RemoteException e) {
// Ignore
}
} }
private NotificationEntry getNotificationForParent(ViewParent parent) { private NotificationEntry getNotificationForParent(ViewParent parent) {
@@ -276,6 +273,7 @@ public class NotificationRemoteInputManager implements Dumpable {
StatusBarStateController statusBarStateController, StatusBarStateController statusBarStateController,
@Main Handler mainHandler, @Main Handler mainHandler,
RemoteInputUriController remoteInputUriController, RemoteInputUriController remoteInputUriController,
NotificationClickNotifier clickNotifier,
ActionClickLogger logger) { ActionClickLogger logger) {
mContext = context; mContext = context;
mLockscreenUserManager = lockscreenUserManager; mLockscreenUserManager = lockscreenUserManager;
@@ -291,6 +289,7 @@ public class NotificationRemoteInputManager implements Dumpable {
mKeyguardManager = context.getSystemService(KeyguardManager.class); mKeyguardManager = context.getSystemService(KeyguardManager.class);
mStatusBarStateController = statusBarStateController; mStatusBarStateController = statusBarStateController;
mRemoteInputUriController = remoteInputUriController; mRemoteInputUriController = remoteInputUriController;
mClickNotifier = clickNotifier;
notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() { notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
@Override @Override

View File

@@ -35,6 +35,7 @@ import java.util.Set;
public class SmartReplyController { public class SmartReplyController {
private final IStatusBarService mBarService; private final IStatusBarService mBarService;
private final NotificationEntryManager mEntryManager; private final NotificationEntryManager mEntryManager;
private final NotificationClickNotifier mClickNotifier;
private Set<String> mSendingKeys = new ArraySet<>(); private Set<String> mSendingKeys = new ArraySet<>();
private Callback mCallback; private Callback mCallback;
@@ -42,9 +43,11 @@ public class SmartReplyController {
* Injected constructor. See {@link StatusBarModule}. * Injected constructor. See {@link StatusBarModule}.
*/ */
public SmartReplyController(NotificationEntryManager entryManager, public SmartReplyController(NotificationEntryManager entryManager,
IStatusBarService statusBarService) { IStatusBarService statusBarService,
NotificationClickNotifier clickNotifier) {
mBarService = statusBarService; mBarService = statusBarService;
mEntryManager = entryManager; mEntryManager = entryManager;
mClickNotifier = clickNotifier;
} }
public void setCallback(Callback callback) { public void setCallback(Callback callback) {
@@ -78,12 +81,8 @@ public class SmartReplyController {
NotificationLogger.getNotificationLocation(entry); NotificationLogger.getNotificationLocation(entry);
final NotificationVisibility nv = NotificationVisibility.obtain( final NotificationVisibility nv = NotificationVisibility.obtain(
entry.getKey(), rank, count, true, location); entry.getKey(), rank, count, true, location);
try { mClickNotifier.onNotificationActionClick(
mBarService.onNotificationActionClick( entry.getKey(), actionIndex, action, nv, generatedByAssistant);
entry.getKey(), actionIndex, action, nv, generatedByAssistant);
} catch (RemoteException e) {
// Nothing to do, system going down
}
} }
/** /**

View File

@@ -29,6 +29,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.ActionClickLogger; import com.android.systemui.statusbar.ActionClickLogger;
import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.MediaArtworkProcessor; import com.android.systemui.statusbar.MediaArtworkProcessor;
import com.android.systemui.statusbar.NotificationClickNotifier;
import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.NotificationMediaManager;
@@ -77,6 +78,7 @@ public interface StatusBarDependenciesModule {
StatusBarStateController statusBarStateController, StatusBarStateController statusBarStateController,
Handler mainHandler, Handler mainHandler,
RemoteInputUriController remoteInputUriController, RemoteInputUriController remoteInputUriController,
NotificationClickNotifier clickNotifier,
ActionClickLogger actionClickLogger) { ActionClickLogger actionClickLogger) {
return new NotificationRemoteInputManager( return new NotificationRemoteInputManager(
context, context,
@@ -87,6 +89,7 @@ public interface StatusBarDependenciesModule {
statusBarStateController, statusBarStateController,
mainHandler, mainHandler,
remoteInputUriController, remoteInputUriController,
clickNotifier,
actionClickLogger); actionClickLogger);
} }
@@ -132,8 +135,10 @@ public interface StatusBarDependenciesModule {
@Singleton @Singleton
@Provides @Provides
static SmartReplyController provideSmartReplyController( static SmartReplyController provideSmartReplyController(
NotificationEntryManager entryManager, IStatusBarService statusBarService) { NotificationEntryManager entryManager,
return new SmartReplyController(entryManager, statusBarService); IStatusBarService statusBarService,
NotificationClickNotifier clickNotifier) {
return new SmartReplyController(entryManager, statusBarService, clickNotifier);
} }
/** */ /** */

View File

@@ -90,7 +90,7 @@ public interface NotificationEntryListener {
* @param removedByUser true if the notification was removed by a user action * @param removedByUser true if the notification was removed by a user action
*/ */
default void onEntryRemoved( default void onEntryRemoved(
NotificationEntry entry, @NonNull NotificationEntry entry,
@Nullable NotificationVisibility visibility, @Nullable NotificationVisibility visibility,
boolean removedByUser, boolean removedByUser,
int reason) { int reason) {

View File

@@ -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.NotifCollection.REASON_NOT_CANCELED;
import static com.android.systemui.statusbar.notification.collection.NotificationEntry.DismissState.NOT_DISMISSED; 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.Arrays;
import java.util.List; import java.util.List;
@@ -35,6 +37,7 @@ public class ListDumper {
*/ */
public static String dumpTree( public static String dumpTree(
List<ListEntry> entries, List<ListEntry> entries,
NotificationInteractionTracker interactionTracker,
boolean includeRecordKeeping, boolean includeRecordKeeping,
String indent) { String indent) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
@@ -46,7 +49,8 @@ public class ListDumper {
indent, indent,
sb, sb,
true, true,
includeRecordKeeping); includeRecordKeeping,
interactionTracker.hasUserInteractedWith(entry.getKey()));
if (entry instanceof GroupEntry) { if (entry instanceof GroupEntry) {
GroupEntry ge = (GroupEntry) entry; GroupEntry ge = (GroupEntry) entry;
List<NotificationEntry> children = ge.getChildren(); List<NotificationEntry> children = ge.getChildren();
@@ -56,7 +60,8 @@ public class ListDumper {
childEntryIndent, childEntryIndent,
sb, sb,
true, true,
includeRecordKeeping); includeRecordKeeping,
interactionTracker.hasUserInteractedWith(entry.getKey()));
} }
} }
} }
@@ -80,7 +85,8 @@ public class ListDumper {
indent, indent,
sb, sb,
false, false,
includeRecordKeeping); includeRecordKeeping,
false);
} }
return sb.toString(); return sb.toString();
} }
@@ -91,7 +97,9 @@ public class ListDumper {
String indent, String indent,
StringBuilder sb, StringBuilder sb,
boolean includeParent, boolean includeParent,
boolean includeRecordKeeping) { boolean includeRecordKeeping,
boolean hasBeenInteractedWith
) {
sb.append(indent) sb.append(indent)
.append("[").append(index).append("] ") .append("[").append(index).append("] ")
.append(entry.getKey()); .append(entry.getKey());
@@ -157,6 +165,8 @@ public class ListDumper {
.append(" "); .append(" ");
} }
rksb.append("interacted=").append(hasBeenInteractedWith ? "yes" : "no").append(" ");
String rkString = rksb.toString(); String rkString = rksb.toString();
if (!rkString.isEmpty()) { if (!rkString.isEmpty()) {
sb.append("\n\t") sb.append("\n\t")

View File

@@ -36,6 +36,7 @@ import androidx.annotation.NonNull;
import com.android.systemui.Dumpable; import com.android.systemui.Dumpable;
import com.android.systemui.dump.DumpManager; 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.OnBeforeFinalizeFilterListener;
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener; 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.OnBeforeSortListener;
@@ -73,6 +74,7 @@ import javax.inject.Singleton;
public class ShadeListBuilder implements Dumpable { public class ShadeListBuilder implements Dumpable {
private final SystemClock mSystemClock; private final SystemClock mSystemClock;
private final ShadeListBuilderLogger mLogger; private final ShadeListBuilderLogger mLogger;
private final NotificationInteractionTracker mInteractionTracker;
private List<ListEntry> mNotifList = new ArrayList<>(); private List<ListEntry> mNotifList = new ArrayList<>();
private List<ListEntry> mNewNotifList = new ArrayList<>(); private List<ListEntry> mNewNotifList = new ArrayList<>();
@@ -105,10 +107,12 @@ public class ShadeListBuilder implements Dumpable {
public ShadeListBuilder( public ShadeListBuilder(
SystemClock systemClock, SystemClock systemClock,
ShadeListBuilderLogger logger, ShadeListBuilderLogger logger,
DumpManager dumpManager) { DumpManager dumpManager,
NotificationInteractionTracker interactionTracker) {
Assert.isMainThread(); Assert.isMainThread();
mSystemClock = systemClock; mSystemClock = systemClock;
mLogger = logger; mLogger = logger;
mInteractionTracker = interactionTracker;
dumpManager.registerDumpable(TAG, this); dumpManager.registerDumpable(TAG, this);
} }
@@ -821,6 +825,7 @@ public class ShadeListBuilder implements Dumpable {
pw.println(ListDumper.dumpTree( pw.println(ListDumper.dumpTree(
getShadeList(), getShadeList(),
mInteractionTracker,
true, true,
"\t\t")); "\t\t"));
} }

View File

@@ -77,7 +77,7 @@ public interface NotifCollectionListener {
* the entry during this call. Instead, use {@link #onEntryRemoved} which will be called before * the entry during this call. Instead, use {@link #onEntryRemoved} which will be called before
* deletion. * deletion.
*/ */
default void onEntryCleanUp(NotificationEntry entry) { default void onEntryCleanUp(@NonNull NotificationEntry entry) {
} }
/** /**

View File

@@ -45,7 +45,6 @@ import android.view.RemoteAnimationAdapter;
import android.view.View; import android.view.View;
import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility; import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.ActivityIntentHelper; 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.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NotificationClickNotifier;
import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationRemoteInputManager;
@@ -103,7 +103,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
private final NotifCollection mNotifCollection; private final NotifCollection mNotifCollection;
private final HeadsUpManagerPhone mHeadsUpManager; private final HeadsUpManagerPhone mHeadsUpManager;
private final ActivityStarter mActivityStarter; private final ActivityStarter mActivityStarter;
private final IStatusBarService mBarService; private final NotificationClickNotifier mClickNotifier;
private final StatusBarStateController mStatusBarStateController; private final StatusBarStateController mStatusBarStateController;
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private final KeyguardManager mKeyguardManager; private final KeyguardManager mKeyguardManager;
@@ -142,7 +142,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
NotifCollection notifCollection, NotifCollection notifCollection,
HeadsUpManagerPhone headsUpManager, HeadsUpManagerPhone headsUpManager,
ActivityStarter activityStarter, ActivityStarter activityStarter,
IStatusBarService statusBarService, NotificationClickNotifier clickNotifier,
StatusBarStateController statusBarStateController, StatusBarStateController statusBarStateController,
StatusBarKeyguardViewManager statusBarKeyguardViewManager, StatusBarKeyguardViewManager statusBarKeyguardViewManager,
KeyguardManager keyguardManager, KeyguardManager keyguardManager,
@@ -177,7 +177,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mNotifCollection = notifCollection; mNotifCollection = notifCollection;
mHeadsUpManager = headsUpManager; mHeadsUpManager = headsUpManager;
mActivityStarter = activityStarter; mActivityStarter = activityStarter;
mBarService = statusBarService; mClickNotifier = clickNotifier;
mStatusBarStateController = statusBarStateController; mStatusBarStateController = statusBarStateController;
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
mKeyguardManager = keyguardManager; mKeyguardManager = keyguardManager;
@@ -379,11 +379,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
NotificationLogger.getNotificationLocation(entry); NotificationLogger.getNotificationLocation(entry);
final NotificationVisibility nv = NotificationVisibility.obtain(notificationKey, final NotificationVisibility nv = NotificationVisibility.obtain(notificationKey,
rank, count, true, location); rank, count, true, location);
try { mClickNotifier.onNotificationClick(notificationKey, nv);
mBarService.onNotificationClick(notificationKey, nv);
} catch (RemoteException ex) {
// system process is dead if we're here.
}
if (!isBubble) { if (!isBubble) {
if (parentToCancelFinal != null) { if (parentToCancelFinal != null) {
@@ -651,7 +647,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
private final NotifCollection mNotifCollection; private final NotifCollection mNotifCollection;
private final HeadsUpManagerPhone mHeadsUpManager; private final HeadsUpManagerPhone mHeadsUpManager;
private final ActivityStarter mActivityStarter; private final ActivityStarter mActivityStarter;
private final IStatusBarService mStatusBarService; private final NotificationClickNotifier mClickNotifier;
private final StatusBarStateController mStatusBarStateController; private final StatusBarStateController mStatusBarStateController;
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private final KeyguardManager mKeyguardManager; private final KeyguardManager mKeyguardManager;
@@ -689,7 +685,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
NotifCollection notifCollection, NotifCollection notifCollection,
HeadsUpManagerPhone headsUpManager, HeadsUpManagerPhone headsUpManager,
ActivityStarter activityStarter, ActivityStarter activityStarter,
IStatusBarService statusBarService, NotificationClickNotifier clickNotifier,
StatusBarStateController statusBarStateController, StatusBarStateController statusBarStateController,
StatusBarKeyguardViewManager statusBarKeyguardViewManager, StatusBarKeyguardViewManager statusBarKeyguardViewManager,
KeyguardManager keyguardManager, KeyguardManager keyguardManager,
@@ -720,7 +716,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mNotifCollection = notifCollection; mNotifCollection = notifCollection;
mHeadsUpManager = headsUpManager; mHeadsUpManager = headsUpManager;
mActivityStarter = activityStarter; mActivityStarter = activityStarter;
mStatusBarService = statusBarService; mClickNotifier = clickNotifier;
mStatusBarStateController = statusBarStateController; mStatusBarStateController = statusBarStateController;
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
mKeyguardManager = keyguardManager; mKeyguardManager = keyguardManager;
@@ -777,7 +773,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mNotifCollection, mNotifCollection,
mHeadsUpManager, mHeadsUpManager,
mActivityStarter, mActivityStarter,
mStatusBarService, mClickNotifier,
mStatusBarStateController, mStatusBarStateController,
mStatusBarKeyguardViewManager, mStatusBarKeyguardViewManager,
mKeyguardManager, mKeyguardManager,

View File

@@ -85,7 +85,8 @@ public class ForegroundServiceControllerTest extends SysuiTestCase {
mFsc = new ForegroundServiceController( mFsc = new ForegroundServiceController(
mEntryManager, mAppOpsController, mMainHandler); mEntryManager, mAppOpsController, mMainHandler);
mListener = new ForegroundServiceNotificationListener( mListener = new ForegroundServiceNotificationListener(
mContext, mFsc, mEntryManager, mNotifPipeline, mClock); mContext, mFsc, mEntryManager, mNotifPipeline,
mock(ForegroundServiceLifetimeExtender.class), mClock);
ArgumentCaptor<NotificationEntryListener> entryListenerCaptor = ArgumentCaptor<NotificationEntryListener> entryListenerCaptor =
ArgumentCaptor.forClass(NotificationEntryListener.class); ArgumentCaptor.forClass(NotificationEntryListener.class);
verify(mEntryManager).addNotificationEntryListener( verify(mEntryManager).addNotificationEntryListener(

View File

@@ -26,6 +26,7 @@ import android.app.Notification;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4; 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.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.util.time.FakeSystemClock; 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.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@SmallTest @SmallTest
@@ -42,9 +45,13 @@ public class ForegroundServiceNotificationListenerTest extends SysuiTestCase {
private Notification mNotif; private Notification mNotif;
private final FakeSystemClock mClock = new FakeSystemClock(); private final FakeSystemClock mClock = new FakeSystemClock();
@Mock
private NotificationInteractionTracker mInteractionTracker;
@Before @Before
public void setup() { public void setup() {
mExtender = new ForegroundServiceLifetimeExtender(mClock); MockitoAnnotations.initMocks(this);
mExtender = new ForegroundServiceLifetimeExtender(mInteractionTracker, mClock);
mNotif = new Notification.Builder(mContext, "") mNotif = new Notification.Builder(mContext, "")
.setSmallIcon(R.drawable.ic_person) .setSmallIcon(R.drawable.ic_person)

View File

@@ -52,7 +52,6 @@ import android.testing.TestableLooper;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.Dependency; import com.android.systemui.Dependency;
import com.android.systemui.SysuiTestCase; import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -86,7 +85,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
@Mock @Mock
private DevicePolicyManager mDevicePolicyManager; private DevicePolicyManager mDevicePolicyManager;
@Mock @Mock
private IStatusBarService mIStatusBarService; private NotificationClickNotifier mClickNotifier;
@Mock @Mock
private KeyguardManager mKeyguardManager; private KeyguardManager mKeyguardManager;
@Mock @Mock
@@ -397,7 +396,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
extends NotificationLockscreenUserManagerImpl { extends NotificationLockscreenUserManagerImpl {
public TestNotificationLockscreenUserManager(Context context) { public TestNotificationLockscreenUserManager(Context context) {
super(context, mBroadcastDispatcher, mDevicePolicyManager, mUserManager, super(context, mBroadcastDispatcher, mDevicePolicyManager, mUserManager,
mIStatusBarService, NotificationLockscreenUserManagerTest.this.mKeyguardManager, mClickNotifier, NotificationLockscreenUserManagerTest.this.mKeyguardManager,
mStatusBarStateController, Handler.createAsync(Looper.myLooper()), mStatusBarStateController, Handler.createAsync(Looper.myLooper()),
mDeviceProvisionedController, mKeyguardStateController); mDeviceProvisionedController, mKeyguardStateController);
} }

View File

@@ -62,6 +62,7 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase {
@Mock private ExpandableNotificationRow mRow; @Mock private ExpandableNotificationRow mRow;
@Mock private StatusBarStateController mStateController; @Mock private StatusBarStateController mStateController;
@Mock private RemoteInputUriController mRemoteInputUriController; @Mock private RemoteInputUriController mRemoteInputUriController;
@Mock private NotificationClickNotifier mClickNotifier;
// Dependency mocks: // Dependency mocks:
@Mock private NotificationEntryManager mEntryManager; @Mock private NotificationEntryManager mEntryManager;
@@ -83,6 +84,7 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase {
mStateController, mStateController,
Handler.createAsync(Looper.myLooper()), Handler.createAsync(Looper.myLooper()),
mRemoteInputUriController, mRemoteInputUriController,
mClickNotifier,
mock(ActionClickLogger.class)); mock(ActionClickLogger.class));
mEntry = new NotificationEntryBuilder() mEntry = new NotificationEntryBuilder()
.setPkg(TEST_PACKAGE_NAME) .setPkg(TEST_PACKAGE_NAME)
@@ -266,6 +268,7 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase {
StatusBarStateController statusBarStateController, StatusBarStateController statusBarStateController,
Handler mainHandler, Handler mainHandler,
RemoteInputUriController remoteInputUriController, RemoteInputUriController remoteInputUriController,
NotificationClickNotifier clickNotifier,
ActionClickLogger actionClickLogger) { ActionClickLogger actionClickLogger) {
super( super(
context, context,
@@ -276,6 +279,7 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase {
statusBarStateController, statusBarStateController,
mainHandler, mainHandler,
remoteInputUriController, remoteInputUriController,
clickNotifier,
actionClickLogger); actionClickLogger);
} }

View File

@@ -75,6 +75,7 @@ public class SmartReplyControllerTest extends SysuiTestCase {
@Mock private IStatusBarService mIStatusBarService; @Mock private IStatusBarService mIStatusBarService;
@Mock private StatusBarStateController mStatusBarStateController; @Mock private StatusBarStateController mStatusBarStateController;
@Mock private RemoteInputUriController mRemoteInputUriController; @Mock private RemoteInputUriController mRemoteInputUriController;
@Mock private NotificationClickNotifier mClickNotifier;
@Before @Before
public void setUp() { public void setUp() {
@@ -83,7 +84,7 @@ public class SmartReplyControllerTest extends SysuiTestCase {
mNotificationEntryManager); mNotificationEntryManager);
mSmartReplyController = new SmartReplyController(mNotificationEntryManager, mSmartReplyController = new SmartReplyController(mNotificationEntryManager,
mIStatusBarService); mIStatusBarService, mClickNotifier);
mDependency.injectTestDependency(SmartReplyController.class, mDependency.injectTestDependency(SmartReplyController.class,
mSmartReplyController); mSmartReplyController);
@@ -93,6 +94,7 @@ public class SmartReplyControllerTest extends SysuiTestCase {
mStatusBarStateController, mStatusBarStateController,
Handler.createAsync(Looper.myLooper()), Handler.createAsync(Looper.myLooper()),
mRemoteInputUriController, mRemoteInputUriController,
mClickNotifier,
mock(ActionClickLogger.class)); mock(ActionClickLogger.class));
mRemoteInputManager.setUpWithCallback(mCallback, mDelegate); mRemoteInputManager.setUpWithCallback(mCallback, mDelegate);
mNotification = new Notification.Builder(mContext, "") mNotification = new Notification.Builder(mContext, "")

View File

@@ -44,6 +44,7 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase; import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager; 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.ShadeListBuilder.OnRenderListListener;
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeFinalizeFilterListener; 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.OnBeforeRenderListListener;
@@ -86,6 +87,7 @@ public class ShadeListBuilderTest extends SysuiTestCase {
@Mock private ShadeListBuilderLogger mLogger; @Mock private ShadeListBuilderLogger mLogger;
@Mock private NotifCollection mNotifCollection; @Mock private NotifCollection mNotifCollection;
@Mock private NotificationInteractionTracker mInteractionTracker;
@Spy private OnBeforeTransformGroupsListener mOnBeforeTransformGroupsListener; @Spy private OnBeforeTransformGroupsListener mOnBeforeTransformGroupsListener;
@Spy private OnBeforeSortListener mOnBeforeSortListener; @Spy private OnBeforeSortListener mOnBeforeSortListener;
@Spy private OnBeforeFinalizeFilterListener mOnBeforeFinalizeFilterListener; @Spy private OnBeforeFinalizeFilterListener mOnBeforeFinalizeFilterListener;
@@ -107,7 +109,8 @@ public class ShadeListBuilderTest extends SysuiTestCase {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
allowTestableLooperAsMainThread(); allowTestableLooperAsMainThread();
mListBuilder = new ShadeListBuilder(mSystemClock, mLogger, mock(DumpManager.class)); mListBuilder = new ShadeListBuilder(
mSystemClock, mLogger, mock(DumpManager.class), mInteractionTracker);
mListBuilder.setOnRenderListListener(mOnRenderListListener); mListBuilder.setOnRenderListListener(mOnRenderListListener);
mListBuilder.attach(mNotifCollection); mListBuilder.attach(mNotifCollection);
@@ -1280,7 +1283,7 @@ public class ShadeListBuilderTest extends SysuiTestCase {
} catch (AssertionError err) { } catch (AssertionError err) {
throw new AssertionError( throw new AssertionError(
"List under test failed verification:\n" + dumpTree(mBuiltList, "List under test failed verification:\n" + dumpTree(mBuiltList,
true, ""), err); mInteractionTracker, true, ""), err);
} }
} }

View File

@@ -48,7 +48,6 @@ import android.testing.TestableLooper;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility; import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.ActivityIntentHelper; 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.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NotificationClickNotifier;
import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationRemoteInputManager;
@@ -98,7 +98,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
@Mock @Mock
private ActivityStarter mActivityStarter; private ActivityStarter mActivityStarter;
@Mock @Mock
private IStatusBarService mStatusBarService; private NotificationClickNotifier mClickNotifier;
@Mock @Mock
private StatusBarStateController mStatusBarStateController; private StatusBarStateController mStatusBarStateController;
@Mock @Mock
@@ -188,7 +188,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
mNotifCollection, mNotifCollection,
mock(HeadsUpManagerPhone.class), mock(HeadsUpManagerPhone.class),
mActivityStarter, mActivityStarter,
mStatusBarService, mClickNotifier,
mock(StatusBarStateController.class), mock(StatusBarStateController.class),
mStatusBarKeyguardViewManager, mStatusBarKeyguardViewManager,
mock(KeyguardManager.class), mock(KeyguardManager.class),
@@ -263,7 +263,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
verify(mAssistManager).hideAssist(); verify(mAssistManager).hideAssist();
verify(mStatusBarService).onNotificationClick( verify(mClickNotifier).onNotificationClick(
eq(sbn.getKey()), any(NotificationVisibility.class)); eq(sbn.getKey()), any(NotificationVisibility.class));
// Notification is removed due to FLAG_AUTO_CANCEL // Notification is removed due to FLAG_AUTO_CANCEL
@@ -289,7 +289,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
verify(mAssistManager).hideAssist(); verify(mAssistManager).hideAssist();
verify(mStatusBarService).onNotificationClick( verify(mClickNotifier).onNotificationClick(
eq(sbn.getKey()), any(NotificationVisibility.class)); eq(sbn.getKey()), any(NotificationVisibility.class));
// The content intent should NOT be sent on click. // The content intent should NOT be sent on click.
@@ -319,7 +319,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
verify(mAssistManager).hideAssist(); verify(mAssistManager).hideAssist();
verify(mStatusBarService).onNotificationClick( verify(mClickNotifier).onNotificationClick(
eq(sbn.getKey()), any(NotificationVisibility.class)); eq(sbn.getKey()), any(NotificationVisibility.class));
// The content intent should NOT be sent on click. // The content intent should NOT be sent on click.
@@ -349,7 +349,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
verify(mAssistManager).hideAssist(); verify(mAssistManager).hideAssist();
verify(mStatusBarService).onNotificationClick( verify(mClickNotifier).onNotificationClick(
eq(sbn.getKey()), any(NotificationVisibility.class)); eq(sbn.getKey()), any(NotificationVisibility.class));
// The content intent should NOT be sent on click. // The content intent should NOT be sent on click.