Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit af08278d authored by Julia Reynolds's avatar Julia Reynolds Committed by Android (Google) Code Review
Browse files

Merge "Restrict TYPE_MANAGED to rules added or updated by a Device Owner" into main

parents 474c8834 a00cb576
Loading
Loading
Loading
Loading
+26 −18
Original line number Diff line number Diff line
@@ -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) {
@@ -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
@@ -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");
+37 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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);