diff options
5 files changed, 172 insertions, 34 deletions
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index 740a387e078d..3830b7ac1aee 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -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)); diff --git a/core/res/res/xml/default_zen_mode_config.xml b/core/res/res/xml/default_zen_mode_config.xml index 2d3cd1cd5d29..f1b61a7edbd6 100644 --- a/core/res/res/xml/default_zen_mode_config.xml +++ b/core/res/res/xml/default_zen_mode_config.xml @@ -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 --> diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index b911c7b85d23..1db373d42b0e 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -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); diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index e86253037b08..5c823433afaf 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -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 - long time = System.currentTimeMillis(); - if (config.automaticRules != null) { - for (ZenRule automaticRule : config.automaticRules.values()) { + } + + boolean resetToDefaultRules = true; + long time = System.currentTimeMillis(); + 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); } } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java index be58fd2c66dd..381e04c188b1 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java @@ -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); @@ -614,6 +616,96 @@ public class ZenModeHelperTest extends UiServiceTestCase { } @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; mZenModeHelperSpy.mConfig.allowWhenScreenOn = 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); + } } |