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

Commit 4e2f76c3 authored by Beverly's avatar Beverly
Browse files

Auto zen rules reset for some upgrading users

Automatic zen rules will be set to the undeletable,
default rules for for fresh P devices and for upgrading users
who didn't have any zen automatic rules enabled on upgrade

Bug: 74381638
Test: atest ZenModeHelperTest
Change-Id: Icfa7dfe6c99cb9d67821df0034d5e9a3457b2ef4
parent f8cb545a
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -97,7 +97,7 @@ public class ZenModeConfig implements Parcelable {
    private static final int DEFAULT_SUPPRESSED_VISUAL_EFFECTS =
            Policy.getAllSuppressedVisualEffects();

    public static final int XML_VERSION = 5;
    public static final int XML_VERSION = 6;
    public static final String ZEN_TAG = "zen";
    private static final String ZEN_ATT_VERSION = "version";
    private static final String ZEN_ATT_USER = "user";
@@ -516,11 +516,17 @@ public class ZenModeConfig implements Parcelable {
        throw new IllegalStateException("Failed to reach END_DOCUMENT");
    }

    public void writeXml(XmlSerializer out) throws IOException {
    /**
     * Writes XML of current ZenModeConfig
     * @param out serializer
     * @param version uses XML_VERSION if version is null
     * @throws IOException
     */
    public void writeXml(XmlSerializer out, Integer version) throws IOException {
        out.startTag(null, ZEN_TAG);
        out.attribute(null, ZEN_ATT_VERSION, Integer.toString(XML_VERSION));
        out.attribute(null, ZEN_ATT_VERSION, version == null
                ? Integer.toString(XML_VERSION) : Integer.toString(version));
        out.attribute(null, ZEN_ATT_USER, Integer.toString(user));

        out.startTag(null, ALLOW_TAG);
        out.attribute(null, ALLOW_ATT_CALLS, Boolean.toString(allowCalls));
        out.attribute(null, ALLOW_ATT_REPEAT_CALLERS, Boolean.toString(allowRepeatCallers));
+1 −1
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@
-->

<!-- Default configuration for zen mode.  See android.service.notification.ZenModeConfig. -->
<zen version="5">
<zen version="6">
    <allow alarms="true" media="true" system="false" calls="false" messages="false" reminders="false"
           events="false" />
    <!-- all visual effects that exist as of P -->
+1 −1
Original line number Diff line number Diff line
@@ -593,7 +593,7 @@ public class NotificationManagerService extends SystemService {
        out.startDocument(null, true);
        out.startTag(null, TAG_NOTIFICATION_POLICY);
        out.attribute(null, ATTR_VERSION, Integer.toString(DB_VERSION));
        mZenModeHelper.writeXml(out, forBackup);
        mZenModeHelper.writeXml(out, forBackup, null);
        mRankingHelper.writeXml(out, forBackup);
        mListeners.writeXml(out, forBackup);
        mAssistants.writeXml(out, forBackup);
+29 −25
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ import android.service.notification.ZenModeConfig.ScheduleInfo;
import android.service.notification.ZenModeConfig.ZenRule;
import android.service.notification.ZenModeProto;
import android.util.AndroidRuntimeException;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
@@ -234,25 +235,12 @@ public class ZenModeHelper {
            config = mDefaultConfig.copy();
            config.user = user;
        }
        enforceDefaultRulesExist(config);
        synchronized (mConfig) {
            setConfigLocked(config, reason);
        }
        cleanUpZenRules();
    }

    private void enforceDefaultRulesExist(ZenModeConfig config) {
        for (String id : ZenModeConfig.DEFAULT_RULE_IDS) {
            if (!config.automaticRules.containsKey(id)) {
                if (id.equals(ZenModeConfig.EVENTS_DEFAULT_RULE_ID)) {
                    appendDefaultEventRules(config);
                } else if (id.equals(ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID)) {
                    appendDefaultEveryNightRule(config);
                }
            }
        }
    }

    public int getZenModeListenerInterruptionFilter() {
        return NotificationManager.zenModeToInterruptionFilter(mZenMode);
    }
@@ -623,43 +611,59 @@ public class ZenModeHelper {

    public void readXml(XmlPullParser parser, boolean forRestore)
            throws XmlPullParserException, IOException {
        final ZenModeConfig config = ZenModeConfig.readXml(parser);
        ZenModeConfig config = ZenModeConfig.readXml(parser);
        String reason = "readXml";

        if (config != null) {
            if (config.version < ZenModeConfig.XML_VERSION || forRestore) {
                Settings.Global.putInt(mContext.getContentResolver(),
                        Global.SHOW_ZEN_UPGRADE_NOTIFICATION, 1);
            }
            if (forRestore) {
                //TODO: http://b/22388012
                if (config.user != UserHandle.USER_SYSTEM) {
                    return;
                }
                config.manualRule = null;  // don't restore the manual rule
            }

            boolean resetToDefaultRules = true;
            long time = System.currentTimeMillis();
                if (config.automaticRules != null) {
            if (config.automaticRules != null && config.automaticRules.size() > 0) {
                for (ZenRule automaticRule : config.automaticRules.values()) {
                    if (forRestore) {
                        // don't restore transient state from restored automatic rules
                        automaticRule.snoozing = false;
                        automaticRule.condition = null;
                        automaticRule.creationTime = time;
                    }
                    resetToDefaultRules &= !automaticRule.enabled;
                }
            }

            if (config.version < ZenModeConfig.XML_VERSION || forRestore) {
                Settings.Global.putInt(mContext.getContentResolver(),
                        Global.SHOW_ZEN_UPGRADE_NOTIFICATION, 1);

                // resets zen automatic rules to default
                // if all prev auto rules were disabled on update
                if (resetToDefaultRules) {
                    config.automaticRules = new ArrayMap<>();
                    appendDefaultRules(config);
                    reason += ", reset to default rules";
                }
            }
            if (DEBUG) Log.d(TAG, "readXml");
            if (DEBUG) Log.d(TAG, reason);
            synchronized (mConfig) {
                setConfigLocked(config, "readXml");
                setConfigLocked(config, reason);
            }
        }
    }

    public void writeXml(XmlSerializer out, boolean forBackup) throws IOException {
    public void writeXml(XmlSerializer out, boolean forBackup, Integer version) throws IOException {
        final int N = mConfigs.size();
        for (int i = 0; i < N; i++) {
            //TODO: http://b/22388012
            if (forBackup && mConfigs.keyAt(i) != UserHandle.USER_SYSTEM) {
                continue;
            }
            mConfigs.valueAt(i).writeXml(out);
            mConfigs.valueAt(i).writeXml(out, version);
        }
    }

+131 −3
Original line number Diff line number Diff line
@@ -49,9 +49,11 @@ import android.media.AudioSystem;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeConfig.ScheduleInfo;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.ArrayMap;
import android.util.Xml;

import com.android.internal.R;
@@ -102,13 +104,13 @@ public class ZenModeHelperTest extends UiServiceTestCase {
                mConditionProviders));
    }

    private ByteArrayOutputStream writeXmlAndPurge(boolean forBackup)
    private ByteArrayOutputStream writeXmlAndPurge(boolean forBackup, Integer version)
            throws Exception {
        XmlSerializer serializer = new FastXmlSerializer();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
        serializer.startDocument(null, true);
        mZenModeHelperSpy.writeXml(serializer, forBackup);
        mZenModeHelperSpy.writeXml(serializer, forBackup, version);
        serializer.endDocument();
        serializer.flush();
        mZenModeHelperSpy.setConfig(new ZenModeConfig(), "writing xml");
@@ -603,7 +605,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {

        ZenModeConfig expected = mZenModeHelperSpy.mConfig.copy();

        ByteArrayOutputStream baos = writeXmlAndPurge(false);
        ByteArrayOutputStream baos = writeXmlAndPurge(false, null);
        XmlPullParser parser = Xml.newPullParser();
        parser.setInput(new BufferedInputStream(
                new ByteArrayInputStream(baos.toByteArray())), null);
@@ -613,6 +615,96 @@ public class ZenModeHelperTest extends UiServiceTestCase {
        assertEquals(expected, mZenModeHelperSpy.mConfig);
    }

    @Test
    public void testReadXml() throws Exception {
        setupZenConfig();

        // automatic zen rule is enabled on upgrade so rules should not be overriden by default
        ArrayMap<String, ZenModeConfig.ZenRule> enabledAutoRule = new ArrayMap<>();
        ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
        final ScheduleInfo weeknights = new ScheduleInfo();
        customRule.enabled = true;
        customRule.name = "Custom Rule";
        customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
        customRule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights);
        enabledAutoRule.put("customRule", customRule);
        mZenModeHelperSpy.mConfig.automaticRules = enabledAutoRule;

        ZenModeConfig expected = mZenModeHelperSpy.mConfig.copy();

        // set previous version
        ByteArrayOutputStream baos = writeXmlAndPurge(false, 5);
        XmlPullParser parser = Xml.newPullParser();
        parser.setInput(new BufferedInputStream(
                new ByteArrayInputStream(baos.toByteArray())), null);
        parser.nextTag();
        mZenModeHelperSpy.readXml(parser, false);

        assertTrue(mZenModeHelperSpy.mConfig.automaticRules.containsKey("customRule"));
        setupZenConfigMaintained();
    }

    @Test
    public void testReadXmlResetDefaultRules() throws Exception {
        setupZenConfig();

        // no enabled automatic zen rule, so rules should be overriden by default rules
        mZenModeHelperSpy.mConfig.automaticRules = new ArrayMap<>();

        // set previous version
        ByteArrayOutputStream baos = writeXmlAndPurge(false, 5);
        XmlPullParser parser = Xml.newPullParser();
        parser.setInput(new BufferedInputStream(
                new ByteArrayInputStream(baos.toByteArray())), null);
        parser.nextTag();
        mZenModeHelperSpy.readXml(parser, false);

        // check default rules
        ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelperSpy.mConfig.automaticRules;
        assertTrue(rules.size() != 0);
        for (String defaultId : ZenModeConfig.DEFAULT_RULE_IDS) {
            assertTrue(rules.containsKey(defaultId));
        }

        setupZenConfigMaintained();
    }


    @Test
    public void testReadXmlAllDisabledRulesResetDefaultRules() throws Exception {
        setupZenConfig();

        // all automatic zen rules are diabled on upgrade so rules should be overriden by default
        // rules
        ArrayMap<String, ZenModeConfig.ZenRule> enabledAutoRule = new ArrayMap<>();
        ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
        final ScheduleInfo weeknights = new ScheduleInfo();
        customRule.enabled = false;
        customRule.name = "Custom Rule";
        customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
        customRule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights);
        enabledAutoRule.put("customRule", customRule);
        mZenModeHelperSpy.mConfig.automaticRules = enabledAutoRule;

        // set previous version
        ByteArrayOutputStream baos = writeXmlAndPurge(false, 5);
        XmlPullParser parser = Xml.newPullParser();
        parser.setInput(new BufferedInputStream(
                new ByteArrayInputStream(baos.toByteArray())), null);
        parser.nextTag();
        mZenModeHelperSpy.readXml(parser, false);

        // check default rules
        ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelperSpy.mConfig.automaticRules;
        assertTrue(rules.size() != 0);
        for (String defaultId : ZenModeConfig.DEFAULT_RULE_IDS) {
            assertTrue(rules.containsKey(defaultId));
        }
        assertFalse(rules.containsKey("customRule"));

        setupZenConfigMaintained();
    }

    @Test
    public void testPolicyReadsSuppressedEffects() {
        mZenModeHelperSpy.mConfig.allowWhenScreenOff = true;
@@ -622,4 +714,40 @@ public class ZenModeHelperTest extends UiServiceTestCase {
        NotificationManager.Policy policy = mZenModeHelperSpy.getNotificationPolicy();
        assertEquals(SUPPRESSED_EFFECT_BADGE, policy.suppressedVisualEffects);
    }

    private void setupZenConfig() {
        mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
        mZenModeHelperSpy.mConfig.allowAlarms = false;
        mZenModeHelperSpy.mConfig.allowMedia = false;
        mZenModeHelperSpy.mConfig.allowSystem = false;
        mZenModeHelperSpy.mConfig.allowReminders = true;
        mZenModeHelperSpy.mConfig.allowCalls = true;
        mZenModeHelperSpy.mConfig.allowMessages = true;
        mZenModeHelperSpy.mConfig.allowEvents = true;
        mZenModeHelperSpy.mConfig.allowRepeatCallers= true;
        mZenModeHelperSpy.mConfig.allowWhenScreenOff = true;
        mZenModeHelperSpy.mConfig.allowWhenScreenOn = true;
        mZenModeHelperSpy.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
        mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule();
        mZenModeHelperSpy.mConfig.manualRule.zenMode =
                Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
        mZenModeHelperSpy.mConfig.manualRule.component = new ComponentName("a", "a");
        mZenModeHelperSpy.mConfig.manualRule.enabled = true;
        mZenModeHelperSpy.mConfig.manualRule.snoozing = true;
    }

    private void setupZenConfigMaintained() {
        // config is still the same as when it was setup (setupZenConfig)
        assertFalse(mZenModeHelperSpy.mConfig.allowAlarms);
        assertFalse(mZenModeHelperSpy.mConfig.allowMedia);
        assertFalse(mZenModeHelperSpy.mConfig.allowSystem);
        assertTrue(mZenModeHelperSpy.mConfig.allowReminders);
        assertTrue(mZenModeHelperSpy.mConfig.allowCalls);
        assertTrue(mZenModeHelperSpy.mConfig.allowMessages);
        assertTrue(mZenModeHelperSpy.mConfig.allowEvents);
        assertTrue(mZenModeHelperSpy.mConfig.allowRepeatCallers);
        assertTrue(mZenModeHelperSpy.mConfig.allowWhenScreenOff);
        assertTrue(mZenModeHelperSpy.mConfig.allowWhenScreenOn);
        assertEquals(SUPPRESSED_EFFECT_BADGE, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
    }
}