Show snoozed conversations in conversation header
- And allow them to be unsnoozed with a tap.
- Also use the conversation's shortcut icon and name if available.
- And ignore the setting to turn off the strips since it now requires
explicit user action to make the strip visible
Note 1: unsnoozing a notification causes it to make sound again - we
probably want to change that for manually unsnoozed things
Note 2: the entries in the header don't yet persist across a reboot
Test: atest, manual
Bug: 149486431
Change-Id: Id661c25a49bc982e39deab977eb912f51eaf6757
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 6562572..0cd96b8 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -19,6 +19,7 @@
import android.annotation.CurrentTimeMillisLong;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.SystemApi;
import android.annotation.TestApi;
@@ -37,6 +38,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.ParceledListSlice;
+import android.content.pm.ShortcutInfo;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
@@ -53,6 +55,7 @@
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Log;
+import android.util.Slog;
import android.widget.RemoteViews;
import com.android.internal.annotations.GuardedBy;
@@ -1566,6 +1569,7 @@
private boolean mCanBubble;
private boolean mVisuallyInterruptive;
private boolean mIsConversation;
+ private ShortcutInfo mShortcutInfo;
private static final int PARCEL_VERSION = 2;
@@ -1599,6 +1603,7 @@
out.writeBoolean(mCanBubble);
out.writeBoolean(mVisuallyInterruptive);
out.writeBoolean(mIsConversation);
+ out.writeParcelable(mShortcutInfo, flags);
}
/** @hide */
@@ -1620,7 +1625,7 @@
mImportance = in.readInt();
mImportanceExplanation = in.readCharSequence(); // may be null
mOverrideGroupKey = in.readString(); // may be null
- mChannel = (NotificationChannel) in.readParcelable(cl); // may be null
+ mChannel = in.readParcelable(cl); // may be null
mOverridePeople = in.createStringArrayList();
mSnoozeCriteria = in.createTypedArrayList(SnoozeCriterion.CREATOR);
mShowBadge = in.readBoolean();
@@ -1633,6 +1638,7 @@
mCanBubble = in.readBoolean();
mVisuallyInterruptive = in.readBoolean();
mIsConversation = in.readBoolean();
+ mShortcutInfo = in.readParcelable(cl);
}
@@ -1840,6 +1846,13 @@
/**
* @hide
*/
+ public @Nullable ShortcutInfo getShortcutInfo() {
+ return mShortcutInfo;
+ }
+
+ /**
+ * @hide
+ */
@VisibleForTesting
public void populate(String key, int rank, boolean matchesInterruptionFilter,
int visibilityOverride, int suppressedVisualEffects, int importance,
@@ -1849,7 +1862,7 @@
int userSentiment, boolean hidden, long lastAudiblyAlertedMs,
boolean noisy, ArrayList<Notification.Action> smartActions,
ArrayList<CharSequence> smartReplies, boolean canBubble,
- boolean visuallyInterruptive, boolean isConversation) {
+ boolean visuallyInterruptive, boolean isConversation, ShortcutInfo shortcutInfo) {
mKey = key;
mRank = rank;
mIsAmbient = importance < NotificationManager.IMPORTANCE_LOW;
@@ -1872,6 +1885,7 @@
mCanBubble = canBubble;
mVisuallyInterruptive = visuallyInterruptive;
mIsConversation = isConversation;
+ mShortcutInfo = shortcutInfo;
}
/**
@@ -1898,7 +1912,8 @@
other.mSmartReplies,
other.mCanBubble,
other.mVisuallyInterruptive,
- other.mIsConversation);
+ other.mIsConversation,
+ other.mShortcutInfo);
}
/**
@@ -1952,7 +1967,10 @@
&& Objects.equals(mSmartReplies, other.mSmartReplies)
&& Objects.equals(mCanBubble, other.mCanBubble)
&& Objects.equals(mVisuallyInterruptive, other.mVisuallyInterruptive)
- && Objects.equals(mIsConversation, other.mIsConversation);
+ && Objects.equals(mIsConversation, other.mIsConversation)
+ // Shortcutinfo doesn't have equals either; use id
+ && Objects.equals((mShortcutInfo == null ? 0 : mShortcutInfo.getId()),
+ (other.mShortcutInfo == null ? 0 : other.mShortcutInfo.getId()));
}
}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/NotificationPersonExtractorPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/NotificationPersonExtractorPlugin.java
index 6650c15..f79cd86 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/NotificationPersonExtractorPlugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/NotificationPersonExtractorPlugin.java
@@ -68,14 +68,14 @@
public final String key;
public final CharSequence name;
public final Drawable avatar;
- public final PendingIntent clickIntent;
+ public final Runnable clickRunnable;
public PersonData(String key, CharSequence name, Drawable avatar,
- PendingIntent clickIntent) {
+ Runnable clickRunnable) {
this.key = key;
this.name = name;
this.avatar = avatar;
- this.clickIntent = clickIntent;
+ this.clickRunnable = clickRunnable;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
index 924d16d..f01fa81 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
@@ -71,7 +71,8 @@
public void onEntryRemoved(
NotificationEntry entry,
NotificationVisibility visibility,
- boolean removedByUser) {
+ boolean removedByUser,
+ int reason) {
removeNotification(entry.getSbn());
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index a220dac..48457f6 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -425,7 +425,8 @@
public void onEntryRemoved(
NotificationEntry entry,
@android.annotation.Nullable NotificationVisibility visibility,
- boolean removedByUser) {
+ boolean removedByUser,
+ int reason) {
BubbleController.this.onEntryRemoved(entry);
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java
index 352ee33..1ec979c 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java
@@ -30,6 +30,8 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.IPackageManager;
+import android.content.pm.LauncherApps;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.hardware.SensorPrivacyManager;
import android.media.AudioManager;
@@ -167,6 +169,12 @@
return LatencyTracker.getInstance(context);
}
+ @Singleton
+ @Provides
+ static LauncherApps provideLauncherApps(Context context) {
+ return context.getSystemService(LauncherApps.class);
+ }
+
@SuppressLint("MissingPermission")
@Singleton
@Provides
@@ -184,6 +192,12 @@
@Singleton
@Provides
+ static PackageManager providePackageManager(Context context) {
+ return context.getPackageManager();
+ }
+
+ @Singleton
+ @Provides
static PackageManagerWrapper providePackageManagerWrapper() {
return PackageManagerWrapper.getInstance();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
index b43fe73..047edd2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
@@ -20,6 +20,7 @@
import static com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON;
import static com.android.systemui.statusbar.phone.StatusBar.DEBUG;
+import android.annotation.NonNull;
import android.annotation.SuppressLint;
import android.app.NotificationManager;
import android.content.ComponentName;
@@ -161,6 +162,15 @@
}
}
+ public final void unsnoozeNotification(@NonNull String key) {
+ if (!isBound()) return;
+ try {
+ getNotificationInterface().unsnoozeNotificationFromSystemListener(mWrapper, key);
+ } catch (android.os.RemoteException ex) {
+ Log.v(TAG, "Unable to contact notification manager", ex);
+ }
+ }
+
public void registerAsSystemService() {
try {
registerAsSystemService(mContext,
@@ -195,7 +205,8 @@
new ArrayList<>(),
false,
false,
- false
+ false,
+ null
);
}
return ranking;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index cdb2c53..3d7beea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -214,7 +214,8 @@
public void onEntryRemoved(
NotificationEntry entry,
NotificationVisibility visibility,
- boolean removedByUser) {
+ boolean removedByUser,
+ int reason) {
onNotificationRemoved(entry.getKey());
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index ebc2fa6..bf28040 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -292,7 +292,8 @@
public void onEntryRemoved(
@Nullable NotificationEntry entry,
NotificationVisibility visibility,
- boolean removedByUser) {
+ boolean removedByUser,
+ int reason) {
// We're removing the notification, the smart controller can forget about it.
mSmartReplyController.stopSending(entry);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java
index 07cf9d9..df21f0b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java
@@ -77,7 +77,8 @@
public void onEntryRemoved(
NotificationEntry entry,
NotificationVisibility visibility,
- boolean removedByUser) {
+ boolean removedByUser,
+ int reason) {
stopAlerting(entry.getKey());
}
});
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 25253a1..2beceb2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java
@@ -92,7 +92,8 @@
default void onEntryRemoved(
NotificationEntry entry,
@Nullable NotificationVisibility visibility,
- boolean removedByUser) {
+ boolean removedByUser,
+ int reason) {
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index 5ebd368..7f0479c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -477,7 +477,7 @@
mLogger.logNotifRemoved(entry.getKey(), removedByUser);
for (NotificationEntryListener listener : mNotificationEntryListeners) {
- listener.onEntryRemoved(entry, visibility, removedByUser);
+ listener.onEntryRemoved(entry, visibility, removedByUser, reason);
}
for (NotifCollectionListener listener : mNotifCollectionListeners) {
// NEM doesn't have a good knowledge of reasons so defaulting to unknown.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java
index f2765db..c9c6f28 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java
@@ -59,7 +59,8 @@
public void onEntryRemoved(
NotificationEntry entry,
NotificationVisibility visibility,
- boolean removedByUser) {
+ boolean removedByUser,
+ int reason) {
mListContainer.cleanUpViewStateForEntry(entry);
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index 25a832d..3e9d8a4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -153,6 +153,7 @@
public String remoteInputMimeType;
public Uri remoteInputUri;
private Notification.BubbleMetadata mBubbleMetadata;
+ private ShortcutInfo mShortcutInfo;
/**
* If {@link android.app.RemoteInput#getEditChoicesBeforeSending} is enabled, and the user is
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
index becb758..6e161c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
@@ -213,7 +213,8 @@
public void onEntryRemoved(
NotificationEntry entry,
NotificationVisibility visibility,
- boolean removedByUser) {
+ boolean removedByUser,
+ int reason) {
if (removedByUser && visibility != null) {
logNotificationClear(entry.getKey(), entry.getSbn(), visibility);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHub.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHub.kt
index 2a02c19..3007198 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHub.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHub.kt
@@ -47,7 +47,7 @@
val key: PersonKey,
val name: CharSequence,
val avatar: Drawable,
- val clickIntent: PendingIntent,
+ val clickRunnable: Runnable,
val userId: Int
)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt
index 721f32a..360bf96 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt
@@ -17,20 +17,30 @@
package com.android.systemui.statusbar.notification.people
import android.app.Notification
+import android.content.Context
+import android.content.pm.LauncherApps
+import android.content.pm.PackageManager
+import android.content.pm.ShortcutInfo
import android.content.pm.UserInfo
+import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.os.UserManager
+import android.service.notification.NotificationListenerService
+import android.service.notification.NotificationListenerService.REASON_SNOOZED
import android.service.notification.StatusBarNotification
+import android.util.IconDrawableFactory
import android.util.SparseArray
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import com.android.internal.statusbar.NotificationVisibility
import com.android.internal.widget.MessagingGroup
+import com.android.settingslib.notification.ConversationIconFactory
import com.android.systemui.R
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.NotificationPersonExtractorPlugin
+import com.android.systemui.statusbar.NotificationListener
import com.android.systemui.statusbar.NotificationLockscreenUserManager
import com.android.systemui.statusbar.notification.NotificationEntryListener
import com.android.systemui.statusbar.notification.NotificationEntryManager
@@ -69,7 +79,7 @@
override fun extractPerson(sbn: StatusBarNotification) =
plugin?.extractPerson(sbn)?.run {
- PersonModel(key, name, avatar, clickIntent, sbn.user.identifier)
+ PersonModel(key, name, avatar, clickRunnable, sbn.user.identifier)
}
override fun extractPersonKey(sbn: StatusBarNotification) = plugin?.extractPersonKey(sbn)
@@ -80,17 +90,26 @@
@Singleton
class PeopleHubDataSourceImpl @Inject constructor(
- private val notificationEntryManager: NotificationEntryManager,
- private val extractor: NotificationPersonExtractor,
- private val userManager: UserManager,
- @Background private val bgExecutor: Executor,
- @Main private val mainExecutor: Executor,
- private val notifLockscreenUserMgr: NotificationLockscreenUserManager
-) : DataSource<PeopleHubModel> {
+ private val notificationEntryManager: NotificationEntryManager,
+ private val extractor: NotificationPersonExtractor,
+ private val userManager: UserManager,
+ private val launcherApps: LauncherApps,
+ private val packageManager: PackageManager,
+ private val c: Context,
+ private val notificationListener: NotificationListener,
+ @Background private val bgExecutor: Executor,
+ @Main private val mainExecutor: Executor,
+ private val notifLockscreenUserMgr: NotificationLockscreenUserManager,
+ private val peopleNotificationIdentifier: PeopleNotificationIdentifier
+ ) : DataSource<PeopleHubModel> {
private var userChangeSubscription: Subscription? = null
private val dataListeners = mutableListOf<DataListener<PeopleHubModel>>()
private val peopleHubManagerForUser = SparseArray<PeopleHubManager>()
+ val context: Context = c.applicationContext
+ val iconFactory = ConversationIconFactory(context, launcherApps, packageManager,
+ IconDrawableFactory.newInstance(context), context.resources.getDimensionPixelSize(
+ R.dimen.notification_guts_conversation_icon_size))
private val notificationEntryListener = object : NotificationEntryListener {
override fun onEntryInflated(entry: NotificationEntry) = addVisibleEntry(entry)
@@ -102,18 +121,23 @@
override fun onEntryRemoved(
entry: NotificationEntry,
visibility: NotificationVisibility?,
- removedByUser: Boolean
- ) = removeVisibleEntry(entry)
+ removedByUser: Boolean,
+ reason: Int
+ ) = removeVisibleEntry(entry, reason)
}
- private fun removeVisibleEntry(entry: NotificationEntry) {
+ private fun removeVisibleEntry(entry: NotificationEntry, reason: Int) {
(extractor.extractPersonKey(entry.sbn) ?: entry.extractPersonKey())?.let { key ->
val userId = entry.sbn.user.identifier
bgExecutor.execute {
val parentId = userManager.getProfileParent(userId)?.id ?: userId
mainExecutor.execute {
- if (peopleHubManagerForUser[parentId]?.removeActivePerson(key) == true) {
- updateUi()
+ if (reason == REASON_SNOOZED) {
+ if (peopleHubManagerForUser[parentId]?.migrateActivePerson(key) == true) {
+ updateUi()
+ }
+ } else {
+ peopleHubManagerForUser[parentId]?.removeActivePerson(key)
}
}
}
@@ -121,7 +145,7 @@
}
private fun addVisibleEntry(entry: NotificationEntry) {
- (extractor.extractPerson(entry.sbn) ?: entry.extractPerson())?.let { personModel ->
+ entry.extractPerson()?.let { personModel ->
val userId = entry.sbn.user.identifier
bgExecutor.execute {
val parentId = userManager.getProfileParent(userId)?.id ?: userId
@@ -180,6 +204,34 @@
listener.onDataChanged(model)
}
}
+
+ private fun NotificationEntry.extractPerson(): PersonModel? {
+ if (!peopleNotificationIdentifier.isPeopleNotification(sbn, ranking)) {
+ return null
+ }
+ val clickRunnable = Runnable { notificationListener.unsnoozeNotification(key) }
+ val extras = sbn.notification.extras
+ val name = ranking.shortcutInfo?.shortLabel
+ ?: extras.getString(Notification.EXTRA_CONVERSATION_TITLE)
+ ?: extras.getString(Notification.EXTRA_TITLE)
+ ?: return null
+ val drawable = ranking.shortcutInfo?.getIcon(iconFactory, sbn, ranking)
+ ?: iconFactory.getConversationDrawable(extractAvatarFromRow(this), sbn.packageName,
+ sbn.uid, ranking.channel.isImportantConversation)
+
+ return PersonModel(key, name, drawable, clickRunnable, sbn.user.identifier)
+ }
+
+ private fun ShortcutInfo.getIcon(iconFactory: ConversationIconFactory,
+ sbn: StatusBarNotification,
+ ranking: NotificationListenerService.Ranking): Drawable? {
+ return iconFactory.getConversationDrawable(ranking.shortcutInfo, sbn.packageName, sbn.uid,
+ ranking.channel.isImportantConversation)
+ }
+
+ private fun NotificationEntry.extractPersonKey(): PersonKey? =
+ // TODO migrate to shortcut id when snoozing is conversation wide
+ if (peopleNotificationIdentifier.isPeopleNotification(sbn, ranking)) key else null
}
private fun NotificationLockscreenUserManager.registerListener(
@@ -201,7 +253,7 @@
// People that were once "active" and have been dismissed, and so can be displayed in the hub
private val inactivePeople = ArrayDeque<PersonModel>(MAX_STORED_INACTIVE_PEOPLE)
- fun removeActivePerson(key: PersonKey): Boolean {
+ fun migrateActivePerson(key: PersonKey): Boolean {
activePeople.remove(key)?.let { data ->
if (inactivePeople.size >= MAX_STORED_INACTIVE_PEOPLE) {
inactivePeople.removeLast()
@@ -212,6 +264,10 @@
return false
}
+ fun removeActivePerson(key: PersonKey) {
+ activePeople.remove(key)
+ }
+
fun addActivePerson(person: PersonModel): Boolean {
activePeople[person.key] = person
return inactivePeople.removeIf { it.key == person.key }
@@ -229,19 +285,6 @@
private fun ViewGroup.childrenWithId(id: Int): Sequence<View> = children.filter { it.id == id }
-private fun NotificationEntry.extractPerson(): PersonModel? {
- if (!isMessagingNotification()) {
- return null
- }
- val clickIntent = sbn.notification.contentIntent ?: return null
- val extras = sbn.notification.extras
- val name = extras.getString(Notification.EXTRA_CONVERSATION_TITLE)
- ?: extras.getString(Notification.EXTRA_TITLE)
- ?: return null
- val drawable = extractAvatarFromRow(this) ?: return null
- return PersonModel(key, name, drawable, clickIntent, sbn.user.identifier)
-}
-
fun extractAvatarFromRow(entry: NotificationEntry): Drawable? =
entry.row
?.childrenWithId(R.id.expanded)
@@ -261,8 +304,3 @@
}
?.firstOrNull()
-private fun NotificationEntry.extractPersonKey(): PersonKey? =
- if (isMessagingNotification()) key else null
-
-private fun NotificationEntry.isMessagingNotification() =
- sbn.notification.notificationStyle == Notification.MessagingStyle::class.java
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubViewController.kt
index a58c42b..62d3612 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubViewController.kt
@@ -102,30 +102,19 @@
@Singleton
class PeopleHubViewModelFactoryDataSourceImpl @Inject constructor(
private val activityStarter: ActivityStarter,
- private val dataSource: DataSource<@JvmSuppressWildcards PeopleHubModel>,
- private val settingChangeSource: DataSource<@JvmSuppressWildcards Boolean>
+ private val dataSource: DataSource<@JvmSuppressWildcards PeopleHubModel>
) : DataSource<PeopleHubViewModelFactory> {
override fun registerListener(listener: DataListener<PeopleHubViewModelFactory>): Subscription {
- var stripEnabled = false
var model: PeopleHubModel? = null
fun updateListener() {
// don't invoke listener until we've received our first model
model?.let { model ->
- val factory =
- if (stripEnabled) PeopleHubViewModelFactoryImpl(model, activityStarter)
- else EmptyViewModelFactory
+ val factory = PeopleHubViewModelFactoryImpl(model, activityStarter)
listener.onDataChanged(factory)
}
}
-
- val settingSub = settingChangeSource.registerListener(object : DataListener<Boolean> {
- override fun onDataChanged(data: Boolean) {
- stripEnabled = data
- updateListener()
- }
- })
val dataSub = dataSource.registerListener(object : DataListener<PeopleHubModel> {
override fun onDataChanged(data: PeopleHubModel) {
model = data
@@ -134,7 +123,6 @@
})
return object : Subscription {
override fun unsubscribe() {
- settingSub.unsubscribe()
dataSub.unsubscribe()
}
}
@@ -155,11 +143,7 @@
override fun createWithAssociatedClickView(view: View): PeopleHubViewModel {
val personViewModels = model.people.asSequence().map { personModel ->
val onClick = {
- activityStarter.startPendingIntentDismissingKeyguard(
- personModel.clickIntent,
- null,
- view
- )
+ personModel.clickRunnable.run()
}
PersonViewModel(personModel.name, personModel.avatar, onClick)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
index a5258fd..1088cdc3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
@@ -216,15 +216,7 @@
if (TextUtils.isEmpty(mConversationId)) {
throw new IllegalArgumentException("Does not have required information");
}
- // TODO: consider querying this earlier in the notification pipeline and passing it in
- LauncherApps.ShortcutQuery query = new LauncherApps.ShortcutQuery()
- .setPackage(mPackageName)
- .setQueryFlags(FLAG_MATCH_DYNAMIC | FLAG_MATCH_PINNED | FLAG_MATCH_CACHED)
- .setShortcutIds(Arrays.asList(mConversationId));
- List<ShortcutInfo> shortcuts = mLauncherApps.getShortcuts(query, mSbn.getUser());
- if (shortcuts != null && !shortcuts.isEmpty()) {
- mShortcutInfo = shortcuts.get(0);
- }
+ mShortcutInfo = entry.getRanking().getShortcutInfo();
mIsBubbleable = mEntry.getBubbleMetadata() != null
&& Settings.Global.getInt(mContext.getContentResolver(),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightsOutNotifController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightsOutNotifController.java
index 5703f06..8e192c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightsOutNotifController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightsOutNotifController.java
@@ -172,7 +172,7 @@
@Override
public void onEntryRemoved(@Nullable NotificationEntry entry,
- NotificationVisibility visibility, boolean removedByUser) {
+ NotificationVisibility visibility, boolean removedByUser, int reason) {
updateLightsOutView();
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java
index d709e02..8c31a37 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java
@@ -196,7 +196,8 @@
public void onEntryRemoved(
@Nullable NotificationEntry entry,
NotificationVisibility visibility,
- boolean removedByUser) {
+ boolean removedByUser,
+ int reason) {
// Removes any alerts pending on this entry. Note that this will not stop any inflation
// tasks started by a transfer, so this should only be used as clean-up for when
// inflation is stopped and the pending alert no longer needs to happen.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index 693cdd2..30d6b507 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -199,7 +199,8 @@
public void onEntryRemoved(
@Nullable NotificationEntry entry,
NotificationVisibility visibility,
- boolean removedByUser) {
+ boolean removedByUser,
+ int reason) {
StatusBarNotificationPresenter.this.onNotificationRemoved(
entry.getKey(), entry.getSbn());
if (removedByUser) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputUriController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputUriController.java
index 4d912de..b503183 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputUriController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputUriController.java
@@ -73,7 +73,7 @@
private final NotificationEntryListener mInlineUriListener = new NotificationEntryListener() {
@Override
public void onEntryRemoved(NotificationEntry entry, NotificationVisibility visibility,
- boolean removedByUser) {
+ boolean removedByUser, int reason) {
try {
mStatusBarManagerService.clearInlineReplyUriPermissions(entry.getKey());
} catch (RemoteException ex) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
index c912b67..69e933e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
@@ -16,6 +16,8 @@
package com.android.systemui;
+import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
import static junit.framework.TestCase.fail;
@@ -528,7 +530,8 @@
.setSbn(notification)
.build(),
null,
- false);
+ false,
+ REASON_APP_CANCEL);
}
private void entryAdded(StatusBarNotification notification, int importance) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
index 3009593..9fe9e6d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
@@ -685,7 +685,7 @@
assertTrue(mBubbleController.hasBubbles());
// Removes the notification
- mEntryListener.onEntryRemoved(mRow.getEntry(), null, false);
+ mEntryListener.onEntryRemoved(mRow.getEntry(), null, false, REASON_APP_CANCEL);
assertFalse(mBubbleController.hasBubbles());
}
@@ -827,7 +827,7 @@
mBubbleController.handleDismissalInterception(groupSummary.getEntry());
// WHEN the summary is cancelled by the app
- mEntryListener.onEntryRemoved(groupSummary.getEntry(), null, true);
+ mEntryListener.onEntryRemoved(groupSummary.getEntry(), null, false, REASON_APP_CANCEL);
// THEN the summary and its children are removed from bubble data
assertFalse(mBubbleData.hasBubbleWithKey(groupedBubble.getEntry().getKey()));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/RankingBuilder.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/RankingBuilder.java
index 16f105d..fe8b89f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/RankingBuilder.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/RankingBuilder.java
@@ -20,6 +20,7 @@
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager.Importance;
+import android.content.pm.ShortcutInfo;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.SnoozeCriterion;
@@ -53,6 +54,7 @@
private boolean mCanBubble = false;
private boolean mIsVisuallyInterruptive = false;
private boolean mIsConversation = false;
+ private ShortcutInfo mShortcutInfo = null;
public RankingBuilder() {
}
@@ -79,6 +81,7 @@
mCanBubble = ranking.canBubble();
mIsVisuallyInterruptive = ranking.visuallyInterruptive();
mIsConversation = ranking.isConversation();
+ mShortcutInfo = ranking.getShortcutInfo();
}
public Ranking build() {
@@ -104,7 +107,8 @@
mSmartReplies,
mCanBubble,
mIsVisuallyInterruptive,
- mIsConversation);
+ mIsConversation,
+ mShortcutInfo);
return ranking;
}
@@ -189,6 +193,11 @@
return this;
}
+ public RankingBuilder setShortcutInfo(ShortcutInfo shortcutInfo) {
+ mShortcutInfo = shortcutInfo;
+ return this;
+ }
+
public RankingBuilder setImportance(@Importance int importance) {
mImportance = importance;
return this;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index 98f12ce..312bb7f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -143,7 +143,7 @@
IMPORTANCE_DEFAULT,
null, null,
null, null, null, true, sentiment, false, -1, false, null, null, false, false,
- false);
+ false, null);
return true;
}).when(mRankingMap).getRanking(eq(key), any(Ranking.class));
}
@@ -162,7 +162,7 @@
null, null,
null, null, null, true,
Ranking.USER_SENTIMENT_NEUTRAL, false, -1,
- false, smartActions, null, false, false, false);
+ false, smartActions, null, false, false, false, null);
return true;
}).when(mRankingMap).getRanking(eq(key), any(Ranking.class));
}
@@ -254,7 +254,7 @@
verify(mPresenter).updateNotificationViews();
verify(mEntryListener).onEntryRemoved(
- eq(mEntry), any(), eq(false) /* removedByUser */);
+ eq(mEntry), any(), eq(false) /* removedByUser */, eq(UNDEFINED_DISMISS_REASON));
verify(mRow).setRemoved();
assertNull(mEntryManager.getActiveNotificationUnfiltered(mSbn.getKey()));
@@ -266,7 +266,7 @@
mEntryManager.removeNotification("not_a_real_key", mRankingMap, UNDEFINED_DISMISS_REASON);
verify(mEntryListener, never()).onEntryRemoved(
- eq(mEntry), any(), eq(false) /* removedByUser */);
+ eq(mEntry), any(), eq(false) /* removedByUser */, eq(UNDEFINED_DISMISS_REASON));
}
@Test
@@ -275,7 +275,7 @@
mEntryManager.removeNotification(mSbn.getKey(), mRankingMap, UNDEFINED_DISMISS_REASON);
verify(mEntryListener, never()).onEntryRemoved(
- eq(mEntry), any(), eq(false /* removedByUser */));
+ eq(mEntry), any(), eq(false /* removedByUser */), eq(UNDEFINED_DISMISS_REASON));
}
@Test
@@ -356,7 +356,8 @@
verify(extender).setShouldManageLifetime(mEntry, true);
// THEN the notification is retained
assertNotNull(mEntryManager.getActiveNotificationUnfiltered(mSbn.getKey()));
- verify(mEntryListener, never()).onEntryRemoved(eq(mEntry), any(), eq(false));
+ verify(mEntryListener, never()).onEntryRemoved(
+ eq(mEntry), any(), eq(false), eq(UNDEFINED_DISMISS_REASON));
}
@Test
@@ -374,7 +375,8 @@
// THEN the notification is removed
assertNull(mEntryManager.getActiveNotificationUnfiltered(mSbn.getKey()));
- verify(mEntryListener).onEntryRemoved(eq(mEntry), any(), eq(false));
+ verify(mEntryListener).onEntryRemoved(
+ eq(mEntry), any(), eq(false), eq(UNDEFINED_DISMISS_REASON));
}
@Test
@@ -447,7 +449,7 @@
// THEN the interceptor intercepts & the entry is not removed & no listeners are called
assertNotNull(mEntryManager.getActiveNotificationUnfiltered(mSbn.getKey()));
verify(mEntryListener, never()).onEntryRemoved(eq(mEntry),
- any(NotificationVisibility.class), anyBoolean());
+ any(NotificationVisibility.class), anyBoolean(), eq(UNDEFINED_DISMISS_REASON));
}
@Test
@@ -466,7 +468,7 @@
// THEN the interceptor intercepts & the entry is not removed & no listeners are called
assertNull(mEntryManager.getActiveNotificationUnfiltered(mSbn.getKey()));
verify(mEntryListener, atLeastOnce()).onEntryRemoved(eq(mEntry),
- any(NotificationVisibility.class), anyBoolean());
+ any(NotificationVisibility.class), anyBoolean(), eq(UNDEFINED_DISMISS_REASON));
}
private NotificationEntry createNotification() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
index 7343e5e..19dd027 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.notification;
+import static com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON;
+
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.verify;
@@ -87,7 +89,8 @@
mEntryListener.onEntryRemoved(
entry,
NotificationVisibility.obtain(entry.getKey(), 0, 0, true),
- false);
+ false,
+ UNDEFINED_DISMISS_REASON);
verify(mListContainer).cleanUpViewStateForEntry(entry);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilder.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilder.java
index d2bb011..92a9080 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilder.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilder.java
@@ -21,6 +21,7 @@
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
+import android.content.pm.ShortcutInfo;
import android.os.UserHandle;
import android.service.notification.SnoozeCriterion;
import android.service.notification.StatusBarNotification;
@@ -266,4 +267,9 @@
mRankingBuilder.setSmartReplies(smartReplies);
return this;
}
+
+ public NotificationEntryBuilder setShortcutInfo(ShortcutInfo shortcutInfo) {
+ mRankingBuilder.setShortcutInfo(shortcutInfo);
+ return this;
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/people/PeopleHubViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/people/PeopleHubViewControllerTest.kt
index b0ca943..b1288f8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/people/PeopleHubViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/people/PeopleHubViewControllerTest.kt
@@ -101,15 +101,13 @@
@Test
fun testViewModelDataSourceTransformsModel() {
- val fakeClickIntent = PendingIntent.getActivity(context, 0, Intent("action"), 0)
- val fakePerson = fakePersonModel("id", "name", fakeClickIntent)
+ val fakeClickRunnable = mock(Runnable::class.java)
+ val fakePerson = fakePersonModel("id", "name", fakeClickRunnable)
val fakeModel = PeopleHubModel(listOf(fakePerson))
val fakeModelDataSource = FakeDataSource(fakeModel)
- val fakeSettingDataSource = FakeDataSource(true)
val factoryDataSource = PeopleHubViewModelFactoryDataSourceImpl(
mockActivityStarter,
- fakeModelDataSource,
- fakeSettingDataSource
+ fakeModelDataSource
)
val fakeListener = FakeDataListener<PeopleHubViewModelFactory>()
val mockClickView = mock(View::class.java)
@@ -126,35 +124,7 @@
people[0].onClick()
- verify(mockActivityStarter).startPendingIntentDismissingKeyguard(
- same(fakeClickIntent),
- any(),
- same(mockClickView)
- )
- }
-
- @Test
- fun testViewModelDataSource_notVisibleIfSettingDisabled() {
- val fakeClickIntent = PendingIntent.getActivity(context, 0, Intent("action"), 0)
- val fakePerson = fakePersonModel("id", "name", fakeClickIntent)
- val fakeModel = PeopleHubModel(listOf(fakePerson))
- val fakeModelDataSource = FakeDataSource(fakeModel)
- val fakeSettingDataSource = FakeDataSource(false)
- val factoryDataSource = PeopleHubViewModelFactoryDataSourceImpl(
- mockActivityStarter,
- fakeModelDataSource,
- fakeSettingDataSource
- )
- val fakeListener = FakeDataListener<PeopleHubViewModelFactory>()
- val mockClickView = mock(View::class.java)
-
- factoryDataSource.registerListener(fakeListener)
-
- val viewModel = (fakeListener.lastSeen as Maybe.Just).value
- .createWithAssociatedClickView(mockClickView)
- assertThat(viewModel.isVisible).isFalse()
- val people = viewModel.people.toList()
- assertThat(people.size).isEqualTo(0)
+ verify(fakeClickRunnable).run()
}
}
@@ -178,10 +148,10 @@
private fun fakePersonModel(
id: String,
name: CharSequence,
- clickIntent: PendingIntent,
+ clickRunnable: Runnable,
userId: Int = 0
): PersonModel =
- PersonModel(id, name, mock(Drawable::class.java), clickIntent, userId)
+ PersonModel(id, name, mock(Drawable::class.java), clickRunnable, userId)
private fun fakePersonViewModel(name: CharSequence): PersonViewModel =
PersonViewModel(name, mock(Drawable::class.java), mock({}.javaClass))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
index 6c12c76..e1ab33a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
@@ -198,7 +198,7 @@
.build();
mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0,
notification, UserHandle.CURRENT, null, 0);
- mEntry = new NotificationEntryBuilder().setSbn(mSbn).build();
+ mEntry = new NotificationEntryBuilder().setSbn(mSbn).setShortcutInfo(mShortcutInfo).build();
PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0,
new Intent(mContext, BubblesTestActivity.class), 0);
@@ -207,7 +207,10 @@
.createIntentBubble(bubbleIntent,
Icon.createWithResource(mContext, R.drawable.android)).build())
.build();
- mBubbleEntry = new NotificationEntryBuilder().setSbn(mBubbleSbn).build();
+ mBubbleEntry = new NotificationEntryBuilder()
+ .setSbn(mBubbleSbn)
+ .setShortcutInfo(mShortcutInfo)
+ .build();
mConversationChannel = new NotificationChannel(
TEST_CHANNEL + " : " + CONVERSATION_ID, TEST_CHANNEL_NAME, IMPORTANCE_LOW);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
index 48a3b25..5d0349d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
@@ -283,7 +283,8 @@
null,
false,
false,
- false);
+ false,
+ null);
mRankingMap = new NotificationListenerService.RankingMap(new Ranking[] {ranking});
TestableLooper.get(this).processAllMessages();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightsOutNotifControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightsOutNotifControllerTest.java
index 3d59d61..dbb4512 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightsOutNotifControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightsOutNotifControllerTest.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.phone;
+import static android.service.notification.NotificationListenerService.REASON_CANCEL_ALL;
import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
import static junit.framework.Assert.assertFalse;
@@ -205,7 +206,8 @@
// WHEN all active notifications are removed
when(mEntryManager.hasActiveNotifications()).thenReturn(false);
assertFalse(mLightsOutNotifController.shouldShowDot());
- mEntryListener.onEntryRemoved(mock(NotificationEntry.class), null, false);
+ mEntryListener.onEntryRemoved(
+ mock(NotificationEntry.class), null, false, REASON_CANCEL_ALL);
// THEN we shouldn't see the dot view
assertIsShowingDot(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
index e171a28..f6a099d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.phone;
+import static com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP;
import static org.junit.Assert.assertFalse;
@@ -254,7 +255,8 @@
mGroupManager.onEntryAdded(summaryEntry);
mGroupManager.onEntryAdded(childEntry);
- mNotificationEntryListener.onEntryRemoved(childEntry, null, false);
+ mNotificationEntryListener.onEntryRemoved(
+ childEntry, null, false, UNDEFINED_DISMISS_REASON);
assertFalse(mGroupAlertTransferHelper.isAlertTransferPending(childEntry));
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index ceb1cd4..7a777c1 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -8575,7 +8575,8 @@
record.getSmartReplies(),
record.canBubble(),
record.isInterruptive(),
- record.isConversation()
+ record.isConversation(),
+ record.getShortcutInfo()
);
rankings.add(ranking);
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 9d243e4..c07107f 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -1344,6 +1344,10 @@
mShortcutInfo = shortcutInfo;
}
+ public ShortcutInfo getShortcutInfo() {
+ return mShortcutInfo;
+ }
+
/**
* Whether this notification is a conversation notification.
*/
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
index da0e03d..dc8d010 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
@@ -35,9 +35,12 @@
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.PendingIntent;
+import android.app.Person;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
+import android.content.pm.ShortcutInfo;
import android.graphics.Bitmap;
import android.graphics.drawable.Icon;
import android.os.Binder;
@@ -118,6 +121,7 @@
assertEquals(canBubble(i), ranking.canBubble());
assertEquals(visuallyInterruptive(i), ranking.visuallyInterruptive());
assertEquals(isConversation(i), ranking.isConversation());
+ assertEquals(getShortcutInfo(i).getId(), ranking.getShortcutInfo().getId());
}
}
@@ -186,7 +190,8 @@
(ArrayList) tweak.getSmartReplies(),
tweak.canBubble(),
tweak.visuallyInterruptive(),
- tweak.isConversation()
+ tweak.isConversation(),
+ tweak.getShortcutInfo()
);
assertNotEquals(nru, nru2);
}
@@ -264,7 +269,8 @@
getSmartReplies(key, i),
canBubble(i),
visuallyInterruptive(i),
- isConversation(i)
+ isConversation(i),
+ getShortcutInfo(i)
);
rankings[i] = ranking;
}
@@ -377,6 +383,17 @@
return index % 4 == 0;
}
+ private ShortcutInfo getShortcutInfo(int index) {
+ ShortcutInfo si = new ShortcutInfo(
+ index, String.valueOf(index), "packageName", new ComponentName("1", "1"), null,
+ "title", 0, "titleResName", "text", 0, "textResName",
+ "disabledMessage", 0, "disabledMessageResName",
+ null, null, 0, null, 0, 0,
+ 0, "iconResName", "bitmapPath", 0,
+ null, null);
+ return si;
+ }
+
private void assertActionsEqual(
List<Notification.Action> expecteds, List<Notification.Action> actuals) {
assertEquals(expecteds.size(), actuals.size());
@@ -411,6 +428,7 @@
assertEquals(comment, a.getSmartReplies(), b.getSmartReplies());
assertEquals(comment, a.canBubble(), b.canBubble());
assertEquals(comment, a.isConversation(), b.isConversation());
+ assertEquals(comment, a.getShortcutInfo().getId(), b.getShortcutInfo().getId());
assertActionsEqual(a.getSmartActions(), b.getSmartActions());
}