Merge "Update logic about parent and convo channels" into sc-dev

This commit is contained in:
Julia Reynolds
2021-06-09 17:33:23 +00:00
committed by Android (Google) Code Review
5 changed files with 210 additions and 97 deletions

View File

@@ -36,8 +36,8 @@ public final class ConversationChannel implements Parcelable {
private ShortcutInfo mShortcutInfo; private ShortcutInfo mShortcutInfo;
private int mUid; private int mUid;
private NotificationChannel mParentNotificationChannel; private NotificationChannel mNotificationChannel;
private NotificationChannelGroup mParentNotificationChannelGroup; private NotificationChannelGroup mNotificationChannelGroup;
private long mLastEventTimestamp; private long mLastEventTimestamp;
private boolean mHasActiveNotifications; private boolean mHasActiveNotifications;
private boolean mHasBirthdayToday; private boolean mHasBirthdayToday;
@@ -61,8 +61,8 @@ public final class ConversationChannel implements Parcelable {
boolean hasActiveNotifications) { boolean hasActiveNotifications) {
mShortcutInfo = shortcutInfo; mShortcutInfo = shortcutInfo;
mUid = uid; mUid = uid;
mParentNotificationChannel = parentNotificationChannel; mNotificationChannel = parentNotificationChannel;
mParentNotificationChannelGroup = parentNotificationChannelGroup; mNotificationChannelGroup = parentNotificationChannelGroup;
mLastEventTimestamp = lastEventTimestamp; mLastEventTimestamp = lastEventTimestamp;
mHasActiveNotifications = hasActiveNotifications; mHasActiveNotifications = hasActiveNotifications;
} }
@@ -74,8 +74,8 @@ public final class ConversationChannel implements Parcelable {
List<ConversationStatus> statuses) { List<ConversationStatus> statuses) {
mShortcutInfo = shortcutInfo; mShortcutInfo = shortcutInfo;
mUid = uid; mUid = uid;
mParentNotificationChannel = parentNotificationChannel; mNotificationChannel = parentNotificationChannel;
mParentNotificationChannelGroup = parentNotificationChannelGroup; mNotificationChannelGroup = parentNotificationChannelGroup;
mLastEventTimestamp = lastEventTimestamp; mLastEventTimestamp = lastEventTimestamp;
mHasActiveNotifications = hasActiveNotifications; mHasActiveNotifications = hasActiveNotifications;
mHasBirthdayToday = hasBirthdayToday; mHasBirthdayToday = hasBirthdayToday;
@@ -85,8 +85,8 @@ public final class ConversationChannel implements Parcelable {
public ConversationChannel(Parcel in) { public ConversationChannel(Parcel in) {
mShortcutInfo = in.readParcelable(ShortcutInfo.class.getClassLoader()); mShortcutInfo = in.readParcelable(ShortcutInfo.class.getClassLoader());
mUid = in.readInt(); mUid = in.readInt();
mParentNotificationChannel = in.readParcelable(NotificationChannel.class.getClassLoader()); mNotificationChannel = in.readParcelable(NotificationChannel.class.getClassLoader());
mParentNotificationChannelGroup = mNotificationChannelGroup =
in.readParcelable(NotificationChannelGroup.class.getClassLoader()); in.readParcelable(NotificationChannelGroup.class.getClassLoader());
mLastEventTimestamp = in.readLong(); mLastEventTimestamp = in.readLong();
mHasActiveNotifications = in.readBoolean(); mHasActiveNotifications = in.readBoolean();
@@ -104,8 +104,8 @@ public final class ConversationChannel implements Parcelable {
public void writeToParcel(Parcel dest, int flags) { public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(mShortcutInfo, flags); dest.writeParcelable(mShortcutInfo, flags);
dest.writeInt(mUid); dest.writeInt(mUid);
dest.writeParcelable(mParentNotificationChannel, flags); dest.writeParcelable(mNotificationChannel, flags);
dest.writeParcelable(mParentNotificationChannelGroup, flags); dest.writeParcelable(mNotificationChannelGroup, flags);
dest.writeLong(mLastEventTimestamp); dest.writeLong(mLastEventTimestamp);
dest.writeBoolean(mHasActiveNotifications); dest.writeBoolean(mHasActiveNotifications);
dest.writeBoolean(mHasBirthdayToday); dest.writeBoolean(mHasBirthdayToday);
@@ -120,12 +120,12 @@ public final class ConversationChannel implements Parcelable {
return mUid; return mUid;
} }
public NotificationChannel getParentNotificationChannel() { public NotificationChannel getNotificationChannel() {
return mParentNotificationChannel; return mNotificationChannel;
} }
public NotificationChannelGroup getParentNotificationChannelGroup() { public NotificationChannelGroup getNotificationChannelGroup() {
return mParentNotificationChannelGroup; return mNotificationChannelGroup;
} }
public long getLastEventTimestamp() { public long getLastEventTimestamp() {
@@ -149,4 +149,18 @@ public final class ConversationChannel implements Parcelable {
public @Nullable List<ConversationStatus> getStatuses() { public @Nullable List<ConversationStatus> getStatuses() {
return mStatuses; return mStatuses;
} }
@Override
public String toString() {
return "ConversationChannel{" +
"mShortcutInfo=" + mShortcutInfo +
", mUid=" + mUid +
", mNotificationChannel=" + mNotificationChannel +
", mNotificationChannelGroup=" + mNotificationChannelGroup +
", mLastEventTimestamp=" + mLastEventTimestamp +
", mHasActiveNotifications=" + mHasActiveNotifications +
", mHasBirthdayToday=" + mHasBirthdayToday +
", mStatuses=" + mStatuses +
'}';
}
} }

View File

@@ -307,10 +307,10 @@ public class PeopleSpaceTile implements Parcelable {
mContactUri = getContactUri(info); mContactUri = getContactUri(info);
mStatuses = channel.getStatuses(); mStatuses = channel.getStatuses();
mLastInteractionTimestamp = channel.getLastEventTimestamp(); mLastInteractionTimestamp = channel.getLastEventTimestamp();
mIsImportantConversation = channel.getParentNotificationChannel() != null mIsImportantConversation = channel.getNotificationChannel() != null
&& channel.getParentNotificationChannel().isImportantConversation(); && channel.getNotificationChannel().isImportantConversation();
mCanBypassDnd = channel.getParentNotificationChannel() != null mCanBypassDnd = channel.getNotificationChannel() != null
&& channel.getParentNotificationChannel().canBypassDnd(); && channel.getNotificationChannel().canBypassDnd();
mNotificationPolicyState = SHOW_CONVERSATIONS; mNotificationPolicyState = SHOW_CONVERSATIONS;
} }

View File

@@ -675,7 +675,7 @@ public class PeopleSpaceWidgetManager {
updatedTile.setUserIcon(icon); updatedTile.setUserIcon(icon);
} }
if (DEBUG) Log.d(TAG, "Statuses: " + conversation.getStatuses().toString()); if (DEBUG) Log.d(TAG, "Statuses: " + conversation.getStatuses().toString());
NotificationChannel channel = conversation.getParentNotificationChannel(); NotificationChannel channel = conversation.getNotificationChannel();
if (channel != null) { if (channel != null) {
if (DEBUG) Log.d(TAG, "Important:" + channel.isImportantConversation()); if (DEBUG) Log.d(TAG, "Important:" + channel.isImportantConversation());
updatedTile.setIsImportantConversation(channel.isImportantConversation()); updatedTile.setIsImportantConversation(channel.isImportantConversation());

View File

@@ -254,6 +254,18 @@ public class DataManager {
return null; return null;
} }
ConversationInfo getConversationInfo(String packageName, int userId, String shortcutId) {
UserData userData = getUnlockedUserData(userId);
if (userData != null) {
PackageData packageData = userData.getPackageData(packageName);
// App may have been uninstalled.
if (packageData != null) {
return packageData.getConversationInfo(shortcutId);
}
}
return null;
}
@Nullable @Nullable
private ConversationChannel getConversationChannel(String packageName, int userId, private ConversationChannel getConversationChannel(String packageName, int userId,
String shortcutId, ConversationInfo conversationInfo) { String shortcutId, ConversationInfo conversationInfo) {
@@ -277,7 +289,7 @@ public class DataManager {
int uid = mPackageManagerInternal.getPackageUid(packageName, 0, userId); int uid = mPackageManagerInternal.getPackageUid(packageName, 0, userId);
NotificationChannel parentChannel = NotificationChannel parentChannel =
mNotificationManagerInternal.getNotificationChannel(packageName, uid, mNotificationManagerInternal.getNotificationChannel(packageName, uid,
conversationInfo.getParentNotificationChannelId()); conversationInfo.getNotificationChannelId());
NotificationChannelGroup parentChannelGroup = null; NotificationChannelGroup parentChannelGroup = null;
if (parentChannel != null) { if (parentChannel != null) {
parentChannelGroup = parentChannelGroup =
@@ -302,7 +314,7 @@ public class DataManager {
String shortcutId = conversationInfo.getShortcutId(); String shortcutId = conversationInfo.getShortcutId();
ConversationChannel channel = getConversationChannel(packageData.getPackageName(), ConversationChannel channel = getConversationChannel(packageData.getPackageName(),
packageData.getUserId(), shortcutId, conversationInfo); packageData.getUserId(), shortcutId, conversationInfo);
if (channel == null || channel.getParentNotificationChannel() == null) { if (channel == null || channel.getNotificationChannel() == null) {
return; return;
} }
conversationChannels.add(channel); conversationChannels.add(channel);
@@ -791,8 +803,8 @@ public class DataManager {
private boolean isCachedRecentConversation(ConversationInfo conversationInfo) { private boolean isCachedRecentConversation(ConversationInfo conversationInfo) {
return conversationInfo.isShortcutCachedForNotification() return conversationInfo.isShortcutCachedForNotification()
&& conversationInfo.getNotificationChannelId() == null && Objects.equals(conversationInfo.getNotificationChannelId(),
&& conversationInfo.getParentNotificationChannelId() != null conversationInfo.getParentNotificationChannelId())
&& conversationInfo.getLastEventTimestamp() > 0L; && conversationInfo.getLastEventTimestamp() > 0L;
} }
@@ -910,7 +922,7 @@ public class DataManager {
} }
@VisibleForTesting @VisibleForTesting
NotificationListenerService getNotificationListenerServiceForTesting(@UserIdInt int userId) { NotificationListener getNotificationListenerServiceForTesting(@UserIdInt int userId) {
return mNotificationListeners.get(userId); return mNotificationListeners.get(userId);
} }
@@ -1132,7 +1144,7 @@ public class DataManager {
} }
@Override @Override
public void onNotificationPosted(StatusBarNotification sbn) { public void onNotificationPosted(StatusBarNotification sbn, RankingMap map) {
if (sbn.getUser().getIdentifier() != mUserId) { if (sbn.getUser().getIdentifier() != mUserId) {
return; return;
} }
@@ -1145,16 +1157,22 @@ public class DataManager {
}); });
if (packageData != null) { if (packageData != null) {
Ranking rank = new Ranking();
map.getRanking(sbn.getKey(), rank);
ConversationInfo conversationInfo = packageData.getConversationInfo(shortcutId); ConversationInfo conversationInfo = packageData.getConversationInfo(shortcutId);
if (conversationInfo == null) { if (conversationInfo == null) {
return; return;
} }
if (DEBUG) Log.d(TAG, "Last event from notification: " + sbn.getPostTime()); if (DEBUG) Log.d(TAG, "Last event from notification: " + sbn.getPostTime());
ConversationInfo updated = new ConversationInfo.Builder(conversationInfo) ConversationInfo.Builder updated = new ConversationInfo.Builder(conversationInfo)
.setLastEventTimestamp(sbn.getPostTime()) .setLastEventTimestamp(sbn.getPostTime())
.setParentNotificationChannelId(sbn.getNotification().getChannelId()) .setNotificationChannelId(rank.getChannel().getId());
.build(); if (!TextUtils.isEmpty(rank.getChannel().getParentChannelId())) {
packageData.getConversationStore().addOrUpdate(updated); updated.setParentNotificationChannelId(rank.getChannel().getParentChannelId());
} else {
updated.setParentNotificationChannelId(sbn.getNotification().getChannelId());
}
packageData.getConversationStore().addOrUpdate(updated.build());
EventHistoryImpl eventHistory = packageData.getEventStore().getOrCreateEventHistory( EventHistoryImpl eventHistory = packageData.getEventStore().getOrCreateEventHistory(
EventStore.CATEGORY_SHORTCUT_BASED, shortcutId); EventStore.CATEGORY_SHORTCUT_BASED, shortcutId);

View File

@@ -134,6 +134,8 @@ public final class DataManagerTest {
private static final String NOTIFICATION_CHANNEL_ID = "test : sc"; private static final String NOTIFICATION_CHANNEL_ID = "test : sc";
private static final String PARENT_NOTIFICATION_CHANNEL_ID = "test"; private static final String PARENT_NOTIFICATION_CHANNEL_ID = "test";
private static final long MILLIS_PER_MINUTE = 1000L * 60L; private static final long MILLIS_PER_MINUTE = 1000L * 60L;
private static final String GENERIC_KEY = "key";
private static final String CUSTOM_KEY = "custom";
@Mock @Mock
private Context mContext; private Context mContext;
@@ -158,7 +160,11 @@ public final class DataManagerTest {
@Mock @Mock
private JobScheduler mJobScheduler; private JobScheduler mJobScheduler;
@Mock @Mock
private StatusBarNotification mStatusBarNotification; private StatusBarNotification mGenericSbn;
@Mock
private StatusBarNotification mConvoSbn;
@Mock
private NotificationListenerService.RankingMap mRankingMap;
@Mock @Mock
private Notification mNotification; private Notification mNotification;
@Mock @Mock
@@ -202,8 +208,6 @@ public final class DataManagerTest {
mParentNotificationChannel = new NotificationChannel( mParentNotificationChannel = new NotificationChannel(
PARENT_NOTIFICATION_CHANNEL_ID, "test channel", PARENT_NOTIFICATION_CHANNEL_ID, "test channel",
NotificationManager.IMPORTANCE_DEFAULT); NotificationManager.IMPORTANCE_DEFAULT);
when(mNotificationManagerInternal.getNotificationChannel(anyString(), anyInt(),
anyString())).thenReturn(mParentNotificationChannel);
when(mContext.getContentResolver()).thenReturn(mContentResolver); when(mContext.getContentResolver()).thenReturn(mContentResolver);
when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper()); when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
@@ -246,16 +250,26 @@ public final class DataManagerTest {
when(mPackageManager.getPackageUidAsUser(TEST_PKG_NAME, USER_ID_PRIMARY)) when(mPackageManager.getPackageUidAsUser(TEST_PKG_NAME, USER_ID_PRIMARY))
.thenReturn(TEST_PKG_UID); .thenReturn(TEST_PKG_UID);
when(mStatusBarNotification.getNotification()).thenReturn(mNotification);
when(mStatusBarNotification.getPackageName()).thenReturn(TEST_PKG_NAME);
when(mStatusBarNotification.getUser()).thenReturn(UserHandle.of(USER_ID_PRIMARY));
when(mStatusBarNotification.getPostTime()).thenReturn(System.currentTimeMillis());
when(mNotification.getShortcutId()).thenReturn(TEST_SHORTCUT_ID);
when(mNotification.getChannelId()).thenReturn(PARENT_NOTIFICATION_CHANNEL_ID);
mNotificationChannel = new NotificationChannel( mNotificationChannel = new NotificationChannel(
NOTIFICATION_CHANNEL_ID, "test channel", NotificationManager.IMPORTANCE_DEFAULT); NOTIFICATION_CHANNEL_ID, "test channel", NotificationManager.IMPORTANCE_DEFAULT);
mNotificationChannel.setConversationId("test", TEST_SHORTCUT_ID); mNotificationChannel.setConversationId(PARENT_NOTIFICATION_CHANNEL_ID, TEST_SHORTCUT_ID);
when(mNotificationManagerInternal.getNotificationChannel(anyString(), anyInt(),
eq(mNotificationChannel.getId()))).thenReturn(mNotificationChannel);
when(mNotificationManagerInternal.getNotificationChannel(anyString(), anyInt(),
eq(mParentNotificationChannel.getId()))).thenReturn(mParentNotificationChannel);
when(mGenericSbn.getKey()).thenReturn(GENERIC_KEY);
when(mGenericSbn.getNotification()).thenReturn(mNotification);
when(mGenericSbn.getPackageName()).thenReturn(TEST_PKG_NAME);
when(mGenericSbn.getUser()).thenReturn(UserHandle.of(USER_ID_PRIMARY));
when(mGenericSbn.getPostTime()).thenReturn(System.currentTimeMillis());
when(mConvoSbn.getKey()).thenReturn(CUSTOM_KEY);
when(mConvoSbn.getNotification()).thenReturn(mNotification);
when(mConvoSbn.getPackageName()).thenReturn(TEST_PKG_NAME);
when(mConvoSbn.getUser()).thenReturn(UserHandle.of(USER_ID_PRIMARY));
when(mConvoSbn.getPostTime()).thenReturn(System.currentTimeMillis());
when(mNotification.getShortcutId()).thenReturn(TEST_SHORTCUT_ID);
mCancellationSignal = new CancellationSignal(); mCancellationSignal = new CancellationSignal();
@@ -449,10 +463,7 @@ public final class DataManagerTest {
buildPerson()); buildPerson());
mDataManager.addOrUpdateConversationInfo(shortcut); mDataManager.addOrUpdateConversationInfo(shortcut);
NotificationListenerService listenerService = sendGenericNotification();
mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
listenerService.onNotificationPosted(mStatusBarNotification);
List<Range<Long>> activeNotificationOpenTimeSlots = getActiveSlotsForTestShortcut( List<Range<Long>> activeNotificationOpenTimeSlots = getActiveSlotsForTestShortcut(
Event.NOTIFICATION_EVENT_TYPES); Event.NOTIFICATION_EVENT_TYPES);
@@ -471,7 +482,7 @@ public final class DataManagerTest {
NotificationListenerService listenerService = NotificationListenerService listenerService =
mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY); mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
listenerService.onNotificationRemoved(mStatusBarNotification, null, listenerService.onNotificationRemoved(mGenericSbn, null,
NotificationListenerService.REASON_CLICK); NotificationListenerService.REASON_CLICK);
List<Range<Long>> activeNotificationOpenTimeSlots = getActiveSlotsForTestShortcut( List<Range<Long>> activeNotificationOpenTimeSlots = getActiveSlotsForTestShortcut(
@@ -495,20 +506,20 @@ public final class DataManagerTest {
shortcut.setCached(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS); shortcut.setCached(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS);
mDataManager.addOrUpdateConversationInfo(shortcut); mDataManager.addOrUpdateConversationInfo(shortcut);
when(mNotification.getShortcutId()).thenReturn(shortcutId); when(mNotification.getShortcutId()).thenReturn(shortcutId);
listenerService.onNotificationPosted(mStatusBarNotification); sendGenericNotification();
} }
// Post another notification for the last conversation. // Post another notification for the last conversation.
listenerService.onNotificationPosted(mStatusBarNotification); sendGenericNotification();
// Removing one of the two notifications does not un-cache the shortcut. // Removing one of the two notifications does not un-cache the shortcut.
listenerService.onNotificationRemoved(mStatusBarNotification, null, listenerService.onNotificationRemoved(mGenericSbn, null,
NotificationListenerService.REASON_CANCEL); NotificationListenerService.REASON_CANCEL);
verify(mShortcutServiceInternal, never()).uncacheShortcuts( verify(mShortcutServiceInternal, never()).uncacheShortcuts(
anyInt(), any(), anyString(), any(), anyInt(), anyInt()); anyInt(), any(), anyString(), any(), anyInt(), anyInt());
// Removing the second notification un-caches the shortcut. // Removing the second notification un-caches the shortcut.
listenerService.onNotificationRemoved(mStatusBarNotification, null, listenerService.onNotificationRemoved(mGenericSbn, null,
NotificationListenerService.REASON_CANCEL_ALL); NotificationListenerService.REASON_CANCEL_ALL);
verify(mShortcutServiceInternal).uncacheShortcuts( verify(mShortcutServiceInternal).uncacheShortcuts(
anyInt(), any(), eq(TEST_PKG_NAME), anyList(), eq(USER_ID_PRIMARY), anyInt(), any(), eq(TEST_PKG_NAME), anyList(), eq(USER_ID_PRIMARY),
@@ -526,7 +537,7 @@ public final class DataManagerTest {
NotificationListenerService listenerService = NotificationListenerService listenerService =
mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY); mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
listenerService.onNotificationPosted(mStatusBarNotification); sendGenericNotification();
shortcut.setCached(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS); shortcut.setCached(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS);
mDataManager.addOrUpdateConversationInfo(shortcut); mDataManager.addOrUpdateConversationInfo(shortcut);
@@ -626,19 +637,13 @@ public final class DataManagerTest {
buildPerson()); buildPerson());
mDataManager.addOrUpdateConversationInfo(shortcut); mDataManager.addOrUpdateConversationInfo(shortcut);
NotificationListenerService listenerService = sendConvoNotification();
mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
listenerService.onNotificationPosted(mStatusBarNotification);
shortcut.setCached(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS); shortcut.setCached(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS);
mDataManager.addOrUpdateConversationInfo(shortcut); mDataManager.addOrUpdateConversationInfo(shortcut);
assertThat(mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY, assertThat(mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
TEST_SHORTCUT_ID)).isNotNull(); TEST_SHORTCUT_ID)).isNotNull();
listenerService.onNotificationChannelModified(TEST_PKG_NAME, UserHandle.of(USER_ID_PRIMARY),
mNotificationChannel, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED);
ConversationChannel result = mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY, ConversationChannel result = mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
TEST_SHORTCUT_ID); TEST_SHORTCUT_ID);
assertThat(result).isNotNull(); assertThat(result).isNotNull();
@@ -661,9 +666,7 @@ public final class DataManagerTest {
assertThat(mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY, assertThat(mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
TEST_SHORTCUT_ID + "1")).isNull(); TEST_SHORTCUT_ID + "1")).isNull();
NotificationListenerService listenerService = sendConvoNotification();
mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
listenerService.onNotificationPosted(mStatusBarNotification);
ConversationStatus cs = new ConversationStatus.Builder("id", ACTIVITY_ANNIVERSARY).build(); ConversationStatus cs = new ConversationStatus.Builder("id", ACTIVITY_ANNIVERSARY).build();
mDataManager.addOrUpdateStatus(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, cs); mDataManager.addOrUpdateStatus(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, cs);
@@ -673,14 +676,50 @@ public final class DataManagerTest {
assertEquals(shortcut.getId(), result.getShortcutInfo().getId()); assertEquals(shortcut.getId(), result.getShortcutInfo().getId());
assertEquals(1, result.getShortcutInfo().getPersons().length); assertEquals(1, result.getShortcutInfo().getPersons().length);
assertEquals(CONTACT_URI, result.getShortcutInfo().getPersons()[0].getUri()); assertEquals(CONTACT_URI, result.getShortcutInfo().getPersons()[0].getUri());
assertEquals(mNotificationChannel.getId(), result.getNotificationChannel().getId());
assertEquals(mParentNotificationChannel.getId(), assertEquals(mParentNotificationChannel.getId(),
result.getParentNotificationChannel().getId()); result.getNotificationChannel().getParentChannelId());
assertEquals(mStatusBarNotification.getPostTime(), result.getLastEventTimestamp()); assertEquals(mConvoSbn.getPostTime(), result.getLastEventTimestamp());
assertTrue(result.hasActiveNotifications()); assertTrue(result.hasActiveNotifications());
assertFalse(result.hasBirthdayToday()); assertFalse(result.hasBirthdayToday());
assertThat(result.getStatuses()).containsExactly(cs); assertThat(result.getStatuses()).containsExactly(cs);
} }
@Test
public void testOnNotificationChannelModified() {
mDataManager.onUserUnlocked(USER_ID_PRIMARY);
assertThat(mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
TEST_SHORTCUT_ID)).isNull();
ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID,
buildPerson());
shortcut.setCached(ShortcutInfo.FLAG_PINNED);
mDataManager.addOrUpdateConversationInfo(shortcut);
sendConvoNotification();
ConversationChannel result = mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
TEST_SHORTCUT_ID);
assertFalse(result.getNotificationChannel().canBubble());
NotificationChannel updated = new NotificationChannel(mNotificationChannel.getId(),
mNotificationChannel.getDescription(), mNotificationChannel.getImportance());
updated.setConversationId(mNotificationChannel.getParentChannelId(),
mNotificationChannel.getConversationId());
updated.setAllowBubbles(true);
NotificationListenerService listenerService =
mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
listenerService.onNotificationChannelModified(TEST_PKG_NAME, UserHandle.of(USER_ID_PRIMARY),
updated, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED);
ConversationInfo ci = mDataManager.getConversationInfo(TEST_PKG_NAME, USER_ID_PRIMARY,
TEST_SHORTCUT_ID);
assertThat(ci).isNotNull();
assertEquals(mNotificationChannel.getId(), ci.getNotificationChannelId());
assertEquals(mParentNotificationChannel.getId(), ci.getParentNotificationChannelId());
assertTrue(ci.isBubbled());
}
@Test @Test
public void testGetConversation_demoted() { public void testGetConversation_demoted() {
mDataManager.onUserUnlocked(USER_ID_PRIMARY); mDataManager.onUserUnlocked(USER_ID_PRIMARY);
@@ -713,11 +752,8 @@ public final class DataManagerTest {
shortcut.setCached(ShortcutInfo.FLAG_PINNED); shortcut.setCached(ShortcutInfo.FLAG_PINNED);
mDataManager.addOrUpdateConversationInfo(shortcut); mDataManager.addOrUpdateConversationInfo(shortcut);
NotificationListenerService listenerService = sendGenericNotification();
mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY); mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID);
listenerService.onNotificationPosted(mStatusBarNotification);
ConversationChannel result = mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
TEST_SHORTCUT_ID);
verify(mShortcutServiceInternal).getShortcuts( verify(mShortcutServiceInternal).getShortcuts(
anyInt(), anyString(), anyLong(), anyString(), anyList(), any(), any(), anyInt(), anyString(), anyLong(), anyString(), anyList(), any(), any(),
@@ -1085,7 +1121,7 @@ public final class DataManagerTest {
shortcut.setCached(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS); shortcut.setCached(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS);
mDataManager.addOrUpdateConversationInfo(shortcut); mDataManager.addOrUpdateConversationInfo(shortcut);
when(mNotification.getShortcutId()).thenReturn(shortcutId); when(mNotification.getShortcutId()).thenReturn(shortcutId);
listenerService.onNotificationPosted(mStatusBarNotification); sendGenericNotification();
} }
mDataManager.pruneDataForUser(USER_ID_PRIMARY, mCancellationSignal); mDataManager.pruneDataForUser(USER_ID_PRIMARY, mCancellationSignal);
@@ -1107,9 +1143,9 @@ public final class DataManagerTest {
shortcut.setCached(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS); shortcut.setCached(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS);
mDataManager.addOrUpdateConversationInfo(shortcut); mDataManager.addOrUpdateConversationInfo(shortcut);
when(mNotification.getShortcutId()).thenReturn(shortcutId); when(mNotification.getShortcutId()).thenReturn(shortcutId);
when(mStatusBarNotification.getPostTime()).thenReturn(100L + i); when(mGenericSbn.getPostTime()).thenReturn(100L + i);
listenerService.onNotificationPosted(mStatusBarNotification); sendGenericNotification();
listenerService.onNotificationRemoved(mStatusBarNotification, null, listenerService.onNotificationRemoved(mGenericSbn, null,
NotificationListenerService.REASON_CANCEL); NotificationListenerService.REASON_CANCEL);
} }
@@ -1162,9 +1198,7 @@ public final class DataManagerTest {
shortcut.setCached(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS); shortcut.setCached(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS);
mDataManager.addOrUpdateConversationInfo(shortcut); mDataManager.addOrUpdateConversationInfo(shortcut);
NotificationListenerService listenerService = sendGenericNotification();
mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
listenerService.onNotificationPosted(mStatusBarNotification);
List<ConversationChannel> result = mDataManager.getRecentConversations(USER_ID_PRIMARY); List<ConversationChannel> result = mDataManager.getRecentConversations(USER_ID_PRIMARY);
assertEquals(1, result.size()); assertEquals(1, result.size());
@@ -1172,8 +1206,9 @@ public final class DataManagerTest {
assertEquals(1, result.get(0).getShortcutInfo().getPersons().length); assertEquals(1, result.get(0).getShortcutInfo().getPersons().length);
assertEquals(CONTACT_URI, result.get(0).getShortcutInfo().getPersons()[0].getUri()); assertEquals(CONTACT_URI, result.get(0).getShortcutInfo().getPersons()[0].getUri());
assertEquals(mParentNotificationChannel.getId(), assertEquals(mParentNotificationChannel.getId(),
result.get(0).getParentNotificationChannel().getId()); result.get(0).getNotificationChannel().getId());
assertEquals(mStatusBarNotification.getPostTime(), result.get(0).getLastEventTimestamp()); assertEquals(null, result.get(0).getNotificationChannel().getParentChannelId());
assertEquals(mGenericSbn.getPostTime(), result.get(0).getLastEventTimestamp());
assertTrue(result.get(0).hasActiveNotifications()); assertTrue(result.get(0).hasActiveNotifications());
} }
@@ -1186,11 +1221,9 @@ public final class DataManagerTest {
shortcut.setCached(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS); shortcut.setCached(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS);
mDataManager.addOrUpdateConversationInfo(shortcut); mDataManager.addOrUpdateConversationInfo(shortcut);
NotificationListenerService listenerService = sendGenericNotification();
mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
listenerService.onNotificationPosted(mStatusBarNotification);
List<ConversationChannel> result = mDataManager.getRecentConversations(USER_ID_PRIMARY); mDataManager.getRecentConversations(USER_ID_PRIMARY);
verify(mShortcutServiceInternal).getShortcuts( verify(mShortcutServiceInternal).getShortcuts(
anyInt(), anyString(), anyLong(), anyString(), anyList(), any(), any(), anyInt(), anyString(), anyLong(), anyString(), anyList(), any(), any(),
@@ -1211,8 +1244,8 @@ public final class DataManagerTest {
NotificationListenerService listenerService = NotificationListenerService listenerService =
mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY); mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
when(mNotification.getShortcutId()).thenReturn(TEST_SHORTCUT_ID); when(mNotification.getShortcutId()).thenReturn(TEST_SHORTCUT_ID);
listenerService.onNotificationPosted(mStatusBarNotification); sendGenericNotification();
listenerService.onNotificationRemoved(mStatusBarNotification, null, listenerService.onNotificationRemoved(mGenericSbn, null,
NotificationListenerService.REASON_CLICK); NotificationListenerService.REASON_CLICK);
mDataManager.pruneOldRecentConversations(USER_ID_PRIMARY, mDataManager.pruneOldRecentConversations(USER_ID_PRIMARY,
@@ -1231,11 +1264,9 @@ public final class DataManagerTest {
buildPerson()); buildPerson());
mDataManager.addOrUpdateConversationInfo(shortcut); mDataManager.addOrUpdateConversationInfo(shortcut);
NotificationListenerService listenerService = sendGenericNotification();
mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
listenerService.onNotificationPosted(mStatusBarNotification);
assertEquals(mStatusBarNotification.getPostTime(), assertEquals(mGenericSbn.getPostTime(),
mDataManager.getLastInteraction(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID)); mDataManager.getLastInteraction(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID));
assertEquals(0L, assertEquals(0L,
mDataManager.getLastInteraction("not_test_pkg", USER_ID_PRIMARY, TEST_SHORTCUT_ID)); mDataManager.getLastInteraction("not_test_pkg", USER_ID_PRIMARY, TEST_SHORTCUT_ID));
@@ -1375,9 +1406,7 @@ public final class DataManagerTest {
TEST_SHORTCUT_ID, buildPerson()); TEST_SHORTCUT_ID, buildPerson());
mDataManager.addOrUpdateConversationInfo(shortcut); mDataManager.addOrUpdateConversationInfo(shortcut);
NotificationListenerService listenerService = sendGenericNotification();
mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
listenerService.onNotificationPosted(mStatusBarNotification);
List<ConversationChannel> result = mDataManager.getRecentConversations(USER_ID_PRIMARY); List<ConversationChannel> result = mDataManager.getRecentConversations(USER_ID_PRIMARY);
assertTrue(result.isEmpty()); assertTrue(result.isEmpty());
@@ -1395,7 +1424,7 @@ public final class DataManagerTest {
// Post a notification and customize the notification settings. // Post a notification and customize the notification settings.
NotificationListenerService listenerService = NotificationListenerService listenerService =
mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY); mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
listenerService.onNotificationPosted(mStatusBarNotification); sendGenericNotification();
listenerService.onNotificationChannelModified(TEST_PKG_NAME, UserHandle.of(USER_ID_PRIMARY), listenerService.onNotificationChannelModified(TEST_PKG_NAME, UserHandle.of(USER_ID_PRIMARY),
mNotificationChannel, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED); mNotificationChannel, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED);
@@ -1414,7 +1443,7 @@ public final class DataManagerTest {
NotificationListenerService listenerService = NotificationListenerService listenerService =
mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY); mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
listenerService.onNotificationPosted(mStatusBarNotification); sendGenericNotification();
// posting updates the last interaction time, so delay before deletion // posting updates the last interaction time, so delay before deletion
try { try {
Thread.sleep(500); Thread.sleep(500);
@@ -1422,7 +1451,7 @@ public final class DataManagerTest {
e.printStackTrace(); e.printStackTrace();
} }
long approxDeletionTime = System.currentTimeMillis(); long approxDeletionTime = System.currentTimeMillis();
listenerService.onNotificationRemoved(mStatusBarNotification, null, listenerService.onNotificationRemoved(mGenericSbn, null,
NotificationListenerService.REASON_CANCEL); NotificationListenerService.REASON_CANCEL);
ConversationInfo conversationInfo = mDataManager.getPackage(TEST_PKG_NAME, USER_ID_PRIMARY) ConversationInfo conversationInfo = mDataManager.getPackage(TEST_PKG_NAME, USER_ID_PRIMARY)
@@ -1442,8 +1471,8 @@ public final class DataManagerTest {
NotificationListenerService listenerService = NotificationListenerService listenerService =
mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY); mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
listenerService.onNotificationPosted(mStatusBarNotification); sendGenericNotification();
listenerService.onNotificationRemoved(mStatusBarNotification, null, listenerService.onNotificationRemoved(mGenericSbn, null,
NotificationListenerService.REASON_CANCEL); NotificationListenerService.REASON_CANCEL);
mDataManager.removeRecentConversation(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, mDataManager.removeRecentConversation(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID,
USER_ID_PRIMARY); USER_ID_PRIMARY);
@@ -1472,14 +1501,14 @@ public final class DataManagerTest {
// Post a notification and then dismiss it for conversation #1. // Post a notification and then dismiss it for conversation #1.
when(mNotification.getShortcutId()).thenReturn("1"); when(mNotification.getShortcutId()).thenReturn("1");
listenerService.onNotificationPosted(mStatusBarNotification); sendGenericNotification();
listenerService.onNotificationRemoved(mStatusBarNotification, null, listenerService.onNotificationRemoved(mGenericSbn, null,
NotificationListenerService.REASON_CANCEL); NotificationListenerService.REASON_CANCEL);
// Post a notification for conversation #2, but don't dismiss it. Its shortcut won't be // Post a notification for conversation #2, but don't dismiss it. Its shortcut won't be
// uncached when removeAllRecentConversations() is called. // uncached when removeAllRecentConversations() is called.
when(mNotification.getShortcutId()).thenReturn("2"); when(mNotification.getShortcutId()).thenReturn("2");
listenerService.onNotificationPosted(mStatusBarNotification); sendGenericNotification();
mDataManager.removeAllRecentConversations(USER_ID_PRIMARY); mDataManager.removeAllRecentConversations(USER_ID_PRIMARY);
@@ -1562,6 +1591,58 @@ public final class DataManagerTest {
return (queryFlags & flag) != 0; return (queryFlags & flag) != 0;
} }
// "Sends" a notification to a non-customized notification channel - the notification channel
// is something generic like "messages" and the notification has a shortcut id
private void sendGenericNotification() {
when(mNotification.getChannelId()).thenReturn(PARENT_NOTIFICATION_CHANNEL_ID);
doAnswer(invocationOnMock -> {
NotificationListenerService.Ranking ranking = (NotificationListenerService.Ranking)
invocationOnMock.getArguments()[1];
ranking.populate(
(String) invocationOnMock.getArguments()[0],
0,
false,
0,
0,
mParentNotificationChannel.getImportance(),
null, null,
mParentNotificationChannel, null, null, true, 0, false, -1, false, null, null,
false, false, false, null, 0, false);
return true;
}).when(mRankingMap).getRanking(eq(GENERIC_KEY),
any(NotificationListenerService.Ranking.class));
NotificationListenerService listenerService =
mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
listenerService.onNotificationPosted(mGenericSbn, mRankingMap);
}
// "Sends" a notification to a customized notification channel - the notification channel
// is specific to a person, and the channel has a convo id matching the notification's shortcut
// and the channel has a parent channel id
private void sendConvoNotification() {
when(mNotification.getChannelId()).thenReturn(NOTIFICATION_CHANNEL_ID);
doAnswer(invocationOnMock -> {
NotificationListenerService.Ranking ranking = (NotificationListenerService.Ranking)
invocationOnMock.getArguments()[1];
ranking.populate(
(String) invocationOnMock.getArguments()[0],
0,
false,
0,
0,
mNotificationChannel.getImportance(),
null, null,
mNotificationChannel, null, null, true, 0, false, -1, false, null, null, false,
false, false, null, 0, false);
return true;
}).when(mRankingMap).getRanking(eq(CUSTOM_KEY),
any(NotificationListenerService.Ranking.class));
NotificationListenerService listenerService =
mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
listenerService.onNotificationPosted(mConvoSbn, mRankingMap);
}
private class TestContactsQueryHelper extends ContactsQueryHelper { private class TestContactsQueryHelper extends ContactsQueryHelper {
private Uri mContactUri; private Uri mContactUri;