diff options
3 files changed, 113 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index a1646862de9f..de3f50ad8c2c 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -1087,7 +1087,8 @@ public class NotificationManagerService extends SystemService { || (queryRestart=action.equals(Intent.ACTION_QUERY_PACKAGE_RESTART)) || action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE) || action.equals(Intent.ACTION_PACKAGES_SUSPENDED) - || action.equals(Intent.ACTION_PACKAGES_UNSUSPENDED)) { + || action.equals(Intent.ACTION_PACKAGES_UNSUSPENDED) + || action.equals(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED)) { int changeUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_ALL); String pkgList[] = null; @@ -1108,6 +1109,23 @@ public class NotificationManagerService extends SystemService { uidList = intent.getIntArrayExtra(Intent.EXTRA_CHANGED_UID_LIST); cancelNotifications = false; unhideNotifications = true; + } else if (action.equals(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED)) { + final int distractionRestrictions = + intent.getIntExtra(Intent.EXTRA_DISTRACTION_RESTRICTIONS, + PackageManager.RESTRICTION_NONE); + if ((distractionRestrictions + & PackageManager.RESTRICTION_HIDE_NOTIFICATIONS) != 0) { + pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); + uidList = intent.getIntArrayExtra(Intent.EXTRA_CHANGED_UID_LIST); + cancelNotifications = false; + hideNotifications = true; + } else { + pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); + uidList = intent.getIntArrayExtra(Intent.EXTRA_CHANGED_UID_LIST); + cancelNotifications = false; + unhideNotifications = true; + } + } else if (queryRestart) { pkgList = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); uidList = new int[] {intent.getIntExtra(Intent.EXTRA_UID, -1)}; @@ -1651,6 +1669,7 @@ public class NotificationManagerService extends SystemService { IntentFilter suspendedPkgFilter = new IntentFilter(); suspendedPkgFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED); suspendedPkgFilter.addAction(Intent.ACTION_PACKAGES_UNSUSPENDED); + suspendedPkgFilter.addAction(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED); getContext().registerReceiverAsUser(mPackageIntentReceiver, UserHandle.ALL, suspendedPkgFilter, null, null); @@ -7743,6 +7762,20 @@ public class NotificationManagerService extends SystemService { mPackageIntentReceiver.onReceive(getContext(), intent); } + @VisibleForTesting + protected void simulatePackageDistractionBroadcast(int flag, String[] pkgs) { + // only use for testing: mimic receive broadcast that package is (un)distracting + // but does not actually register that info with packagemanager + final Bundle extras = new Bundle(); + extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgs); + extras.putInt(Intent.EXTRA_DISTRACTION_RESTRICTIONS, flag); + + final Intent intent = new Intent(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED); + intent.putExtras(extras); + + mPackageIntentReceiver.onReceive(getContext(), intent); + } + /** * Wrapper for a StatusBarNotification object that allows transfer across a oneway * binder without sending large amounts of data over a oneway transaction. diff --git a/services/core/java/com/android/server/notification/NotificationShellCmd.java b/services/core/java/com/android/server/notification/NotificationShellCmd.java index 3d88f20f0710..2aaa1edcfad9 100644 --- a/services/core/java/com/android/server/notification/NotificationShellCmd.java +++ b/services/core/java/com/android/server/notification/NotificationShellCmd.java @@ -176,6 +176,14 @@ public class NotificationShellCmd extends ShellCommand { // only use for testing mDirectService.simulatePackageSuspendBroadcast(false, getNextArgRequired()); } + case "distract_package": { + // only use for testing + // Flag values are in + // {@link android.content.pm.PackageManager.DistractionRestriction}. + mDirectService.simulatePackageDistractionBroadcast( + Integer.parseInt(getNextArgRequired()), + getNextArgRequired().split(",")); + } break; case "post": case "notify": diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 62229235a026..9c6ab0ab9aa9 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -3410,6 +3410,77 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void testHideAndUnhideNotificationsOnDistractingPackageBroadcast() { + // Post 2 notifications from 2 packages + NotificationRecord pkgA = new NotificationRecord(mContext, + generateSbn("a", 1000, 9, 0), mTestNotificationChannel); + mService.addNotification(pkgA); + NotificationRecord pkgB = new NotificationRecord(mContext, + generateSbn("b", 1001, 9, 0), mTestNotificationChannel); + mService.addNotification(pkgB); + + // on broadcast, hide one of the packages + mService.simulatePackageDistractionBroadcast( + PackageManager.RESTRICTION_HIDE_NOTIFICATIONS, new String[] {"a"}); + ArgumentCaptor<List<NotificationRecord>> captorHide = ArgumentCaptor.forClass(List.class); + verify(mListeners, times(1)).notifyHiddenLocked(captorHide.capture()); + assertEquals(1, captorHide.getValue().size()); + assertEquals("a", captorHide.getValue().get(0).sbn.getPackageName()); + + // on broadcast, unhide the package + mService.simulatePackageDistractionBroadcast( + PackageManager.RESTRICTION_HIDE_FROM_SUGGESTIONS, new String[] {"a"}); + ArgumentCaptor<List<NotificationRecord>> captorUnhide = ArgumentCaptor.forClass(List.class); + verify(mListeners, times(1)).notifyUnhiddenLocked(captorUnhide.capture()); + assertEquals(1, captorUnhide.getValue().size()); + assertEquals("a", captorUnhide.getValue().get(0).sbn.getPackageName()); + } + + @Test + public void testHideAndUnhideNotificationsOnDistractingPackageBroadcast_multiPkg() { + // Post 2 notifications from 2 packages + NotificationRecord pkgA = new NotificationRecord(mContext, + generateSbn("a", 1000, 9, 0), mTestNotificationChannel); + mService.addNotification(pkgA); + NotificationRecord pkgB = new NotificationRecord(mContext, + generateSbn("b", 1001, 9, 0), mTestNotificationChannel); + mService.addNotification(pkgB); + + // on broadcast, hide one of the packages + mService.simulatePackageDistractionBroadcast( + PackageManager.RESTRICTION_HIDE_NOTIFICATIONS, new String[] {"a", "b"}); + ArgumentCaptor<List<NotificationRecord>> captorHide = ArgumentCaptor.forClass(List.class); + verify(mListeners, times(2)).notifyHiddenLocked(captorHide.capture()); + assertEquals(2, captorHide.getValue().size()); + assertEquals("a", captorHide.getValue().get(0).sbn.getPackageName()); + assertEquals("b", captorHide.getValue().get(1).sbn.getPackageName()); + + // on broadcast, unhide the package + mService.simulatePackageDistractionBroadcast( + PackageManager.RESTRICTION_HIDE_FROM_SUGGESTIONS, new String[] {"a", "b"}); + ArgumentCaptor<List<NotificationRecord>> captorUnhide = ArgumentCaptor.forClass(List.class); + verify(mListeners, times(2)).notifyUnhiddenLocked(captorUnhide.capture()); + assertEquals(2, captorUnhide.getValue().size()); + assertEquals("a", captorUnhide.getValue().get(0).sbn.getPackageName()); + assertEquals("b", captorUnhide.getValue().get(1).sbn.getPackageName()); + } + + @Test + public void testNoNotificationsHiddenOnDistractingPackageBroadcast() { + // post notification from this package + final NotificationRecord notif1 = generateNotificationRecord( + mTestNotificationChannel, 1, null, true); + mService.addNotification(notif1); + + // on broadcast, nothing is hidden since no notifications are of package "test_package" + mService.simulatePackageDistractionBroadcast( + PackageManager.RESTRICTION_HIDE_NOTIFICATIONS, new String[] {"test_package"}); + ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class); + verify(mListeners, times(1)).notifyHiddenLocked(captor.capture()); + assertEquals(0, captor.getValue().size()); + } + + @Test public void testCanUseManagedServicesLowRamNoWatchNullPkg() { when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false); when(mActivityManager.isLowRamDevice()).thenReturn(true); |