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

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

Make manually activated rules stay activated on reboot

For symmetry with the old behavior of snoozing, we were clearing activation state on reboot. However users apparently expect modes to stay on, so do that.

Manual deactivation is still not stored, and cleared on reboots.

Fixes: 367309333
Test: atest ZenModeHelperTest + manual
Flag: android.app.modes_ui
Change-Id: I40c92d49d5a5cae5fe4810a8a9f95de0d0035c3e
parent c7c82ca0
Loading
Loading
Loading
Loading
+17 −7
Original line number Diff line number Diff line
@@ -313,6 +313,7 @@ public class ZenModeConfig implements Parcelable {
    private static final String RULE_ATT_DELETION_INSTANT = "deletionInstant";
    private static final String RULE_ATT_DISABLED_ORIGIN = "disabledOrigin";
    private static final String RULE_ATT_LEGACY_SUPPRESSED_EFFECTS = "legacySuppressedEffects";
    private static final String RULE_ATT_CONDITION_OVERRIDE = "conditionOverride";

    private static final String DEVICE_EFFECT_DISPLAY_GRAYSCALE = "zdeDisplayGrayscale";
    private static final String DEVICE_EFFECT_SUPPRESS_AMBIENT_DISPLAY =
@@ -1144,7 +1145,7 @@ public class ZenModeConfig implements Parcelable {

        if (manualRule != null) {
            out.startTag(null, MANUAL_TAG);
            writeRuleXml(manualRule, out);
            writeRuleXml(manualRule, out, forBackup);
            out.endTag(null, MANUAL_TAG);
        }
        final int N = automaticRules.size();
@@ -1153,7 +1154,7 @@ public class ZenModeConfig implements Parcelable {
            final ZenRule automaticRule = automaticRules.valueAt(i);
            out.startTag(null, AUTOMATIC_TAG);
            out.attribute(null, RULE_ATT_ID, id);
            writeRuleXml(automaticRule, out);
            writeRuleXml(automaticRule, out, forBackup);
            out.endTag(null, AUTOMATIC_TAG);
        }
        if (Flags.modesApi() && !forBackup) {
@@ -1161,7 +1162,7 @@ public class ZenModeConfig implements Parcelable {
                final ZenRule deletedRule = deletedRules.valueAt(i);
                out.startTag(null, AUTOMATIC_DELETED_TAG);
                out.attribute(null, RULE_ATT_ID, deletedRule.id);
                writeRuleXml(deletedRule, out);
                writeRuleXml(deletedRule, out, forBackup);
                out.endTag(null, AUTOMATIC_DELETED_TAG);
            }
        }
@@ -1220,12 +1221,15 @@ public class ZenModeConfig implements Parcelable {
                        ORIGIN_UNKNOWN);
                rt.legacySuppressedEffects = safeInt(parser,
                        RULE_ATT_LEGACY_SUPPRESSED_EFFECTS, 0);
                rt.conditionOverride = safeInt(parser, RULE_ATT_CONDITION_OVERRIDE,
                        ZenRule.OVERRIDE_NONE);
            }
        }
        return rt;
    }

    public static void writeRuleXml(ZenRule rule, TypedXmlSerializer out) throws IOException {
    public static void writeRuleXml(ZenRule rule, TypedXmlSerializer out, boolean forBackup)
            throws IOException {
        out.attributeBoolean(null, RULE_ATT_ENABLED, rule.enabled);
        if (rule.name != null) {
            out.attribute(null, RULE_ATT_NAME, rule.name);
@@ -1279,6 +1283,9 @@ public class ZenModeConfig implements Parcelable {
                out.attributeInt(null, RULE_ATT_DISABLED_ORIGIN, rule.disabledOrigin);
                out.attributeInt(null, RULE_ATT_LEGACY_SUPPRESSED_EFFECTS,
                        rule.legacySuppressedEffects);
                if (rule.conditionOverride == ZenRule.OVERRIDE_ACTIVATE && !forBackup) {
                    out.attributeInt(null, RULE_ATT_CONDITION_OVERRIDE, rule.conditionOverride);
                }
            }
        }
    }
@@ -2622,9 +2629,12 @@ public class ZenModeConfig implements Parcelable {
        int legacySuppressedEffects;
        /**
         * Signals a user's action to (temporarily or permanently) activate or deactivate this
         * rule, overruling the condition set by the owner. This value is not stored to disk, as
         * it shouldn't survive reboots or be involved in B&R. It might be reset by certain
         * owner-provided state transitions as well.
         * rule, overruling the condition set by the owner.
         *
         * <p>An {@link #OVERRIDE_ACTIVATE} is stored to disk, since we want it to survive reboots
         * (but it's not included in B&R), while an {@link #OVERRIDE_DEACTIVATE} is not (meaning
         * that snoozed rules may reactivate on reboot). It might be reset by certain owner-provided
         * state transitions as well.
         */
        @FlaggedApi(Flags.FLAG_MODES_UI)
        @ConditionOverride
+1 −1
Original line number Diff line number Diff line
@@ -1274,7 +1274,7 @@ public class ZenModeConfigTest extends UiServiceTestCase {
        out.setOutput(new BufferedOutputStream(os), "utf-8");
        out.startDocument(null, true);
        out.startTag(null, tag);
        ZenModeConfig.writeRuleXml(rule, out);
        ZenModeConfig.writeRuleXml(rule, out, /* forBackup= */ false);
        out.endTag(null, tag);
        out.endDocument();
    }
+69 −0
Original line number Diff line number Diff line
@@ -6923,6 +6923,75 @@ public class ZenModeHelperTest extends UiServiceTestCase {
        assertThat(eventsRule.triggerDescription).isNotEmpty();
    }

    @Test
    @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
    public void setAutomaticZenRuleState_withManualActivation_activeOnReboot()
            throws Exception {
        AutomaticZenRule rule = new AutomaticZenRule.Builder("Rule", Uri.parse("cond"))
                .setPackage(mPkg)
                .build();
        String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, rule, ORIGIN_APP, "adding",
                CUSTOM_PKG_UID);
        mZenModeHelper.setAutomaticZenRuleState(ruleId,
                new Condition(rule.getConditionId(), "manual-on", STATE_TRUE, SOURCE_USER_ACTION),
                ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID);
        assertThat(mZenModeHelper.getAutomaticZenRuleState(ruleId)).isEqualTo(STATE_TRUE);
        ZenRule zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
        assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_ACTIVATE);
        assertThat(zenRule.condition).isNull();

        ByteArrayOutputStream xmlBytes = writeXmlAndPurge(ZenModeConfig.XML_VERSION_MODES_UI);
        zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
        assertThat(zenRule).isNull();

        // Now simulate a reboot -> reload the configuration after purging.
        TypedXmlPullParser parser = getParserForByteStream(xmlBytes);
        mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);

        if (Flags.modesUi()) {
            assertThat(mZenModeHelper.getAutomaticZenRuleState(ruleId)).isEqualTo(STATE_TRUE);
            zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
            assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_ACTIVATE);
            assertThat(zenRule.condition).isNull();
        } else {
            assertThat(mZenModeHelper.getAutomaticZenRuleState(ruleId)).isEqualTo(STATE_FALSE);
        }
    }

    @Test
    @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
    public void setAutomaticZenRuleState_withManualDeactivation_clearedOnReboot()
            throws Exception {
        AutomaticZenRule rule = new AutomaticZenRule.Builder("Rule", Uri.parse("cond"))
                .setPackage(mPkg)
                .build();
        String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, rule, ORIGIN_APP, "adding",
                CUSTOM_PKG_UID);
        mZenModeHelper.setAutomaticZenRuleState(ruleId,
                new Condition(rule.getConditionId(), "auto-on", STATE_TRUE, SOURCE_CONTEXT),
                ORIGIN_APP, CUSTOM_PKG_UID);
        mZenModeHelper.setAutomaticZenRuleState(ruleId,
                new Condition(rule.getConditionId(), "snooze", STATE_FALSE, SOURCE_USER_ACTION),
                ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID);
        assertThat(mZenModeHelper.getAutomaticZenRuleState(ruleId)).isEqualTo(STATE_FALSE);
        ZenRule zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
        assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_DEACTIVATE);
        assertThat(zenRule.condition).isNotNull();

        ByteArrayOutputStream xmlBytes = writeXmlAndPurge(ZenModeConfig.XML_VERSION_MODES_UI);
        zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
        assertThat(zenRule).isNull();

        // Now simulate a reboot -> reload the configuration after purging.
        TypedXmlPullParser parser = getParserForByteStream(xmlBytes);
        mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);

        assertThat(mZenModeHelper.getAutomaticZenRuleState(ruleId)).isEqualTo(STATE_TRUE);
        zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
        assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_NONE);
        assertThat(zenRule.condition).isNotNull();
    }

    private static void addZenRule(ZenModeConfig config, String id, String ownerPkg, int zenMode,
            @Nullable ZenPolicy zenPolicy) {
        ZenRule rule = new ZenRule();