Loading core/java/android/service/notification/ZenModeConfig.java +31 −10 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF; import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; import static android.service.notification.Condition.STATE_TRUE; import static android.service.notification.SystemZenRules.PACKAGE_ANDROID; import static android.service.notification.ZenAdapters.peopleTypeToPrioritySenders; import static android.service.notification.ZenAdapters.prioritySendersToPeopleType; import static android.service.notification.ZenAdapters.zenPolicyConversationSendersToNotificationPolicy; Loading Loading @@ -454,7 +456,7 @@ public class ZenModeConfig implements Parcelable { newRule.conditionId = Uri.EMPTY; newRule.allowManualInvocation = true; newRule.zenPolicy = getDefaultZenPolicy(); newRule.pkg = "android"; newRule.pkg = PACKAGE_ANDROID; manualRule = newRule; } } Loading Loading @@ -957,15 +959,9 @@ public class ZenModeConfig implements Parcelable { rt.user = safeInt(parser, ZEN_ATT_USER, rt.user); boolean readSuppressedEffects = false; boolean readManualRule = false; boolean readManualRuleWithoutPolicy = false; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { tag = parser.getName(); if (type == XmlPullParser.END_TAG && ZEN_TAG.equals(tag)) { if (Flags.modesUi() && !readManualRule) { // migrate from fields on config into manual rule rt.manualRule.zenPolicy = rt.toZenPolicy(); } return rt; } if (type == XmlPullParser.START_TAG) { if (ALLOW_TAG.equals(tag)) { rt.allowCalls = safeBoolean(parser, ALLOW_ATT_CALLS, Loading Loading @@ -1034,9 +1030,17 @@ public class ZenModeConfig implements Parcelable { rt.suppressedVisualEffects = safeInt(parser, DISALLOW_ATT_VISUAL_EFFECTS, DEFAULT_SUPPRESSED_VISUAL_EFFECTS); } else if (MANUAL_TAG.equals(tag)) { rt.manualRule = readRuleXml(parser); if (rt.manualRule != null) { ZenRule manualRule = readRuleXml(parser); if (manualRule != null) { rt.manualRule = manualRule; // Manual rule may be present prior to modes_ui if it were on, but in that // case it would not have a set policy, so make note of the need to set // it up later. readManualRule = true; if (rt.manualRule.zenPolicy == null) { readManualRuleWithoutPolicy = true; } } } else if (AUTOMATIC_TAG.equals(tag) || (Flags.modesApi() && AUTOMATIC_DELETED_TAG.equals(tag))) { Loading @@ -1058,6 +1062,23 @@ public class ZenModeConfig implements Parcelable { STATE_ATT_CHANNELS_BYPASSING_DND, DEFAULT_CHANNELS_BYPASSING_DND); } } if (type == XmlPullParser.END_TAG && ZEN_TAG.equals(tag)) { if (Flags.modesUi() && (!readManualRule || readManualRuleWithoutPolicy)) { // migrate from fields on config into manual rule rt.manualRule.zenPolicy = rt.toZenPolicy(); if (readManualRuleWithoutPolicy) { // indicates that the xml represents a pre-modes_ui XML with an enabled // manual rule; set rule active, and fill in other fields as would be done // in ensureManualZenRule() and setManualZenMode(). rt.manualRule.pkg = PACKAGE_ANDROID; rt.manualRule.type = AutomaticZenRule.TYPE_OTHER; rt.manualRule.condition = new Condition( rt.manualRule.conditionId != null ? rt.manualRule.conditionId : Uri.EMPTY, "", STATE_TRUE); } } return rt; } } throw new IllegalStateException("Failed to reach END_DOCUMENT"); } Loading services/core/java/com/android/server/notification/ZenModeHelper.java +5 −1 Original line number Diff line number Diff line Loading @@ -1676,7 +1676,11 @@ public class ZenModeHelper { if (config != null) { if (forRestore) { config.user = userId; if (!Flags.modesUi()) { if (Flags.modesUi()) { if (config.manualRule != null) { config.manualRule.condition = null; // don't restore transient state } } else { config.manualRule = null; // don't restore the manual rule } } Loading services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java +77 −2 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ import static android.service.notification.Condition.SOURCE_USER_ACTION; import static android.service.notification.Condition.STATE_FALSE; import static android.service.notification.Condition.STATE_TRUE; import static android.service.notification.NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_ON; import static android.service.notification.ZenModeConfig.XML_VERSION_MODES_API; import static android.service.notification.ZenModeConfig.ZEN_TAG; import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_IMPORTANT; import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_NONE; import static android.service.notification.ZenPolicy.PEOPLE_TYPE_ANYONE; Loading Loading @@ -990,6 +992,58 @@ public class ZenModeConfigTest extends UiServiceTestCase { assertThat(fromXml.zenPolicy).isEqualTo(config.getZenPolicy()); } @Test @EnableFlags(Flags.FLAG_MODES_UI) public void testConfigXml_manualRule_upgradeWhenExisting() throws Exception { // prior to modes_ui, it's possible to have a non-null manual rule that doesn't have much // data on it because it's meant to indicate that the manual rule is on by merely existing. ZenModeConfig config = new ZenModeConfig(); config.manualRule = new ZenModeConfig.ZenRule(); config.manualRule.enabled = true; config.manualRule.pkg = "android"; config.manualRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; config.manualRule.conditionId = ZenModeConfig.toTimeCondition(mContext, 200, mUserId).id; config.manualRule.enabler = "test"; // write out entire config xml ByteArrayOutputStream baos = new ByteArrayOutputStream(); writeConfigXml(config, XML_VERSION_MODES_API, /* forBackup= */ false, baos); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ZenModeConfig fromXml = readConfigXml(bais); // The result should have a manual rule; it should have a non-null ZenPolicy and a condition // whose state is true. The conditionId and enabler data should also be preserved. assertThat(fromXml.manualRule).isNotNull(); assertThat(fromXml.manualRule.zenPolicy).isNotNull(); assertThat(fromXml.manualRule.condition).isNotNull(); assertThat(fromXml.manualRule.condition.state).isEqualTo(STATE_TRUE); assertThat(fromXml.manualRule.conditionId).isEqualTo(config.manualRule.conditionId); assertThat(fromXml.manualRule.enabler).isEqualTo("test"); assertThat(fromXml.isManualActive()).isTrue(); } @Test @EnableFlags(Flags.FLAG_MODES_UI) public void testConfigXml_manualRule_doesNotTurnOnIfNotUpgrade() throws Exception { // confirm that if the manual rule is already properly set up for modes_ui, it does not get // turned on (set to condition with STATE_TRUE) when reading xml. // getMutedAllConfig sets up the manual rule with a policy muting everything ZenModeConfig config = getMutedAllConfig(); config.manualRule.condition = new Condition(Uri.EMPTY, "", STATE_FALSE, SOURCE_USER_ACTION); assertThat(config.isManualActive()).isFalse(); // write out entire config xml ByteArrayOutputStream baos = new ByteArrayOutputStream(); writeConfigXml(config, XML_VERSION_MODES_API, /* forBackup= */ false, baos); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ZenModeConfig fromXml = readConfigXml(bais); // The result should have a manual rule; it should not be changed from the previous rule. assertThat(fromXml.manualRule).isEqualTo(config.manualRule); assertThat(fromXml.isManualActive()).isFalse(); } @Test public void testGetDescription_off() { ZenModeConfig config = new ZenModeConfig(); Loading Loading @@ -1238,4 +1292,25 @@ public class ZenModeConfigTest extends UiServiceTestCase { parser.nextTag(); return ZenModeConfig.readZenPolicyXml(parser); } private void writeConfigXml(ZenModeConfig config, Integer version, boolean forBackup, ByteArrayOutputStream os) throws IOException { String tag = ZEN_TAG; TypedXmlSerializer out = Xml.newFastSerializer(); out.setOutput(new BufferedOutputStream(os), "utf-8"); out.startDocument(null, true); out.startTag(null, tag); config.writeXml(out, version, forBackup); out.endTag(null, tag); out.endDocument(); } private ZenModeConfig readConfigXml(ByteArrayInputStream is) throws XmlPullParserException, IOException { TypedXmlPullParser parser = Xml.newFastPullParser(); parser.setInput(new BufferedInputStream(is), null); parser.nextTag(); return ZenModeConfig.readXml(parser); } } services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +24 −0 Original line number Diff line number Diff line Loading @@ -1494,6 +1494,30 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertNotEquals(expected, mZenModeHelper.mConfig); } @Test public void testReadXmlRestore_doesNotEnableManualRule() throws Exception { setupZenConfig(); // Turn on manual zen mode mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, ORIGIN_USER_IN_SYSTEMUI, "", "someCaller", SYSTEM_UID); ZenModeConfig original = mZenModeHelper.mConfig.copy(); assertThat(original.isManualActive()).isTrue(); ByteArrayOutputStream baos = writeXmlAndPurge(null); TypedXmlPullParser parser = getParserForByteStream(baos); mZenModeHelper.readXml(parser, true, UserHandle.USER_ALL); ZenModeConfig result = mZenModeHelper.getConfig(); assertThat(result.isManualActive()).isFalse(); // confirm that we do still keep policy information, modes_ui only; prior to modes_ui the // entire rule is intentionally cleared if (Flags.modesUi()) { assertThat(result.manualRule.zenPolicy).isNotNull(); } } @Test public void testWriteXmlWithZenPolicy() throws Exception { final String ruleId = "customRule"; Loading Loading
core/java/android/service/notification/ZenModeConfig.java +31 −10 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF; import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; import static android.service.notification.Condition.STATE_TRUE; import static android.service.notification.SystemZenRules.PACKAGE_ANDROID; import static android.service.notification.ZenAdapters.peopleTypeToPrioritySenders; import static android.service.notification.ZenAdapters.prioritySendersToPeopleType; import static android.service.notification.ZenAdapters.zenPolicyConversationSendersToNotificationPolicy; Loading Loading @@ -454,7 +456,7 @@ public class ZenModeConfig implements Parcelable { newRule.conditionId = Uri.EMPTY; newRule.allowManualInvocation = true; newRule.zenPolicy = getDefaultZenPolicy(); newRule.pkg = "android"; newRule.pkg = PACKAGE_ANDROID; manualRule = newRule; } } Loading Loading @@ -957,15 +959,9 @@ public class ZenModeConfig implements Parcelable { rt.user = safeInt(parser, ZEN_ATT_USER, rt.user); boolean readSuppressedEffects = false; boolean readManualRule = false; boolean readManualRuleWithoutPolicy = false; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { tag = parser.getName(); if (type == XmlPullParser.END_TAG && ZEN_TAG.equals(tag)) { if (Flags.modesUi() && !readManualRule) { // migrate from fields on config into manual rule rt.manualRule.zenPolicy = rt.toZenPolicy(); } return rt; } if (type == XmlPullParser.START_TAG) { if (ALLOW_TAG.equals(tag)) { rt.allowCalls = safeBoolean(parser, ALLOW_ATT_CALLS, Loading Loading @@ -1034,9 +1030,17 @@ public class ZenModeConfig implements Parcelable { rt.suppressedVisualEffects = safeInt(parser, DISALLOW_ATT_VISUAL_EFFECTS, DEFAULT_SUPPRESSED_VISUAL_EFFECTS); } else if (MANUAL_TAG.equals(tag)) { rt.manualRule = readRuleXml(parser); if (rt.manualRule != null) { ZenRule manualRule = readRuleXml(parser); if (manualRule != null) { rt.manualRule = manualRule; // Manual rule may be present prior to modes_ui if it were on, but in that // case it would not have a set policy, so make note of the need to set // it up later. readManualRule = true; if (rt.manualRule.zenPolicy == null) { readManualRuleWithoutPolicy = true; } } } else if (AUTOMATIC_TAG.equals(tag) || (Flags.modesApi() && AUTOMATIC_DELETED_TAG.equals(tag))) { Loading @@ -1058,6 +1062,23 @@ public class ZenModeConfig implements Parcelable { STATE_ATT_CHANNELS_BYPASSING_DND, DEFAULT_CHANNELS_BYPASSING_DND); } } if (type == XmlPullParser.END_TAG && ZEN_TAG.equals(tag)) { if (Flags.modesUi() && (!readManualRule || readManualRuleWithoutPolicy)) { // migrate from fields on config into manual rule rt.manualRule.zenPolicy = rt.toZenPolicy(); if (readManualRuleWithoutPolicy) { // indicates that the xml represents a pre-modes_ui XML with an enabled // manual rule; set rule active, and fill in other fields as would be done // in ensureManualZenRule() and setManualZenMode(). rt.manualRule.pkg = PACKAGE_ANDROID; rt.manualRule.type = AutomaticZenRule.TYPE_OTHER; rt.manualRule.condition = new Condition( rt.manualRule.conditionId != null ? rt.manualRule.conditionId : Uri.EMPTY, "", STATE_TRUE); } } return rt; } } throw new IllegalStateException("Failed to reach END_DOCUMENT"); } Loading
services/core/java/com/android/server/notification/ZenModeHelper.java +5 −1 Original line number Diff line number Diff line Loading @@ -1676,7 +1676,11 @@ public class ZenModeHelper { if (config != null) { if (forRestore) { config.user = userId; if (!Flags.modesUi()) { if (Flags.modesUi()) { if (config.manualRule != null) { config.manualRule.condition = null; // don't restore transient state } } else { config.manualRule = null; // don't restore the manual rule } } Loading
services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java +77 −2 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ import static android.service.notification.Condition.SOURCE_USER_ACTION; import static android.service.notification.Condition.STATE_FALSE; import static android.service.notification.Condition.STATE_TRUE; import static android.service.notification.NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_ON; import static android.service.notification.ZenModeConfig.XML_VERSION_MODES_API; import static android.service.notification.ZenModeConfig.ZEN_TAG; import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_IMPORTANT; import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_NONE; import static android.service.notification.ZenPolicy.PEOPLE_TYPE_ANYONE; Loading Loading @@ -990,6 +992,58 @@ public class ZenModeConfigTest extends UiServiceTestCase { assertThat(fromXml.zenPolicy).isEqualTo(config.getZenPolicy()); } @Test @EnableFlags(Flags.FLAG_MODES_UI) public void testConfigXml_manualRule_upgradeWhenExisting() throws Exception { // prior to modes_ui, it's possible to have a non-null manual rule that doesn't have much // data on it because it's meant to indicate that the manual rule is on by merely existing. ZenModeConfig config = new ZenModeConfig(); config.manualRule = new ZenModeConfig.ZenRule(); config.manualRule.enabled = true; config.manualRule.pkg = "android"; config.manualRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; config.manualRule.conditionId = ZenModeConfig.toTimeCondition(mContext, 200, mUserId).id; config.manualRule.enabler = "test"; // write out entire config xml ByteArrayOutputStream baos = new ByteArrayOutputStream(); writeConfigXml(config, XML_VERSION_MODES_API, /* forBackup= */ false, baos); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ZenModeConfig fromXml = readConfigXml(bais); // The result should have a manual rule; it should have a non-null ZenPolicy and a condition // whose state is true. The conditionId and enabler data should also be preserved. assertThat(fromXml.manualRule).isNotNull(); assertThat(fromXml.manualRule.zenPolicy).isNotNull(); assertThat(fromXml.manualRule.condition).isNotNull(); assertThat(fromXml.manualRule.condition.state).isEqualTo(STATE_TRUE); assertThat(fromXml.manualRule.conditionId).isEqualTo(config.manualRule.conditionId); assertThat(fromXml.manualRule.enabler).isEqualTo("test"); assertThat(fromXml.isManualActive()).isTrue(); } @Test @EnableFlags(Flags.FLAG_MODES_UI) public void testConfigXml_manualRule_doesNotTurnOnIfNotUpgrade() throws Exception { // confirm that if the manual rule is already properly set up for modes_ui, it does not get // turned on (set to condition with STATE_TRUE) when reading xml. // getMutedAllConfig sets up the manual rule with a policy muting everything ZenModeConfig config = getMutedAllConfig(); config.manualRule.condition = new Condition(Uri.EMPTY, "", STATE_FALSE, SOURCE_USER_ACTION); assertThat(config.isManualActive()).isFalse(); // write out entire config xml ByteArrayOutputStream baos = new ByteArrayOutputStream(); writeConfigXml(config, XML_VERSION_MODES_API, /* forBackup= */ false, baos); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ZenModeConfig fromXml = readConfigXml(bais); // The result should have a manual rule; it should not be changed from the previous rule. assertThat(fromXml.manualRule).isEqualTo(config.manualRule); assertThat(fromXml.isManualActive()).isFalse(); } @Test public void testGetDescription_off() { ZenModeConfig config = new ZenModeConfig(); Loading Loading @@ -1238,4 +1292,25 @@ public class ZenModeConfigTest extends UiServiceTestCase { parser.nextTag(); return ZenModeConfig.readZenPolicyXml(parser); } private void writeConfigXml(ZenModeConfig config, Integer version, boolean forBackup, ByteArrayOutputStream os) throws IOException { String tag = ZEN_TAG; TypedXmlSerializer out = Xml.newFastSerializer(); out.setOutput(new BufferedOutputStream(os), "utf-8"); out.startDocument(null, true); out.startTag(null, tag); config.writeXml(out, version, forBackup); out.endTag(null, tag); out.endDocument(); } private ZenModeConfig readConfigXml(ByteArrayInputStream is) throws XmlPullParserException, IOException { TypedXmlPullParser parser = Xml.newFastPullParser(); parser.setInput(new BufferedInputStream(is), null); parser.nextTag(); return ZenModeConfig.readXml(parser); } }
services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +24 −0 Original line number Diff line number Diff line Loading @@ -1494,6 +1494,30 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertNotEquals(expected, mZenModeHelper.mConfig); } @Test public void testReadXmlRestore_doesNotEnableManualRule() throws Exception { setupZenConfig(); // Turn on manual zen mode mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, ORIGIN_USER_IN_SYSTEMUI, "", "someCaller", SYSTEM_UID); ZenModeConfig original = mZenModeHelper.mConfig.copy(); assertThat(original.isManualActive()).isTrue(); ByteArrayOutputStream baos = writeXmlAndPurge(null); TypedXmlPullParser parser = getParserForByteStream(baos); mZenModeHelper.readXml(parser, true, UserHandle.USER_ALL); ZenModeConfig result = mZenModeHelper.getConfig(); assertThat(result.isManualActive()).isFalse(); // confirm that we do still keep policy information, modes_ui only; prior to modes_ui the // entire rule is intentionally cleared if (Flags.modesUi()) { assertThat(result.manualRule.zenPolicy).isNotNull(); } } @Test public void testWriteXmlWithZenPolicy() throws Exception { final String ruleId = "customRule"; Loading