diff options
| author | 2020-02-06 12:40:22 -0800 | |
|---|---|---|
| committer | 2020-02-06 17:21:59 -0800 | |
| commit | 44725cd285dd8c45352f903f3b3dacf8c4594329 (patch) | |
| tree | 7eb2c125864f89a4566828861a89a066203a551b | |
| parent | e82ae9c3e516fac525ac6610df128226247fea5e (diff) | |
Listen to the notification channel creation/modification/deletion events
Bug: 146522621
Test: atest com.android.server.people.data.DataManagerTest
Change-Id: I2e465627c16bc3055f784d81800f2907c2728025
6 files changed, 152 insertions, 23 deletions
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index f07113591fa5..46dc21bbeaad 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -9256,7 +9256,7 @@ public class NotificationManagerService extends SystemService { } BackgroundThread.getHandler().post(() -> { - if (hasCompanionDevice(serviceInfo)) { + if (serviceInfo.isSystem || hasCompanionDevice(serviceInfo)) { notifyNotificationChannelChanged( serviceInfo, pkg, user, channel, modificationType); } @@ -9276,7 +9276,7 @@ public class NotificationManagerService extends SystemService { } BackgroundThread.getHandler().post(() -> { - if (hasCompanionDevice(serviceInfo)) { + if (serviceInfo.isSystem || hasCompanionDevice(serviceInfo)) { notifyNotificationChannelGroupChanged( serviceInfo, pkg, user, group, modificationType); } diff --git a/services/people/java/com/android/server/people/data/ConversationInfo.java b/services/people/java/com/android/server/people/data/ConversationInfo.java index bb97533b3222..b60ed3e8783f 100644 --- a/services/people/java/com/android/server/people/data/ConversationInfo.java +++ b/services/people/java/com/android/server/people/data/ConversationInfo.java @@ -35,7 +35,7 @@ import java.util.Objects; */ public class ConversationInfo { - private static final int FLAG_VIP = 1; + private static final int FLAG_IMPORTANT = 1; private static final int FLAG_NOTIFICATION_SILENCED = 1 << 1; @@ -50,7 +50,7 @@ public class ConversationInfo { private static final int FLAG_DEMOTED = 1 << 6; @IntDef(flag = true, prefix = {"FLAG_"}, value = { - FLAG_VIP, + FLAG_IMPORTANT, FLAG_NOTIFICATION_SILENCED, FLAG_BUBBLED, FLAG_PERSON_IMPORTANT, @@ -129,9 +129,9 @@ public class ConversationInfo { return hasShortcutFlags(ShortcutInfo.FLAG_LONG_LIVED); } - /** Whether this conversation is marked as VIP by the user. */ - public boolean isVip() { - return hasConversationFlags(FLAG_VIP); + /** Whether this conversation is marked as important by the user. */ + public boolean isImportant() { + return hasConversationFlags(FLAG_IMPORTANT); } /** Whether the notifications for this conversation should be silenced. */ @@ -208,8 +208,8 @@ public class ConversationInfo { sb.append("]"); sb.append(", conversationFlags=0x").append(Integer.toHexString(mConversationFlags)); sb.append(" ["); - if (isVip()) { - sb.append("Vip"); + if (isImportant()) { + sb.append("Imp"); } if (isNotificationSilenced()) { sb.append("Sil"); @@ -221,7 +221,7 @@ public class ConversationInfo { sb.append("Dem"); } if (isPersonImportant()) { - sb.append("Imp"); + sb.append("PIm"); } if (isPersonBot()) { sb.append("Bot"); @@ -318,8 +318,8 @@ public class ConversationInfo { return this; } - Builder setVip(boolean value) { - return setConversationFlag(FLAG_VIP, value); + Builder setImportant(boolean value) { + return setConversationFlag(FLAG_IMPORTANT, value); } Builder setNotificationSilenced(boolean value) { diff --git a/services/people/java/com/android/server/people/data/DataManager.java b/services/people/java/com/android/server/people/data/DataManager.java index 7fdcf42c6364..7a3ed5348d30 100644 --- a/services/people/java/com/android/server/people/data/DataManager.java +++ b/services/people/java/com/android/server/people/data/DataManager.java @@ -21,6 +21,8 @@ import android.annotation.Nullable; import android.annotation.UserIdInt; import android.annotation.WorkerThread; import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; import android.app.Person; import android.app.prediction.AppTarget; import android.app.prediction.AppTargetEvent; @@ -157,8 +159,8 @@ public class DataManager { mNotificationListeners.put(userId, notificationListener); try { notificationListener.registerAsSystemService(mContext, - new ComponentName(PLATFORM_PACKAGE_NAME, getClass().getSimpleName()), - UserHandle.myUserId()); + new ComponentName(PLATFORM_PACKAGE_NAME, getClass().getCanonicalName()), + userId); } catch (RemoteException e) { // Should never occur for local calls. } @@ -571,6 +573,44 @@ public class DataManager { long currentTime = System.currentTimeMillis(); eventHistory.addEvent(new Event(currentTime, Event.TYPE_NOTIFICATION_OPENED)); } + + @Override + public void onNotificationChannelModified(String pkg, UserHandle user, + NotificationChannel channel, int modificationType) { + PackageData packageData = getPackage(pkg, user.getIdentifier()); + String shortcutId = channel.getConversationId(); + if (packageData == null || shortcutId == null) { + return; + } + ConversationStore conversationStore = packageData.getConversationStore(); + ConversationInfo conversationInfo = conversationStore.getConversation(shortcutId); + if (conversationInfo == null) { + return; + } + ConversationInfo.Builder builder = new ConversationInfo.Builder(conversationInfo); + switch (modificationType) { + case NOTIFICATION_CHANNEL_OR_GROUP_ADDED: + case NOTIFICATION_CHANNEL_OR_GROUP_UPDATED: + builder.setNotificationChannelId(channel.getId()); + builder.setImportant(channel.isImportantConversation()); + builder.setDemoted(channel.isDemoted()); + builder.setNotificationSilenced( + channel.getImportance() <= NotificationManager.IMPORTANCE_LOW); + builder.setBubbled(channel.canBubble()); + break; + case NOTIFICATION_CHANNEL_OR_GROUP_DELETED: + // If the notification channel is deleted, revert all the notification settings + // to the default value. + builder.setNotificationChannelId(null); + builder.setImportant(false); + builder.setDemoted(false); + builder.setNotificationSilenced(false); + builder.setBubbled(false); + break; + } + conversationStore.addOrUpdate(builder.build()); + // TODO: Cache the shortcut when a conversation's notification setting is changed. + } } /** diff --git a/services/tests/servicestests/src/com/android/server/people/data/ConversationInfoTest.java b/services/tests/servicestests/src/com/android/server/people/data/ConversationInfoTest.java index 05a9a80e262c..c0e7927a8d72 100644 --- a/services/tests/servicestests/src/com/android/server/people/data/ConversationInfoTest.java +++ b/services/tests/servicestests/src/com/android/server/people/data/ConversationInfoTest.java @@ -47,7 +47,7 @@ public final class ConversationInfoTest { .setContactPhoneNumber(PHONE_NUMBER) .setNotificationChannelId(NOTIFICATION_CHANNEL_ID) .setShortcutFlags(ShortcutInfo.FLAG_LONG_LIVED) - .setVip(true) + .setImportant(true) .setNotificationSilenced(true) .setBubbled(true) .setDemoted(true) @@ -62,7 +62,7 @@ public final class ConversationInfoTest { assertEquals(PHONE_NUMBER, conversationInfo.getContactPhoneNumber()); assertEquals(NOTIFICATION_CHANNEL_ID, conversationInfo.getNotificationChannelId()); assertTrue(conversationInfo.isShortcutLongLived()); - assertTrue(conversationInfo.isVip()); + assertTrue(conversationInfo.isImportant()); assertTrue(conversationInfo.isNotificationSilenced()); assertTrue(conversationInfo.isBubbled()); assertTrue(conversationInfo.isDemoted()); @@ -83,7 +83,7 @@ public final class ConversationInfoTest { assertNull(conversationInfo.getContactPhoneNumber()); assertNull(conversationInfo.getNotificationChannelId()); assertFalse(conversationInfo.isShortcutLongLived()); - assertFalse(conversationInfo.isVip()); + assertFalse(conversationInfo.isImportant()); assertFalse(conversationInfo.isNotificationSilenced()); assertFalse(conversationInfo.isBubbled()); assertFalse(conversationInfo.isDemoted()); @@ -101,7 +101,7 @@ public final class ConversationInfoTest { .setContactPhoneNumber(PHONE_NUMBER) .setNotificationChannelId(NOTIFICATION_CHANNEL_ID) .setShortcutFlags(ShortcutInfo.FLAG_LONG_LIVED) - .setVip(true) + .setImportant(true) .setNotificationSilenced(true) .setBubbled(true) .setPersonImportant(true) @@ -110,7 +110,7 @@ public final class ConversationInfoTest { .build(); ConversationInfo destination = new ConversationInfo.Builder(source) - .setVip(false) + .setImportant(false) .setContactStarred(false) .build(); @@ -120,7 +120,7 @@ public final class ConversationInfoTest { assertEquals(PHONE_NUMBER, destination.getContactPhoneNumber()); assertEquals(NOTIFICATION_CHANNEL_ID, destination.getNotificationChannelId()); assertTrue(destination.isShortcutLongLived()); - assertFalse(destination.isVip()); + assertFalse(destination.isImportant()); assertTrue(destination.isNotificationSilenced()); assertTrue(destination.isBubbled()); assertTrue(destination.isPersonImportant()); diff --git a/services/tests/servicestests/src/com/android/server/people/data/ConversationStoreTest.java b/services/tests/servicestests/src/com/android/server/people/data/ConversationStoreTest.java index bbcb54ef8d3e..331ad5972fc1 100644 --- a/services/tests/servicestests/src/com/android/server/people/data/ConversationStoreTest.java +++ b/services/tests/servicestests/src/com/android/server/people/data/ConversationStoreTest.java @@ -167,7 +167,7 @@ public final class ConversationStoreTest { .setContactPhoneNumber(phoneNumber) .setNotificationChannelId(notificationChannelId) .setShortcutFlags(ShortcutInfo.FLAG_LONG_LIVED) - .setVip(true) + .setImportant(true) .setBubbled(true) .build(); } diff --git a/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java b/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java index ad5c57dd11bc..498d8886eec3 100644 --- a/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java @@ -16,10 +16,15 @@ package com.android.server.people.data; +import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED; +import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED; +import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED; + import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; @@ -33,6 +38,8 @@ import static org.mockito.Mockito.when; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; import android.app.Person; import android.app.prediction.AppTarget; import android.app.prediction.AppTargetEvent; @@ -88,6 +95,7 @@ public final class DataManagerTest { private static final String TEST_SHORTCUT_ID = "sc"; private static final String CONTACT_URI = "content://com.android.contacts/contacts/lookup/123"; private static final String PHONE_NUMBER = "+1234567890"; + private static final String NOTIFICATION_CHANNEL_ID = "test : sc"; private static final long MILLIS_PER_MINUTE = 1000L * 60L; @Mock private Context mContext; @@ -103,6 +111,7 @@ public final class DataManagerTest { @Mock private StatusBarNotification mStatusBarNotification; @Mock private Notification mNotification; + private NotificationChannel mNotificationChannel; private DataManager mDataManager; private int mCallingUserId; private TestInjector mInjector; @@ -152,6 +161,10 @@ public final class DataManagerTest { when(mStatusBarNotification.getUser()).thenReturn(UserHandle.of(USER_ID_PRIMARY)); when(mNotification.getShortcutId()).thenReturn(TEST_SHORTCUT_ID); + mNotificationChannel = new NotificationChannel( + NOTIFICATION_CHANNEL_ID, "test channel", NotificationManager.IMPORTANCE_DEFAULT); + mNotificationChannel.setConversationId("test", TEST_SHORTCUT_ID); + mCallingUserId = USER_ID_PRIMARY; mInjector = new TestInjector(); @@ -284,9 +297,8 @@ public final class DataManagerTest { } @Test - public void testNotificationListener() { + public void testNotificationOpened() { mDataManager.onUserUnlocked(USER_ID_PRIMARY); - mDataManager.onUserUnlocked(USER_ID_SECONDARY); ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, buildPerson()); @@ -308,6 +320,83 @@ public final class DataManagerTest { } @Test + public void testNotificationChannelCreated() { + mDataManager.onUserUnlocked(USER_ID_PRIMARY); + mDataManager.onUserUnlocked(USER_ID_SECONDARY); + + ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, + buildPerson()); + mDataManager.onShortcutAddedOrUpdated(shortcut); + + NotificationListenerService listenerService = + mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY); + listenerService.onNotificationChannelModified(TEST_PKG_NAME, UserHandle.of(USER_ID_PRIMARY), + mNotificationChannel, NOTIFICATION_CHANNEL_OR_GROUP_ADDED); + + ConversationInfo conversationInfo = mDataManager.getPackage(TEST_PKG_NAME, USER_ID_PRIMARY) + .getConversationStore() + .getConversation(TEST_SHORTCUT_ID); + assertEquals(NOTIFICATION_CHANNEL_ID, conversationInfo.getNotificationChannelId()); + assertFalse(conversationInfo.isImportant()); + assertFalse(conversationInfo.isNotificationSilenced()); + assertFalse(conversationInfo.isDemoted()); + } + + @Test + public void testNotificationChannelModified() { + mNotificationChannel.setImportantConversation(true); + + mDataManager.onUserUnlocked(USER_ID_PRIMARY); + mDataManager.onUserUnlocked(USER_ID_SECONDARY); + + ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, + buildPerson()); + mDataManager.onShortcutAddedOrUpdated(shortcut); + + NotificationListenerService listenerService = + mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY); + listenerService.onNotificationChannelModified(TEST_PKG_NAME, UserHandle.of(USER_ID_PRIMARY), + mNotificationChannel, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED); + + ConversationInfo conversationInfo = mDataManager.getPackage(TEST_PKG_NAME, USER_ID_PRIMARY) + .getConversationStore() + .getConversation(TEST_SHORTCUT_ID); + assertEquals(NOTIFICATION_CHANNEL_ID, conversationInfo.getNotificationChannelId()); + assertTrue(conversationInfo.isImportant()); + assertFalse(conversationInfo.isNotificationSilenced()); + assertFalse(conversationInfo.isDemoted()); + } + + @Test + public void testNotificationChannelDeleted() { + mDataManager.onUserUnlocked(USER_ID_PRIMARY); + mDataManager.onUserUnlocked(USER_ID_SECONDARY); + + ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, + buildPerson()); + mDataManager.onShortcutAddedOrUpdated(shortcut); + + NotificationListenerService listenerService = + mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY); + listenerService.onNotificationChannelModified(TEST_PKG_NAME, UserHandle.of(USER_ID_PRIMARY), + mNotificationChannel, NOTIFICATION_CHANNEL_OR_GROUP_ADDED); + ConversationInfo conversationInfo = mDataManager.getPackage(TEST_PKG_NAME, USER_ID_PRIMARY) + .getConversationStore() + .getConversation(TEST_SHORTCUT_ID); + assertEquals(NOTIFICATION_CHANNEL_ID, conversationInfo.getNotificationChannelId()); + + listenerService.onNotificationChannelModified(TEST_PKG_NAME, UserHandle.of(USER_ID_PRIMARY), + mNotificationChannel, NOTIFICATION_CHANNEL_OR_GROUP_DELETED); + conversationInfo = mDataManager.getPackage(TEST_PKG_NAME, USER_ID_PRIMARY) + .getConversationStore() + .getConversation(TEST_SHORTCUT_ID); + assertNull(conversationInfo.getNotificationChannelId()); + assertFalse(conversationInfo.isImportant()); + assertFalse(conversationInfo.isNotificationSilenced()); + assertFalse(conversationInfo.isDemoted()); + } + + @Test public void testCallLogContentObserver() { mDataManager.onUserUnlocked(USER_ID_PRIMARY); mDataManager.onUserUnlocked(USER_ID_SECONDARY); |