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

Commit 077d1907 authored by Matías Hernández's avatar Matías Hernández Committed by Yuri Lin
Browse files

Emulate Zen rule policy inheritance until edit UI is available

Before MODES_API, rules without a policy (or with a partially specified policy) would inherit the manual DND policy settings when calculating the consolidated policy. This change temporarily restores part of this behavior, because users have come to expect it (even though it's not applied consistently). In order to do so, whenever the manual policy is modified, we update the policies of rules that match either the default or previous manual policy.

This becomes obsolete with MODES_UI since the user can then view and edit those policies, and it will be clear that the NotificationPolicy only applies to manual DND (and this is also the reason that don't apply the new manual policy to rules that have their own policy pages today).

Flag: android.app.modes_api
Fixes: 337193321
Test: atest ZenModeHelperTest NotificationManagerZenTest
Change-Id: I2217b1f251608a1eea54072720b50b08eb3b4d39
parent 41f15711
Loading
Loading
Loading
Loading
+22 −1
Original line number Diff line number Diff line
@@ -1725,7 +1725,28 @@ public class ZenModeHelper {
        synchronized (mConfigLock) {
            if (policy == null || mConfig == null) return;
            final ZenModeConfig newConfig = mConfig.copy();
            if (Flags.modesApi() && !Flags.modesUi()) {
                // Fix for b/337193321 -- propagate changes to notificationPolicy to rules where
                // the user cannot edit zen policy to emulate the previous "inheritance".
                ZenPolicy previousPolicy = ZenAdapters.notificationPolicyToZenPolicy(
                        newConfig.toNotificationPolicy());
                ZenPolicy newPolicy = ZenAdapters.notificationPolicyToZenPolicy(policy);

                newConfig.applyNotificationPolicy(policy);

                if (!previousPolicy.equals(newPolicy)) {
                    for (ZenRule rule : newConfig.automaticRules.values()) {
                        if (!SystemZenRules.isSystemOwnedRule(rule)
                                && rule.zenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
                                && (rule.zenPolicy == null || rule.zenPolicy.equals(previousPolicy)
                                        || rule.zenPolicy.equals(getDefaultZenPolicy()))) {
                            rule.zenPolicy = newPolicy;
                        }
                    }
                }
            } else {
                newConfig.applyNotificationPolicy(policy);
            }
            setConfigLocked(newConfig, null, origin, "setNotificationPolicy", callingUid);
        }
    }
+61 −0
Original line number Diff line number Diff line
@@ -6095,6 +6095,67 @@ public class ZenModeHelperTest extends UiServiceTestCase {
        assertThat(readPolicy.allowConversations()).isFalse();
    }

    @Test
    @EnableFlags(Flags.FLAG_MODES_API)
    @DisableFlags(Flags.FLAG_MODES_UI)
    public void setNotificationPolicy_updatesRulePolicies_ifRulePolicyIsDefaultOrGlobalPolicy() {
        ZenPolicy defaultZenPolicy = mZenModeHelper.getDefaultZenPolicy();
        Policy previousManualPolicy = mZenModeHelper.mConfig.toNotificationPolicy();
        ZenPolicy previousManualZenPolicy = ZenAdapters.notificationPolicyToZenPolicy(
                previousManualPolicy);
        ZenPolicy customZenPolicy = new ZenPolicy.Builder(defaultZenPolicy).allowConversations(
                CONVERSATION_SENDERS_ANYONE).build();

        mZenModeHelper.mConfig.automaticRules.clear();
        addZenRule(mZenModeHelper.mConfig, "appWithDefault", "app.pkg",
                ZEN_MODE_IMPORTANT_INTERRUPTIONS, defaultZenPolicy);
        addZenRule(mZenModeHelper.mConfig, "appWithSameAsManual", "app.pkg",
                ZEN_MODE_IMPORTANT_INTERRUPTIONS, previousManualZenPolicy);
        addZenRule(mZenModeHelper.mConfig, "appWithCustom", "app.pkg",
                ZEN_MODE_IMPORTANT_INTERRUPTIONS, customZenPolicy);
        addZenRule(mZenModeHelper.mConfig, "appWithOtherFilter", "app.pkg",
                ZEN_MODE_ALARMS, null);
        addZenRule(mZenModeHelper.mConfig, "systemWithDefault", "android",
                ZEN_MODE_IMPORTANT_INTERRUPTIONS, defaultZenPolicy);
        addZenRule(mZenModeHelper.mConfig, "systemWithSameAsManual", "android",
                ZEN_MODE_IMPORTANT_INTERRUPTIONS, previousManualZenPolicy);

        Policy newManualPolicy = new Policy(PRIORITY_CATEGORY_EVENTS, 0, 0);
        mZenModeHelper.setNotificationPolicy(newManualPolicy, UPDATE_ORIGIN_USER, 0);
        ZenPolicy newManualZenPolicy = ZenAdapters.notificationPolicyToZenPolicy(newManualPolicy);

        // Only app rules with default or same-as-manual policies were updated.
        assertThat(mZenModeHelper.mConfig.automaticRules.get("appWithDefault").zenPolicy)
                .isEqualTo(newManualZenPolicy);
        assertThat(mZenModeHelper.mConfig.automaticRules.get("appWithSameAsManual").zenPolicy)
                .isEqualTo(newManualZenPolicy);

        assertThat(mZenModeHelper.mConfig.automaticRules.get("appWithCustom").zenPolicy)
                .isEqualTo(customZenPolicy);
        assertThat(mZenModeHelper.mConfig.automaticRules.get("appWithOtherFilter").zenPolicy)
                .isNull();
        assertThat(mZenModeHelper.mConfig.automaticRules.get("systemWithDefault").zenPolicy)
                .isEqualTo(defaultZenPolicy);
        assertThat(mZenModeHelper.mConfig.automaticRules.get("systemWithSameAsManual").zenPolicy)
                .isEqualTo(previousManualZenPolicy);
    }

    private static void addZenRule(ZenModeConfig config, String id, String ownerPkg, int zenMode,
            @Nullable ZenPolicy zenPolicy) {
        ZenRule rule = new ZenRule();
        rule.id = id;
        rule.pkg = ownerPkg;
        rule.enabled = true;
        rule.zenMode = zenMode;
        rule.zenPolicy = zenPolicy;
        // Plus stuff so that isValidAutomaticRule() passes
        rule.name = String.format("Rule %s from %s with mode=%s and policy=%s", id, ownerPkg,
                zenMode, zenPolicy);
        rule.conditionId = Uri.parse(rule.name);

        config.automaticRules.put(id, rule);
    }

    private static final Correspondence<ZenRule, ZenRule> IGNORE_METADATA =
            Correspondence.transforming(zr -> {
                Parcel p = Parcel.obtain();