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
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 740a387..3830b7a 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -97,7 +97,7 @@
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 @@
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 2d3cd1c..f1b61a7 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 b911c7b..1db373d 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 @@
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 e862530..5c82343 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.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 @@
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 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 (DEBUG) Log.d(TAG, "readXml");
+
+ 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, 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 be58fd2..381e04c 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.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 @@
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 @@
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 @@
}
@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 @@
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);
+ }
}