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

Commit d2b75eb7 authored by Matías Hernández's avatar Matías Hernández
Browse files

Allow apps to recreate rules if changing the owner component

This is not permitted for rule updates, so allow delete+add in that case (even though it loses previous user customization).

Fixes: 361568883
Test: atest ZenModeHelperTest
Flag: android.app.modes_ui
Change-Id: I886820ab3b70c6640530e4bec6430cb33e84d6c0
parent 28b2ac4c
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -485,7 +485,7 @@ public class ZenModeHelper {
            newConfig = mConfig.copy();
            ZenRule rule = new ZenRule();
            populateZenRule(pkg, automaticZenRule, rule, origin, /* isNew= */ true);
            rule = maybeRestoreRemovedRule(newConfig, rule, automaticZenRule, origin);
            rule = maybeRestoreRemovedRule(newConfig, pkg, rule, automaticZenRule, origin);
            newConfig.automaticRules.put(rule.id, rule);
            maybeReplaceDefaultRule(newConfig, automaticZenRule);

@@ -498,7 +498,7 @@ public class ZenModeHelper {
    }

    @GuardedBy("mConfigLock")
    private ZenRule maybeRestoreRemovedRule(ZenModeConfig config, ZenRule ruleToAdd,
    private ZenRule maybeRestoreRemovedRule(ZenModeConfig config, String pkg, ZenRule ruleToAdd,
            AutomaticZenRule azrToAdd, @ConfigOrigin int origin) {
        if (!Flags.modesApi()) {
            return ruleToAdd;
@@ -522,10 +522,18 @@ public class ZenModeHelper {
        if (origin != ORIGIN_APP) {
            return ruleToAdd; // Okay to create anew.
        }
        if (Flags.modesUi()) {
            if (!Objects.equals(ruleToRestore.pkg, pkg)
                    || !Objects.equals(ruleToRestore.component, azrToAdd.getOwner())) {
                // Apps are not allowed to change the owner via updateAutomaticZenRule(). Thus, if
                // they have to, delete+add is their only option.
                return ruleToAdd;
            }
        }

        // "Preserve" the previous rule by considering the azrToAdd an update instead.
        // Only app-modifiable fields will actually be modified.
        populateZenRule(ruleToRestore.pkg, azrToAdd, ruleToRestore, origin, /* isNew= */ false);
        populateZenRule(pkg, azrToAdd, ruleToRestore, origin, /* isNew= */ false);
        return ruleToRestore;
    }

+43 −0
Original line number Diff line number Diff line
@@ -5537,6 +5537,49 @@ public class ZenModeHelperTest extends UiServiceTestCase {
        assertThat(newRuleId).isNotEqualTo(ruleId);
    }

    @Test
    @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
    public void removeAndAddAutomaticZenRule_ifChangingComponent_isAllowedAndDoesNotRestore() {
        // Start with a rule.
        mZenModeHelper.mConfig.automaticRules.clear();
        AutomaticZenRule rule = new AutomaticZenRule.Builder("Test", CONDITION_ID)
                .setOwner(new ComponentName("first", "owner"))
                .setInterruptionFilter(INTERRUPTION_FILTER_ALL)
                .build();
        String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), rule,
                ORIGIN_APP, "add it", CUSTOM_PKG_UID);

        // User customizes it.
        AutomaticZenRule userUpdate = new AutomaticZenRule.Builder(rule)
                .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
                .build();
        mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdate, ORIGIN_USER_IN_SYSTEMUI,
                "userUpdate", SYSTEM_UID);

        // App deletes it. It's preserved for a possible restoration.
        mZenModeHelper.removeAutomaticZenRule(ruleId, ORIGIN_APP, "delete it",
                CUSTOM_PKG_UID);
        assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(0);
        assertThat(mZenModeHelper.mConfig.deletedRules).hasSize(1);

        // App adds it again, but this time with a different owner!
        AutomaticZenRule readdingWithDifferentOwner = new AutomaticZenRule.Builder(rule)
                .setOwner(new ComponentName("second", "owner"))
                .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS)
                .build();
        String newRuleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(),
                readdingWithDifferentOwner, ORIGIN_APP, "add it again", CUSTOM_PKG_UID);

        // Verify that the rule was NOT restored:
        assertThat(newRuleId).isNotEqualTo(ruleId);
        AutomaticZenRule finalRule = mZenModeHelper.getAutomaticZenRule(newRuleId);
        assertThat(finalRule.getInterruptionFilter()).isEqualTo(INTERRUPTION_FILTER_ALARMS);
        assertThat(finalRule.getOwner()).isEqualTo(new ComponentName("second", "owner"));

        // Also, we discarded the "deleted rule" since we found it but decided not to use it.
        assertThat(mZenModeHelper.mConfig.deletedRules).hasSize(0);
    }

    @Test
    @EnableFlags(FLAG_MODES_API)
    public void removeAutomaticZenRule_preservedForRestoringByPackageAndConditionId() {