Loading services/core/java/com/android/server/notification/NotificationManagerService.java +26 −18 Original line number Diff line number Diff line Loading @@ -5334,14 +5334,7 @@ public class NotificationManagerService extends SystemService { @Override public String addAutomaticZenRule(AutomaticZenRule automaticZenRule, String pkg) { Objects.requireNonNull(automaticZenRule, "automaticZenRule is null"); Objects.requireNonNull(automaticZenRule.getName(), "Name is null"); if (automaticZenRule.getOwner() == null && automaticZenRule.getConfigurationActivity() == null) { throw new NullPointerException( "Rule must have a conditionproviderservice and/or configuration activity"); } Objects.requireNonNull(automaticZenRule.getConditionId(), "ConditionId is null"); validateAutomaticZenRule(automaticZenRule); checkCallerIsSameApp(pkg); if (automaticZenRule.getZenPolicy() != null && automaticZenRule.getInterruptionFilter() != INTERRUPTION_FILTER_PRIORITY) { Loading @@ -5368,16 +5361,8 @@ public class NotificationManagerService extends SystemService { } @Override public boolean updateAutomaticZenRule(String id, AutomaticZenRule automaticZenRule) throws RemoteException { Objects.requireNonNull(automaticZenRule, "automaticZenRule is null"); Objects.requireNonNull(automaticZenRule.getName(), "Name is null"); if (automaticZenRule.getOwner() == null && automaticZenRule.getConfigurationActivity() == null) { throw new NullPointerException( "Rule must have a conditionproviderservice and/or configuration activity"); } Objects.requireNonNull(automaticZenRule.getConditionId(), "ConditionId is null"); public boolean updateAutomaticZenRule(String id, AutomaticZenRule automaticZenRule) { validateAutomaticZenRule(automaticZenRule); enforcePolicyAccess(Binder.getCallingUid(), "updateAutomaticZenRule"); // TODO: b/308670715: Distinguish origin properly (e.g. USER if updating a rule Loading @@ -5388,6 +5373,29 @@ public class NotificationManagerService extends SystemService { "updateAutomaticZenRule", Binder.getCallingUid()); } private void validateAutomaticZenRule(AutomaticZenRule rule) { Objects.requireNonNull(rule, "automaticZenRule is null"); Objects.requireNonNull(rule.getName(), "Name is null"); if (rule.getOwner() == null && rule.getConfigurationActivity() == null) { throw new NullPointerException( "Rule must have a conditionproviderservice and/or configuration activity"); } Objects.requireNonNull(rule.getConditionId(), "ConditionId is null"); if (android.app.Flags.modesApi()) { if (rule.getType() == AutomaticZenRule.TYPE_MANAGED) { int uid = Binder.getCallingUid(); boolean isDeviceOwner = Binder.withCleanCallingIdentity( () -> mDpm.isActiveDeviceOwner(uid)); if (!isDeviceOwner) { throw new IllegalArgumentException( "Only Device Owners can use AutomaticZenRules with TYPE_MANAGED"); } } } } @Override public boolean removeAutomaticZenRule(String id) throws RemoteException { Objects.requireNonNull(id, "Id is null"); Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +37 −0 Original line number Diff line number Diff line Loading @@ -209,6 +209,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.WorkSource; import android.permission.PermissionManager; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.provider.DeviceConfig; import android.provider.MediaStore; Loading Loading @@ -8977,6 +8978,42 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { anyString(), anyInt()); // doesn't count as a system/systemui call } @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) public void testAddAutomaticZenRule_typeManagedCanBeUsedByDeviceOwners() throws Exception { mService.setCallerIsNormalPackage(); mService.setZenHelper(mock(ZenModeHelper.class)); when(mConditionProviders.isPackageOrComponentAllowed(anyString(), anyInt())) .thenReturn(true); AutomaticZenRule rule = new AutomaticZenRule.Builder("rule", Uri.parse("uri")) .setType(AutomaticZenRule.TYPE_MANAGED) .setOwner(new ComponentName("pkg", "cls")) .build(); when(mDevicePolicyManager.isActiveDeviceOwner(anyInt())).thenReturn(true); mBinderService.addAutomaticZenRule(rule, "pkg"); // No exception! } @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) public void testAddAutomaticZenRule_typeManagedCannotBeUsedByRegularApps() throws Exception { mService.setCallerIsNormalPackage(); mService.setZenHelper(mock(ZenModeHelper.class)); when(mConditionProviders.isPackageOrComponentAllowed(anyString(), anyInt())) .thenReturn(true); AutomaticZenRule rule = new AutomaticZenRule.Builder("rule", Uri.parse("uri")) .setType(AutomaticZenRule.TYPE_MANAGED) .setOwner(new ComponentName("pkg", "cls")) .build(); when(mDevicePolicyManager.isActiveDeviceOwner(anyInt())).thenReturn(false); assertThrows(IllegalArgumentException.class, () -> mBinderService.addAutomaticZenRule(rule, "pkg")); } @Test public void onZenModeChanged_sendsBroadcasts() throws Exception { when(mAmi.getCurrentUserId()).thenReturn(100); Loading Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +26 −18 Original line number Diff line number Diff line Loading @@ -5334,14 +5334,7 @@ public class NotificationManagerService extends SystemService { @Override public String addAutomaticZenRule(AutomaticZenRule automaticZenRule, String pkg) { Objects.requireNonNull(automaticZenRule, "automaticZenRule is null"); Objects.requireNonNull(automaticZenRule.getName(), "Name is null"); if (automaticZenRule.getOwner() == null && automaticZenRule.getConfigurationActivity() == null) { throw new NullPointerException( "Rule must have a conditionproviderservice and/or configuration activity"); } Objects.requireNonNull(automaticZenRule.getConditionId(), "ConditionId is null"); validateAutomaticZenRule(automaticZenRule); checkCallerIsSameApp(pkg); if (automaticZenRule.getZenPolicy() != null && automaticZenRule.getInterruptionFilter() != INTERRUPTION_FILTER_PRIORITY) { Loading @@ -5368,16 +5361,8 @@ public class NotificationManagerService extends SystemService { } @Override public boolean updateAutomaticZenRule(String id, AutomaticZenRule automaticZenRule) throws RemoteException { Objects.requireNonNull(automaticZenRule, "automaticZenRule is null"); Objects.requireNonNull(automaticZenRule.getName(), "Name is null"); if (automaticZenRule.getOwner() == null && automaticZenRule.getConfigurationActivity() == null) { throw new NullPointerException( "Rule must have a conditionproviderservice and/or configuration activity"); } Objects.requireNonNull(automaticZenRule.getConditionId(), "ConditionId is null"); public boolean updateAutomaticZenRule(String id, AutomaticZenRule automaticZenRule) { validateAutomaticZenRule(automaticZenRule); enforcePolicyAccess(Binder.getCallingUid(), "updateAutomaticZenRule"); // TODO: b/308670715: Distinguish origin properly (e.g. USER if updating a rule Loading @@ -5388,6 +5373,29 @@ public class NotificationManagerService extends SystemService { "updateAutomaticZenRule", Binder.getCallingUid()); } private void validateAutomaticZenRule(AutomaticZenRule rule) { Objects.requireNonNull(rule, "automaticZenRule is null"); Objects.requireNonNull(rule.getName(), "Name is null"); if (rule.getOwner() == null && rule.getConfigurationActivity() == null) { throw new NullPointerException( "Rule must have a conditionproviderservice and/or configuration activity"); } Objects.requireNonNull(rule.getConditionId(), "ConditionId is null"); if (android.app.Flags.modesApi()) { if (rule.getType() == AutomaticZenRule.TYPE_MANAGED) { int uid = Binder.getCallingUid(); boolean isDeviceOwner = Binder.withCleanCallingIdentity( () -> mDpm.isActiveDeviceOwner(uid)); if (!isDeviceOwner) { throw new IllegalArgumentException( "Only Device Owners can use AutomaticZenRules with TYPE_MANAGED"); } } } } @Override public boolean removeAutomaticZenRule(String id) throws RemoteException { Objects.requireNonNull(id, "Id is null"); Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +37 −0 Original line number Diff line number Diff line Loading @@ -209,6 +209,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.WorkSource; import android.permission.PermissionManager; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.provider.DeviceConfig; import android.provider.MediaStore; Loading Loading @@ -8977,6 +8978,42 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { anyString(), anyInt()); // doesn't count as a system/systemui call } @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) public void testAddAutomaticZenRule_typeManagedCanBeUsedByDeviceOwners() throws Exception { mService.setCallerIsNormalPackage(); mService.setZenHelper(mock(ZenModeHelper.class)); when(mConditionProviders.isPackageOrComponentAllowed(anyString(), anyInt())) .thenReturn(true); AutomaticZenRule rule = new AutomaticZenRule.Builder("rule", Uri.parse("uri")) .setType(AutomaticZenRule.TYPE_MANAGED) .setOwner(new ComponentName("pkg", "cls")) .build(); when(mDevicePolicyManager.isActiveDeviceOwner(anyInt())).thenReturn(true); mBinderService.addAutomaticZenRule(rule, "pkg"); // No exception! } @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) public void testAddAutomaticZenRule_typeManagedCannotBeUsedByRegularApps() throws Exception { mService.setCallerIsNormalPackage(); mService.setZenHelper(mock(ZenModeHelper.class)); when(mConditionProviders.isPackageOrComponentAllowed(anyString(), anyInt())) .thenReturn(true); AutomaticZenRule rule = new AutomaticZenRule.Builder("rule", Uri.parse("uri")) .setType(AutomaticZenRule.TYPE_MANAGED) .setOwner(new ComponentName("pkg", "cls")) .build(); when(mDevicePolicyManager.isActiveDeviceOwner(anyInt())).thenReturn(false); assertThrows(IllegalArgumentException.class, () -> mBinderService.addAutomaticZenRule(rule, "pkg")); } @Test public void onZenModeChanged_sendsBroadcasts() throws Exception { when(mAmi.getCurrentUserId()).thenReturn(100); Loading