Loading services/core/java/com/android/server/notification/ManagedServices.java +1 −19 Original line number Diff line number Diff line Loading @@ -892,6 +892,7 @@ abstract public class ManagedServices { return allowedComponents; } @NonNull protected List<String> getAllowedPackages(int userId) { final List<String> allowedPackages = new ArrayList<>(); synchronized (mApproved) { Loading Loading @@ -1181,25 +1182,6 @@ abstract public class ManagedServices { return installed; } protected Set<String> getAllowedPackages() { final Set<String> allowedPackages = new ArraySet<>(); synchronized (mApproved) { for (int k = 0; k < mApproved.size(); k++) { ArrayMap<Boolean, ArraySet<String>> allowedByType = mApproved.valueAt(k); for (int i = 0; i < allowedByType.size(); i++) { final ArraySet<String> allowed = allowedByType.valueAt(i); for (int j = 0; j < allowed.size(); j++) { String pkgName = getPackageName(allowed.valueAt(j)); if (!TextUtils.isEmpty(pkgName)) { allowedPackages.add(pkgName); } } } } } return allowedPackages; } private void trimApprovedListsAccordingToInstalledServices(int userId) { synchronized (mApproved) { final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(userId); Loading services/core/java/com/android/server/notification/NotificationManagerService.java +11 −9 Original line number Diff line number Diff line Loading @@ -2709,16 +2709,18 @@ public class NotificationManagerService extends SystemService { } private void sendRegisteredOnlyBroadcast(String action) { Intent intent = new Intent(action); getContext().sendBroadcastAsUser(intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY), UserHandle.ALL, null); int[] userIds = mUmInternal.getProfileIds(mAmi.getCurrentUserId(), true); Intent intent = new Intent(action).addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); for (int userId : userIds) { getContext().sendBroadcastAsUser(intent, UserHandle.of(userId), null); } // explicitly send the broadcast to all DND packages, even if they aren't currently running intent.setFlags(0); final Set<String> dndApprovedPackages = mConditionProviders.getAllowedPackages(); for (String pkg : dndApprovedPackages) { intent.setPackage(pkg); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); getContext().sendBroadcastAsUser(intent, UserHandle.ALL); for (int userId : userIds) { for (String pkg : mConditionProviders.getAllowedPackages(userId)) { Intent pkgIntent = new Intent(action).setPackage(pkg).setFlags( Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); getContext().sendBroadcastAsUser(pkgIntent, UserHandle.of(userId)); } } } Loading services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java +7 −47 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ import static android.service.notification.NotificationListenerService.META_DATA import static com.android.server.notification.ManagedServices.APPROVAL_BY_COMPONENT; import static com.android.server.notification.ManagedServices.APPROVAL_BY_PACKAGE; import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertNotNull; Loading Loading @@ -1201,28 +1203,11 @@ public class ManagedServicesTest extends UiServiceTestCase { mIpm, approvalLevel); loadXml(service); List<String> allowedPackagesForUser0 = new ArrayList<>(); allowedPackagesForUser0.add("this.is.a.package.name"); allowedPackagesForUser0.add("another.package"); allowedPackagesForUser0.add("secondary"); List<String> actual = service.getAllowedPackages(0); assertEquals(3, actual.size()); for (String pkg : allowedPackagesForUser0) { assertTrue(actual.contains(pkg)); } List<String> allowedPackagesForUser10 = new ArrayList<>(); allowedPackagesForUser10.add("this.is.another.package"); allowedPackagesForUser10.add("package"); allowedPackagesForUser10.add("this.is.another.package"); allowedPackagesForUser10.add("component"); actual = service.getAllowedPackages(10); assertEquals(4, actual.size()); for (String pkg : allowedPackagesForUser10) { assertTrue(actual.contains(pkg)); } assertThat(service.getAllowedPackages(0)).containsExactly("this.is.a.package.name", "another.package", "secondary"); assertThat(service.getAllowedPackages(10)).containsExactly("this.is.another.package", "package", "this.is.another.package", "component"); assertThat(service.getAllowedPackages(999)).isEmpty(); } } Loading Loading @@ -1262,31 +1247,6 @@ public class ManagedServicesTest extends UiServiceTestCase { assertEquals(0, service.getAllowedComponents(10).size()); } @Test public void testGetAllowedPackages() throws Exception { ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm, APPROVAL_BY_COMPONENT); loadXml(service); service.mApprovalLevel = APPROVAL_BY_PACKAGE; loadXml(service); List<String> allowedPackages = new ArrayList<>(); allowedPackages.add("this.is.a.package.name"); allowedPackages.add("another.package"); allowedPackages.add("secondary"); allowedPackages.add("this.is.another.package"); allowedPackages.add("package"); allowedPackages.add("component"); allowedPackages.add("bananas!"); allowedPackages.add("non.user.set.package"); Set<String> actual = service.getAllowedPackages(); assertEquals(allowedPackages.size(), actual.size()); for (String pkg : allowedPackages) { assertTrue(actual.contains(pkg)); } } @Test public void testOnUserRemoved() throws Exception { for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) { Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +75 −1 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import static android.app.Notification.FLAG_FOREGROUND_SERVICE; import static android.app.Notification.FLAG_NO_CLEAR; import static android.app.Notification.FLAG_ONGOING_EVENT; import static android.app.NotificationChannel.USER_LOCKED_ALLOW_BUBBLE; import static android.app.NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED; import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL; import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE; import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED; Loading @@ -50,7 +51,6 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR; import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.app.PendingIntent.FLAG_MUTABLE; import static android.app.PendingIntent.FLAG_ONE_SHOT; Loading Loading @@ -237,6 +237,7 @@ import com.android.server.utils.quota.MultiRateLimiter; import com.android.server.wm.ActivityTaskManagerInternal; import com.android.server.wm.WindowManagerInternal; import com.google.android.collect.Lists; import com.google.common.collect.ImmutableList; import org.junit.After; Loading @@ -245,10 +246,13 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; import org.mockito.ArgumentMatchers; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import java.io.BufferedInputStream; Loading Loading @@ -440,6 +444,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mContext.addMockSystemService(Context.ALARM_SERVICE, mAlarmManager); mContext.addMockSystemService(NotificationManager.class, mMockNm); doNothing().when(mContext).sendBroadcastAsUser(any(), any()); doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any()); setDpmAppOppsExemptFromDismissal(false); Loading Loading @@ -7827,6 +7832,75 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { eq("another.package"), eq(rule), anyString()); } @Test public void onZenModeChanged_sendsBroadcasts() throws Exception { when(mAmi.getCurrentUserId()).thenReturn(100); when(mUmInternal.getProfileIds(eq(100), anyBoolean())).thenReturn(new int[]{100, 101, 102}); when(mConditionProviders.getAllowedPackages(anyInt())).then(new Answer<List<String>>() { @Override public List<String> answer(InvocationOnMock invocation) { int userId = invocation.getArgument(0); switch (userId) { case 100: return Lists.newArrayList("a", "b", "c"); case 101: return Lists.newArrayList(); case 102: return Lists.newArrayList("b"); default: throw new IllegalArgumentException( "Why would you ask for packages of userId " + userId + "?"); } } }); mService.getBinderService().setZenMode(Settings.Global.ZEN_MODE_NO_INTERRUPTIONS, null, "testing!"); waitForIdle(); InOrder inOrder = inOrder(mContext); // Verify broadcasts for registered receivers inOrder.verify(mContext).sendBroadcastAsUser(eqIntent( new Intent(ACTION_INTERRUPTION_FILTER_CHANGED).setFlags( Intent.FLAG_RECEIVER_REGISTERED_ONLY)), eq(UserHandle.of(100)), eq(null)); inOrder.verify(mContext).sendBroadcastAsUser(eqIntent( new Intent(ACTION_INTERRUPTION_FILTER_CHANGED).setFlags( Intent.FLAG_RECEIVER_REGISTERED_ONLY)), eq(UserHandle.of(101)), eq(null)); inOrder.verify(mContext).sendBroadcastAsUser(eqIntent( new Intent(ACTION_INTERRUPTION_FILTER_CHANGED).setFlags( Intent.FLAG_RECEIVER_REGISTERED_ONLY)), eq(UserHandle.of(102)), eq(null)); // Verify broadcast for packages that manage DND. inOrder.verify(mContext).sendBroadcastAsUser(eqIntent(new Intent( ACTION_INTERRUPTION_FILTER_CHANGED).setPackage("a").setFlags( Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)), eq(UserHandle.of(100))); inOrder.verify(mContext).sendBroadcastAsUser(eqIntent(new Intent( ACTION_INTERRUPTION_FILTER_CHANGED).setPackage("b").setFlags( Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)), eq(UserHandle.of(100))); inOrder.verify(mContext).sendBroadcastAsUser(eqIntent(new Intent( ACTION_INTERRUPTION_FILTER_CHANGED).setPackage("c").setFlags( Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)), eq(UserHandle.of(100))); inOrder.verify(mContext).sendBroadcastAsUser(eqIntent(new Intent( ACTION_INTERRUPTION_FILTER_CHANGED).setPackage("b").setFlags( Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)), eq(UserHandle.of(102))); } private static Intent eqIntent(Intent wanted) { return ArgumentMatchers.argThat( new ArgumentMatcher<Intent>() { @Override public boolean matches(Intent argument) { return wanted.filterEquals(argument) && wanted.getFlags() == argument.getFlags(); } @Override public String toString() { return wanted.toString(); } }); } @Test public void testAreNotificationsEnabledForPackage() throws Exception { mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(), Loading Loading
services/core/java/com/android/server/notification/ManagedServices.java +1 −19 Original line number Diff line number Diff line Loading @@ -892,6 +892,7 @@ abstract public class ManagedServices { return allowedComponents; } @NonNull protected List<String> getAllowedPackages(int userId) { final List<String> allowedPackages = new ArrayList<>(); synchronized (mApproved) { Loading Loading @@ -1181,25 +1182,6 @@ abstract public class ManagedServices { return installed; } protected Set<String> getAllowedPackages() { final Set<String> allowedPackages = new ArraySet<>(); synchronized (mApproved) { for (int k = 0; k < mApproved.size(); k++) { ArrayMap<Boolean, ArraySet<String>> allowedByType = mApproved.valueAt(k); for (int i = 0; i < allowedByType.size(); i++) { final ArraySet<String> allowed = allowedByType.valueAt(i); for (int j = 0; j < allowed.size(); j++) { String pkgName = getPackageName(allowed.valueAt(j)); if (!TextUtils.isEmpty(pkgName)) { allowedPackages.add(pkgName); } } } } } return allowedPackages; } private void trimApprovedListsAccordingToInstalledServices(int userId) { synchronized (mApproved) { final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(userId); Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +11 −9 Original line number Diff line number Diff line Loading @@ -2709,16 +2709,18 @@ public class NotificationManagerService extends SystemService { } private void sendRegisteredOnlyBroadcast(String action) { Intent intent = new Intent(action); getContext().sendBroadcastAsUser(intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY), UserHandle.ALL, null); int[] userIds = mUmInternal.getProfileIds(mAmi.getCurrentUserId(), true); Intent intent = new Intent(action).addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); for (int userId : userIds) { getContext().sendBroadcastAsUser(intent, UserHandle.of(userId), null); } // explicitly send the broadcast to all DND packages, even if they aren't currently running intent.setFlags(0); final Set<String> dndApprovedPackages = mConditionProviders.getAllowedPackages(); for (String pkg : dndApprovedPackages) { intent.setPackage(pkg); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); getContext().sendBroadcastAsUser(intent, UserHandle.ALL); for (int userId : userIds) { for (String pkg : mConditionProviders.getAllowedPackages(userId)) { Intent pkgIntent = new Intent(action).setPackage(pkg).setFlags( Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); getContext().sendBroadcastAsUser(pkgIntent, UserHandle.of(userId)); } } } Loading
services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java +7 −47 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ import static android.service.notification.NotificationListenerService.META_DATA import static com.android.server.notification.ManagedServices.APPROVAL_BY_COMPONENT; import static com.android.server.notification.ManagedServices.APPROVAL_BY_PACKAGE; import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertNotNull; Loading Loading @@ -1201,28 +1203,11 @@ public class ManagedServicesTest extends UiServiceTestCase { mIpm, approvalLevel); loadXml(service); List<String> allowedPackagesForUser0 = new ArrayList<>(); allowedPackagesForUser0.add("this.is.a.package.name"); allowedPackagesForUser0.add("another.package"); allowedPackagesForUser0.add("secondary"); List<String> actual = service.getAllowedPackages(0); assertEquals(3, actual.size()); for (String pkg : allowedPackagesForUser0) { assertTrue(actual.contains(pkg)); } List<String> allowedPackagesForUser10 = new ArrayList<>(); allowedPackagesForUser10.add("this.is.another.package"); allowedPackagesForUser10.add("package"); allowedPackagesForUser10.add("this.is.another.package"); allowedPackagesForUser10.add("component"); actual = service.getAllowedPackages(10); assertEquals(4, actual.size()); for (String pkg : allowedPackagesForUser10) { assertTrue(actual.contains(pkg)); } assertThat(service.getAllowedPackages(0)).containsExactly("this.is.a.package.name", "another.package", "secondary"); assertThat(service.getAllowedPackages(10)).containsExactly("this.is.another.package", "package", "this.is.another.package", "component"); assertThat(service.getAllowedPackages(999)).isEmpty(); } } Loading Loading @@ -1262,31 +1247,6 @@ public class ManagedServicesTest extends UiServiceTestCase { assertEquals(0, service.getAllowedComponents(10).size()); } @Test public void testGetAllowedPackages() throws Exception { ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm, APPROVAL_BY_COMPONENT); loadXml(service); service.mApprovalLevel = APPROVAL_BY_PACKAGE; loadXml(service); List<String> allowedPackages = new ArrayList<>(); allowedPackages.add("this.is.a.package.name"); allowedPackages.add("another.package"); allowedPackages.add("secondary"); allowedPackages.add("this.is.another.package"); allowedPackages.add("package"); allowedPackages.add("component"); allowedPackages.add("bananas!"); allowedPackages.add("non.user.set.package"); Set<String> actual = service.getAllowedPackages(); assertEquals(allowedPackages.size(), actual.size()); for (String pkg : allowedPackages) { assertTrue(actual.contains(pkg)); } } @Test public void testOnUserRemoved() throws Exception { for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) { Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +75 −1 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import static android.app.Notification.FLAG_FOREGROUND_SERVICE; import static android.app.Notification.FLAG_NO_CLEAR; import static android.app.Notification.FLAG_ONGOING_EVENT; import static android.app.NotificationChannel.USER_LOCKED_ALLOW_BUBBLE; import static android.app.NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED; import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL; import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE; import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED; Loading @@ -50,7 +51,6 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR; import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.app.PendingIntent.FLAG_MUTABLE; import static android.app.PendingIntent.FLAG_ONE_SHOT; Loading Loading @@ -237,6 +237,7 @@ import com.android.server.utils.quota.MultiRateLimiter; import com.android.server.wm.ActivityTaskManagerInternal; import com.android.server.wm.WindowManagerInternal; import com.google.android.collect.Lists; import com.google.common.collect.ImmutableList; import org.junit.After; Loading @@ -245,10 +246,13 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; import org.mockito.ArgumentMatchers; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import java.io.BufferedInputStream; Loading Loading @@ -440,6 +444,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mContext.addMockSystemService(Context.ALARM_SERVICE, mAlarmManager); mContext.addMockSystemService(NotificationManager.class, mMockNm); doNothing().when(mContext).sendBroadcastAsUser(any(), any()); doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any()); setDpmAppOppsExemptFromDismissal(false); Loading Loading @@ -7827,6 +7832,75 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { eq("another.package"), eq(rule), anyString()); } @Test public void onZenModeChanged_sendsBroadcasts() throws Exception { when(mAmi.getCurrentUserId()).thenReturn(100); when(mUmInternal.getProfileIds(eq(100), anyBoolean())).thenReturn(new int[]{100, 101, 102}); when(mConditionProviders.getAllowedPackages(anyInt())).then(new Answer<List<String>>() { @Override public List<String> answer(InvocationOnMock invocation) { int userId = invocation.getArgument(0); switch (userId) { case 100: return Lists.newArrayList("a", "b", "c"); case 101: return Lists.newArrayList(); case 102: return Lists.newArrayList("b"); default: throw new IllegalArgumentException( "Why would you ask for packages of userId " + userId + "?"); } } }); mService.getBinderService().setZenMode(Settings.Global.ZEN_MODE_NO_INTERRUPTIONS, null, "testing!"); waitForIdle(); InOrder inOrder = inOrder(mContext); // Verify broadcasts for registered receivers inOrder.verify(mContext).sendBroadcastAsUser(eqIntent( new Intent(ACTION_INTERRUPTION_FILTER_CHANGED).setFlags( Intent.FLAG_RECEIVER_REGISTERED_ONLY)), eq(UserHandle.of(100)), eq(null)); inOrder.verify(mContext).sendBroadcastAsUser(eqIntent( new Intent(ACTION_INTERRUPTION_FILTER_CHANGED).setFlags( Intent.FLAG_RECEIVER_REGISTERED_ONLY)), eq(UserHandle.of(101)), eq(null)); inOrder.verify(mContext).sendBroadcastAsUser(eqIntent( new Intent(ACTION_INTERRUPTION_FILTER_CHANGED).setFlags( Intent.FLAG_RECEIVER_REGISTERED_ONLY)), eq(UserHandle.of(102)), eq(null)); // Verify broadcast for packages that manage DND. inOrder.verify(mContext).sendBroadcastAsUser(eqIntent(new Intent( ACTION_INTERRUPTION_FILTER_CHANGED).setPackage("a").setFlags( Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)), eq(UserHandle.of(100))); inOrder.verify(mContext).sendBroadcastAsUser(eqIntent(new Intent( ACTION_INTERRUPTION_FILTER_CHANGED).setPackage("b").setFlags( Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)), eq(UserHandle.of(100))); inOrder.verify(mContext).sendBroadcastAsUser(eqIntent(new Intent( ACTION_INTERRUPTION_FILTER_CHANGED).setPackage("c").setFlags( Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)), eq(UserHandle.of(100))); inOrder.verify(mContext).sendBroadcastAsUser(eqIntent(new Intent( ACTION_INTERRUPTION_FILTER_CHANGED).setPackage("b").setFlags( Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)), eq(UserHandle.of(102))); } private static Intent eqIntent(Intent wanted) { return ArgumentMatchers.argThat( new ArgumentMatcher<Intent>() { @Override public boolean matches(Intent argument) { return wanted.filterEquals(argument) && wanted.getFlags() == argument.getFlags(); } @Override public String toString() { return wanted.toString(); } }); } @Test public void testAreNotificationsEnabledForPackage() throws Exception { mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(), Loading