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

Commit 061f570a authored by Matías Hernández's avatar Matías Hernández Committed by Android (Google) Code Review
Browse files

Merge "Make "strict zen component validation" less strict" into main

parents 724367e8 4d425d3b
Loading
Loading
Loading
Loading
+33 −19
Original line number Diff line number Diff line
@@ -6484,7 +6484,7 @@ public class NotificationManagerService extends SystemService {
        @Override
        public String addAutomaticZenRule(AutomaticZenRule automaticZenRule, String pkg,
                boolean fromUser) {
            validateAutomaticZenRule(/* updateId= */ null, automaticZenRule);
            automaticZenRule = validateAutomaticZenRule(/* updateId= */ null, automaticZenRule);
            checkCallerIsSameApp(pkg);
            if (automaticZenRule.getZenPolicy() != null
                    && automaticZenRule.getInterruptionFilter() != INTERRUPTION_FILTER_PRIORITY) {
@@ -6521,7 +6521,7 @@ public class NotificationManagerService extends SystemService {
        @Override
        public boolean updateAutomaticZenRule(String id, AutomaticZenRule automaticZenRule,
                boolean fromUser) throws RemoteException {
            validateAutomaticZenRule(id, automaticZenRule);
            automaticZenRule = validateAutomaticZenRule(id, automaticZenRule);
            enforcePolicyAccess(Binder.getCallingUid(), "updateAutomaticZenRule");
            enforceUserOriginOnlyFromSystem(fromUser, "updateAutomaticZenRule");
            UserHandle zenUser = getCallingZenUser();
@@ -6530,9 +6530,16 @@ public class NotificationManagerService extends SystemService {
                    computeZenOrigin(fromUser), "updateAutomaticZenRule", Binder.getCallingUid());
        }
        private void validateAutomaticZenRule(@Nullable String updateId, AutomaticZenRule rule) {
        /**
         * Validate and potentially "fix" a rule supplied to {@link #addAutomaticZenRule} or
         * {@link #updateAutomaticZenRule}.
         */
        @NonNull
        private AutomaticZenRule validateAutomaticZenRule(@Nullable String updateId,
                AutomaticZenRule rule) {
            Objects.requireNonNull(rule, "automaticZenRule is null");
            Objects.requireNonNull(rule.getName(), "Name is null");
            Objects.requireNonNull(rule.getConditionId(), "ConditionId is null");
            rule.validate();
            // Implicit rules have no ConditionProvider or Activity. We allow the user to customize
@@ -6548,37 +6555,42 @@ public class NotificationManagerService extends SystemService {
                        "Rule must have a ConditionProviderService and/or configuration "
                                + "activity");
            }
            Objects.requireNonNull(rule.getConditionId(), "ConditionId is null");
            // If supplied, both CPS and ConfigurationActivity must be accessible to the calling
            // package. Skip check when the caller is the system: for additions we trust ourselves,
            // and for updates we don't want to block updating a rule in Settings even if the owner
            // package has changed its manifest so that some component is gone.
            // package. Clear them out if invalid -- but at least one must remain.
            if (Flags.strictZenRuleComponentValidation() && !isCallerSystemOrSystemUi()) {
                if (rule.getOwner() != null) {
                    PackageItemInfo ownerInfo = mZenModeHelper.getServiceInfo(rule.getOwner());
                ComponentName ruleOwner = rule.getOwner();
                if (ruleOwner != null) {
                    PackageItemInfo ownerInfo = mZenModeHelper.getServiceInfo(ruleOwner);
                    if (ownerInfo == null) {
                        throw new IllegalArgumentException(
                                "Lacking enabled ConditionProviderService " + rule.getOwner());
                        Slog.e(TAG, "AZR.owner " + ruleOwner
                                + " is not valid. This might throw in a future release.");
                        rule = new AutomaticZenRule.Builder(rule).setOwner(null).build();
                    }
                }
                if (rule.getConfigurationActivity() != null) {
                    PackageItemInfo activityInfo = mZenModeHelper.getActivityInfo(
                            rule.getConfigurationActivity());
                ComponentName ruleActivity = rule.getConfigurationActivity();
                if (ruleActivity != null) {
                    PackageItemInfo activityInfo = mZenModeHelper.getActivityInfo(ruleActivity);
                    if (activityInfo == null) {
                        throw new IllegalArgumentException(
                                "Lacking enabled ConfigurationActivity "
                                        + rule.getConfigurationActivity());
                        Slog.e(TAG, "AZR.configurationActivity " + ruleActivity
                                + " is not valid. This might throw in a future release.");
                        rule = new AutomaticZenRule.Builder(rule)
                                .setConfigurationActivity(null)
                                .build();
                    }
                }
                if (rule.getOwner() == null && rule.getConfigurationActivity() == null) {
                    throw new IllegalArgumentException(
                            "Rule must have a valid (enabled) ConditionProviderService or "
                                    + "configurationActivity");
                }
            }
            if (isCallerSystemOrSystemUi()) {
                return; // System callers can use any type.
                return rule; // System callers can use any type.
            }
            int uid = Binder.getCallingUid();
            int userId = UserHandle.getUserId(uid);
            if (rule.getType() == AutomaticZenRule.TYPE_MANAGED) {
                boolean isDeviceOwner = Binder.withCleanCallingIdentity(
                        () -> mDpm.isActiveDeviceOwner(uid));
@@ -6597,6 +6609,8 @@ public class NotificationManagerService extends SystemService {
                                    + "TYPE_BEDTIME");
                }
            }
            return rule;
        }
        @Override
+86 −8
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import static android.app.NotificationSystemUtil.toggleNotificationPolicyAccess;
import static android.service.notification.Condition.STATE_FALSE;
import static android.service.notification.Condition.STATE_TRUE;

import static com.android.server.notification.Flags.FLAG_STRICT_ZEN_RULE_COMPONENT_VALIDATION;

import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.assertThrows;
@@ -101,6 +103,8 @@ public class NotificationManagerZenTest {

        AutomaticZenRule savedAzr = mNotificationManager.getAutomaticZenRule(ruleId);
        assertThat(savedAzr).isNotNull();
        assertThat(savedAzr.getOwner()).isEqualTo(CONDITION_PROVIDER_SERVICE);
        assertThat(savedAzr.getConfigurationActivity()).isEqualTo(CONFIGURATION_ACTIVITY);
        assertThat(savedAzr.getPackageName()).isEqualTo(mContext.getPackageName());
    }

@@ -115,6 +119,7 @@ public class NotificationManagerZenTest {

        AutomaticZenRule savedAzr = mNotificationManager.getAutomaticZenRule(ruleId);
        assertThat(savedAzr).isNotNull();
        assertThat(savedAzr.getOwner()).isEqualTo(CONDITION_PROVIDER_SERVICE);
        assertThat(savedAzr.getPackageName()).isEqualTo(mContext.getPackageName());
    }

@@ -129,6 +134,7 @@ public class NotificationManagerZenTest {

        AutomaticZenRule savedAzr = mNotificationManager.getAutomaticZenRule(ruleId);
        assertThat(savedAzr).isNotNull();
        assertThat(savedAzr.getConfigurationActivity()).isEqualTo(CONFIGURATION_ACTIVITY);
        assertThat(savedAzr.getPackageName()).isEqualTo(mContext.getPackageName());
    }

@@ -144,7 +150,7 @@ public class NotificationManagerZenTest {
    }

    @Test
    public void addAutomaticZenRule_invalidCps_rejected() {
    public void addAutomaticZenRule_invalidCpsAndNoConfigActivity_rejected() {
        AutomaticZenRule azr = new AutomaticZenRule.Builder("Invalid CPS", CONDITION_ID)
                .setOwner(new ComponentName(mContext, "android.app.NonExistentCps"))
                .build();
@@ -154,7 +160,24 @@ public class NotificationManagerZenTest {
    }

    @Test
    public void addAutomaticZenRule_invalidConfigActivity_rejected() {
    @RequiresFlagsEnabled(FLAG_STRICT_ZEN_RULE_COMPONENT_VALIDATION)
    public void addAutomaticZenRule_invalidCpsButValidConfigActivity_cpsRemoved() {
        AutomaticZenRule azr = new AutomaticZenRule.Builder("Invalid CPS", CONDITION_ID)
                .setOwner(new ComponentName(mContext, "android.app.NonExistentCps"))
                .setConfigurationActivity(CONFIGURATION_ACTIVITY)
                .build();

        String ruleId = mNotificationManager.addAutomaticZenRule(azr);

        AutomaticZenRule savedAzr = mNotificationManager.getAutomaticZenRule(ruleId);
        assertThat(savedAzr).isNotNull();
        assertThat(savedAzr.getOwner()).isNull();
        assertThat(savedAzr.getConfigurationActivity()).isEqualTo(CONFIGURATION_ACTIVITY);
        assertThat(savedAzr.getPackageName()).isEqualTo(mContext.getPackageName());
    }

    @Test
    public void addAutomaticZenRule_invalidConfigActivityAndNoCps_rejected() {
        AutomaticZenRule azr = new AutomaticZenRule.Builder("Invalid CPS", CONDITION_ID)
                .setConfigurationActivity(
                        new ComponentName(mContext, "android.app.NonExistentActivity"))
@@ -164,6 +187,24 @@ public class NotificationManagerZenTest {
                () -> mNotificationManager.addAutomaticZenRule(azr));
    }

    @Test
    @RequiresFlagsEnabled(FLAG_STRICT_ZEN_RULE_COMPONENT_VALIDATION)
    public void addAutomaticZenRule_invalidConfigActivityButValidCps_configActivityRemoved() {
        AutomaticZenRule azr = new AutomaticZenRule.Builder("Invalid CPS", CONDITION_ID)
                .setOwner(CONDITION_PROVIDER_SERVICE)
                .setConfigurationActivity(
                        new ComponentName(mContext, "android.app.NonExistentActivity"))
                .build();

        String ruleId = mNotificationManager.addAutomaticZenRule(azr);

        AutomaticZenRule savedAzr = mNotificationManager.getAutomaticZenRule(ruleId);
        assertThat(savedAzr).isNotNull();
        assertThat(savedAzr.getOwner()).isEqualTo(CONDITION_PROVIDER_SERVICE);
        assertThat(savedAzr.getConfigurationActivity()).isNull();
        assertThat(savedAzr.getPackageName()).isEqualTo(mContext.getPackageName());
    }

    @Test
    public void addAutomaticZenRule_cpsInDifferentPackage_rejected() {
        AutomaticZenRule azr = new AutomaticZenRule.Builder("System CPS !!", CONDITION_ID)
@@ -186,12 +227,10 @@ public class NotificationManagerZenTest {
    }

    @Test
    @RequiresFlagsEnabled(
            com.android.server.notification.Flags.FLAG_STRICT_ZEN_RULE_COMPONENT_VALIDATION)
    @RequiresFlagsEnabled(FLAG_STRICT_ZEN_RULE_COMPONENT_VALIDATION)
    public void updateAutomaticZenRule_switchToInvalidCps_rejected() {
        AutomaticZenRule original = new AutomaticZenRule.Builder("OK so far", CONDITION_ID)
                .setOwner(CONDITION_PROVIDER_SERVICE)
                .setConfigurationActivity(CONFIGURATION_ACTIVITY)
                .build();

        String ruleId = mNotificationManager.addAutomaticZenRule(original);
@@ -205,13 +244,31 @@ public class NotificationManagerZenTest {
    }

    @Test
    @RequiresFlagsEnabled(
            com.android.server.notification.Flags.FLAG_STRICT_ZEN_RULE_COMPONENT_VALIDATION)
    public void updateAutomaticZenRule_switchToInvalidConfigActivity_rejected() {
    @RequiresFlagsEnabled(FLAG_STRICT_ZEN_RULE_COMPONENT_VALIDATION)
    public void updateAutomaticZenRule_switchToInvalidCpsButWithValidConfigActivity_cpsGone() {
        AutomaticZenRule original = new AutomaticZenRule.Builder("OK so far", CONDITION_ID)
                .setOwner(CONDITION_PROVIDER_SERVICE)
                .setConfigurationActivity(CONFIGURATION_ACTIVITY)
                .build();
        String ruleId = mNotificationManager.addAutomaticZenRule(original);

        AutomaticZenRule sneaky = new AutomaticZenRule.Builder(original)
                .setOwner(ZenModeConfig.getScheduleConditionProvider())
                .build();
        mNotificationManager.updateAutomaticZenRule(ruleId, sneaky);

        AutomaticZenRule savedAzr = mNotificationManager.getAutomaticZenRule(ruleId);
        assertThat(savedAzr).isNotNull();
        assertThat(savedAzr.getOwner()).isNull();
        assertThat(savedAzr.getConfigurationActivity()).isEqualTo(CONFIGURATION_ACTIVITY);
    }

    @Test
    @RequiresFlagsEnabled(FLAG_STRICT_ZEN_RULE_COMPONENT_VALIDATION)
    public void updateAutomaticZenRule_switchToInvalidConfigActivity_rejected() {
        AutomaticZenRule original = new AutomaticZenRule.Builder("OK so far", CONDITION_ID)
                .setConfigurationActivity(CONFIGURATION_ACTIVITY)
                .build();

        String ruleId = mNotificationManager.addAutomaticZenRule(original);

@@ -224,6 +281,27 @@ public class NotificationManagerZenTest {
                () -> mNotificationManager.updateAutomaticZenRule(ruleId, sneaky));
    }

    @Test
    @RequiresFlagsEnabled(FLAG_STRICT_ZEN_RULE_COMPONENT_VALIDATION)
    public void updateAutomaticZenRule_switchToInvalidConfigActivityButWithValidCps_activityGone() {
        AutomaticZenRule original = new AutomaticZenRule.Builder("OK so far", CONDITION_ID)
                .setOwner(CONDITION_PROVIDER_SERVICE)
                .setConfigurationActivity(CONFIGURATION_ACTIVITY)
                .build();
        String ruleId = mNotificationManager.addAutomaticZenRule(original);

        AutomaticZenRule sneaky = new AutomaticZenRule.Builder(original)
                .setConfigurationActivity(
                        new ComponentName("com.android.settings", "Settings$ModesSettingsActivity"))
                .build();
        mNotificationManager.updateAutomaticZenRule(ruleId, sneaky);

        AutomaticZenRule savedAzr = mNotificationManager.getAutomaticZenRule(ruleId);
        assertThat(savedAzr).isNotNull();
        assertThat(savedAzr.getConfigurationActivity()).isNull();
        assertThat(savedAzr.getOwner()).isEqualTo(CONDITION_PROVIDER_SERVICE);
    }

    @Test
    public void addAutomaticZenRule_fromPackage_forcesOwnerPackage() {
        AutomaticZenRule azr = new AutomaticZenRule.Builder("Set wrong package", CONDITION_ID)