Loading services/core/java/com/android/server/notification/NotificationManagerService.java +1 −2 Original line number Diff line number Diff line Loading @@ -5931,8 +5931,7 @@ public class NotificationManagerService extends SystemService { newVisualEffects, policy.priorityConversationSenders); if (shouldApplyAsImplicitRule) { mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(pkg, callingUid, policy, origin); mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(pkg, callingUid, policy); } else { ZenLog.traceSetNotificationPolicy(pkg, applicationInfo.targetSdkVersion, policy); Loading services/core/java/com/android/server/notification/ZenModeHelper.java +17 −6 Original line number Diff line number Diff line Loading @@ -605,7 +605,11 @@ public class ZenModeHelper { rule = newImplicitZenRule(callingPkg); newConfig.automaticRules.put(rule.id, rule); } // If the user has changed the rule's *zenMode*, then don't let app overwrite it. // We allow the update if the user has only changed other aspects of the rule. if ((rule.userModifiedFields & AutomaticZenRule.FIELD_INTERRUPTION_FILTER) == 0) { rule.zenMode = zenMode; } rule.snoozing = false; rule.condition = new Condition(rule.conditionId, mContext.getString(R.string.zen_mode_implicit_activated), Loading @@ -628,7 +632,7 @@ public class ZenModeHelper { * {@link Global#ZEN_MODE_IMPORTANT_INTERRUPTIONS}. */ void applyGlobalPolicyAsImplicitZenRule(String callingPkg, int callingUid, NotificationManager.Policy policy, @ConfigChangeOrigin int origin) { NotificationManager.Policy policy) { if (!android.app.Flags.modesApi()) { Log.wtf(TAG, "applyGlobalPolicyAsImplicitZenRule called with flag off!"); return; Loading @@ -644,12 +648,19 @@ public class ZenModeHelper { rule.zenMode = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; newConfig.automaticRules.put(rule.id, rule); } // TODO: b/308673679 - Keep user customization of this rule! rule.zenPolicy = ZenAdapters.notificationPolicyToZenPolicy(policy); setConfigLocked(newConfig, /* triggeringComponent= */ null, origin, // If the user has changed the rule's *ZenPolicy*, then don't let app overwrite it. // We allow the update if the user has only changed other aspects of the rule. if (rule.zenPolicyUserModifiedFields == 0) { updatePolicy( rule, ZenAdapters.notificationPolicyToZenPolicy(policy), /* updateBitmask= */ false); setConfigLocked(newConfig, /* triggeringComponent= */ null, UPDATE_ORIGIN_APP, "applyGlobalPolicyAsImplicitZenRule", callingUid); } } } /** * Returns the {@link Policy} associated to the "implicit" {@link ZenRule} of a package that has Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +2 −3 Original line number Diff line number Diff line Loading @@ -13792,8 +13792,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { NotificationManager.Policy policy = new NotificationManager.Policy(0, 0, 0); mBinderService.setNotificationPolicy("package", policy, false); verify(zenHelper).applyGlobalPolicyAsImplicitZenRule(eq("package"), anyInt(), eq(policy), eq(ZenModeConfig.UPDATE_ORIGIN_APP)); verify(zenHelper).applyGlobalPolicyAsImplicitZenRule(eq("package"), anyInt(), eq(policy)); } @Test Loading Loading @@ -13859,7 +13858,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { verify(zenModeHelper).setNotificationPolicy(eq(policy), anyInt(), anyInt()); } else { verify(zenModeHelper).applyGlobalPolicyAsImplicitZenRule(anyString(), anyInt(), eq(policy), anyInt()); eq(policy)); } } services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +148 −13 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.provider.Settings.Global.ZEN_MODE_ALARMS; import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS; import static android.provider.Settings.Global.ZEN_MODE_OFF; import static android.service.notification.Condition.SOURCE_SCHEDULE; import static android.service.notification.Condition.SOURCE_USER_ACTION; Loading @@ -67,6 +68,7 @@ import static com.android.os.dnd.DNDProtoEnums.STATE_ALLOW; import static com.android.os.dnd.DNDProtoEnums.STATE_DISALLOW; import static com.android.server.notification.ZenModeHelper.RULE_LIMIT_PER_PACKAGE; import static com.google.common.collect.Iterables.getOnlyElement; import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertEquals; Loading Loading @@ -295,6 +297,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { when(appInfoSpy.loadLabel(any())).thenReturn(CUSTOM_APP_LABEL); when(mPackageManager.getApplicationInfo(eq(CUSTOM_PKG_NAME), anyInt())) .thenReturn(appInfoSpy); when(mPackageManager.getApplicationInfo(eq(mContext.getPackageName()), anyInt())) .thenReturn(appInfoSpy); mZenModeHelper.mPm = mPackageManager; mZenModeEventLogger.reset(); Loading Loading @@ -4578,7 +4582,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { ZEN_MODE_IMPORTANT_INTERRUPTIONS); assertThat(mZenModeHelper.mConfig.automaticRules.values()) .comparingElementsUsing(IGNORE_TIMESTAMPS) .comparingElementsUsing(IGNORE_METADATA) .containsExactly( expectedImplicitRule(CUSTOM_PKG_NAME, ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, true)); Loading @@ -4598,11 +4602,74 @@ public class ZenModeHelperTest extends UiServiceTestCase { ZEN_MODE_ALARMS); assertThat(mZenModeHelper.mConfig.automaticRules.values()) .comparingElementsUsing(IGNORE_TIMESTAMPS) .comparingElementsUsing(IGNORE_METADATA) .containsExactly( expectedImplicitRule(CUSTOM_PKG_NAME, ZEN_MODE_ALARMS, null, true)); } @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) public void applyGlobalZenModeAsImplicitZenRule_ruleCustomized_doesNotUpdateRule() { mZenModeHelper.mConfig.automaticRules.clear(); String pkg = mContext.getPackageName(); // From app, call "setInterruptionFilter" and create and implicit rule. mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(pkg, CUSTOM_PKG_UID, ZEN_MODE_IMPORTANT_INTERRUPTIONS); String ruleId = getOnlyElement(mZenModeHelper.mConfig.automaticRules.keySet()); assertThat(getOnlyElement(mZenModeHelper.mConfig.automaticRules.values()).zenMode) .isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS); // From user, update that rule's interruption filter. AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(ruleId); AutomaticZenRule userUpdateRule = new AutomaticZenRule.Builder(rule) .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS) .build(); mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdateRule, UPDATE_ORIGIN_USER, "reason", Process.SYSTEM_UID); // From app, call "setInterruptionFilter" again. mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(pkg, CUSTOM_PKG_UID, ZEN_MODE_NO_INTERRUPTIONS); // The app's update was ignored, and the user's update is still current, and the current // mode is the one they chose. assertThat(getOnlyElement(mZenModeHelper.mConfig.automaticRules.values()).zenMode) .isEqualTo(ZEN_MODE_ALARMS); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_ALARMS); } @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) public void applyGlobalZenModeAsImplicitZenRule_ruleCustomizedButNotFilter_updatesRule() { mZenModeHelper.mConfig.automaticRules.clear(); String pkg = mContext.getPackageName(); // From app, call "setInterruptionFilter" and create and implicit rule. mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(pkg, CUSTOM_PKG_UID, ZEN_MODE_IMPORTANT_INTERRUPTIONS); String ruleId = getOnlyElement(mZenModeHelper.mConfig.automaticRules.keySet()); assertThat(getOnlyElement(mZenModeHelper.mConfig.automaticRules.values()).zenMode) .isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS); // From user, update something in that rule, but not the interruption filter. AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(ruleId); AutomaticZenRule userUpdateRule = new AutomaticZenRule.Builder(rule) .setName("Renamed") .build(); mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdateRule, UPDATE_ORIGIN_USER, "reason", Process.SYSTEM_UID); // From app, call "setInterruptionFilter" again. mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(pkg, CUSTOM_PKG_UID, ZEN_MODE_NO_INTERRUPTIONS); // The app's update was accepted, and the current mode is the one that they wanted. assertThat(getOnlyElement(mZenModeHelper.mConfig.automaticRules.values()).zenMode) .isEqualTo(ZEN_MODE_NO_INTERRUPTIONS); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_NO_INTERRUPTIONS); } @Test public void applyGlobalZenModeAsImplicitZenRule_modeOff_deactivatesImplicitRule() { mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API); Loading Loading @@ -4673,8 +4740,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { Policy policy = new Policy(PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_CONVERSATIONS, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED, Policy.getAllSuppressedVisualEffects(), CONVERSATION_SENDERS_IMPORTANT); mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(CUSTOM_PKG_NAME, CUSTOM_PKG_UID, policy, UPDATE_ORIGIN_APP); mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(CUSTOM_PKG_NAME, CUSTOM_PKG_UID, policy); ZenPolicy expectedZenPolicy = new ZenPolicy.Builder() .disallowAllSounds() Loading @@ -4684,7 +4750,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .allowPriorityChannels(true) .build(); assertThat(mZenModeHelper.mConfig.automaticRules.values()) .comparingElementsUsing(IGNORE_TIMESTAMPS) .comparingElementsUsing(IGNORE_METADATA) .containsExactly( expectedImplicitRule(CUSTOM_PKG_NAME, ZEN_MODE_IMPORTANT_INTERRUPTIONS, expectedZenPolicy, /* conditionActive= */ null)); Loading @@ -4699,14 +4765,13 @@ public class ZenModeHelperTest extends UiServiceTestCase { PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED, Policy.getAllSuppressedVisualEffects(), CONVERSATION_SENDERS_IMPORTANT); mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(CUSTOM_PKG_NAME, CUSTOM_PKG_UID, original, UPDATE_ORIGIN_APP); original); // Change priorityCallSenders: contacts -> starred. Policy updated = new Policy(PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_CONVERSATIONS, PRIORITY_SENDERS_STARRED, PRIORITY_SENDERS_STARRED, Policy.getAllSuppressedVisualEffects(), CONVERSATION_SENDERS_IMPORTANT); mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(CUSTOM_PKG_NAME, CUSTOM_PKG_UID, updated, UPDATE_ORIGIN_APP); mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(CUSTOM_PKG_NAME, CUSTOM_PKG_UID, updated); ZenPolicy expectedZenPolicy = new ZenPolicy.Builder() .disallowAllSounds() Loading @@ -4716,12 +4781,79 @@ public class ZenModeHelperTest extends UiServiceTestCase { .allowPriorityChannels(true) .build(); assertThat(mZenModeHelper.mConfig.automaticRules.values()) .comparingElementsUsing(IGNORE_TIMESTAMPS) .comparingElementsUsing(IGNORE_METADATA) .containsExactly( expectedImplicitRule(CUSTOM_PKG_NAME, ZEN_MODE_IMPORTANT_INTERRUPTIONS, expectedZenPolicy, /* conditionActive= */ null)); } @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) public void applyGlobalPolicyAsImplicitZenRule_ruleCustomized_doesNotUpdateRule() { mZenModeHelper.mConfig.automaticRules.clear(); String pkg = mContext.getPackageName(); // From app, call "setNotificationPolicy" and create and implicit rule. Policy originalPolicy = new Policy(PRIORITY_CATEGORY_MEDIA, 0, 0); mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(pkg, CUSTOM_PKG_UID, originalPolicy); String ruleId = getOnlyElement(mZenModeHelper.mConfig.automaticRules.keySet()); // From user, update that rule's policy. AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(ruleId); ZenPolicy userUpdateZenPolicy = new ZenPolicy.Builder().disallowAllSounds() .allowAlarms(true).build(); AutomaticZenRule userUpdateRule = new AutomaticZenRule.Builder(rule) .setZenPolicy(userUpdateZenPolicy) .build(); mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdateRule, UPDATE_ORIGIN_USER, "reason", Process.SYSTEM_UID); // From app, call "setNotificationPolicy" again. Policy appUpdatePolicy = new Policy(PRIORITY_CATEGORY_SYSTEM, 0, 0); mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(pkg, CUSTOM_PKG_UID, appUpdatePolicy); // The app's update was ignored, and the user's update is still current. assertThat(mZenModeHelper.mConfig.automaticRules.values()) .comparingElementsUsing(IGNORE_METADATA) .containsExactly( expectedImplicitRule(pkg, ZEN_MODE_IMPORTANT_INTERRUPTIONS, userUpdateZenPolicy, /* conditionActive= */ null)); } @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) public void applyGlobalPolicyAsImplicitZenRule_ruleCustomizedButNotZenPolicy_updatesRule() { mZenModeHelper.mConfig.automaticRules.clear(); String pkg = mContext.getPackageName(); // From app, call "setNotificationPolicy" and create and implicit rule. Policy originalPolicy = new Policy(PRIORITY_CATEGORY_MEDIA, 0, 0); mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(pkg, CUSTOM_PKG_UID, originalPolicy); String ruleId = getOnlyElement(mZenModeHelper.mConfig.automaticRules.keySet()); // From user, update something in that rule, but not the ZenPolicy. AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(ruleId); AutomaticZenRule userUpdateRule = new AutomaticZenRule.Builder(rule) .setName("Rule renamed, not touching policy") .build(); mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdateRule, UPDATE_ORIGIN_USER, "reason", Process.SYSTEM_UID); // From app, call "setNotificationPolicy" again. Policy appUpdatePolicy = new Policy(PRIORITY_CATEGORY_SYSTEM, 0, 0); mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(pkg, CUSTOM_PKG_UID, appUpdatePolicy); // The app's update was applied. ZenPolicy appsSecondZenPolicy = new ZenPolicy.Builder() .disallowAllSounds() .allowSystem(true) .allowPriorityChannels(true) .build(); assertThat(getOnlyElement(mZenModeHelper.mConfig.automaticRules.values()).zenPolicy) .isEqualTo(appsSecondZenPolicy); } @Test public void applyGlobalPolicyAsImplicitZenRule_flagOff_ignored() { mSetFlagsRule.disableFlags(android.app.Flags.FLAG_MODES_API); Loading @@ -4729,7 +4861,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { withoutWtfCrash( () -> mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(CUSTOM_PKG_NAME, CUSTOM_PKG_UID, new Policy(0, 0, 0), UPDATE_ORIGIN_APP)); CUSTOM_PKG_UID, new Policy(0, 0, 0))); assertThat(mZenModeHelper.mConfig.automaticRules).isEmpty(); } Loading @@ -4742,7 +4874,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { Policy.getAllSuppressedVisualEffects(), STATE_FALSE, CONVERSATION_SENDERS_IMPORTANT); mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(CUSTOM_PKG_NAME, CUSTOM_PKG_UID, writtenPolicy, UPDATE_ORIGIN_APP); writtenPolicy); Policy readPolicy = mZenModeHelper.getNotificationPolicyFromImplicitZenRule( CUSTOM_PKG_NAME); Loading Loading @@ -4782,7 +4914,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertThat(readPolicy.allowConversations()).isFalse(); } private static final Correspondence<ZenRule, ZenRule> IGNORE_TIMESTAMPS = private static final Correspondence<ZenRule, ZenRule> IGNORE_METADATA = Correspondence.transforming(zr -> { Parcel p = Parcel.obtain(); try { Loading @@ -4790,12 +4922,15 @@ public class ZenModeHelperTest extends UiServiceTestCase { p.setDataPosition(0); ZenRule copy = new ZenRule(p); copy.creationTime = 0; copy.userModifiedFields = 0; copy.zenPolicyUserModifiedFields = 0; copy.zenDeviceEffectsUserModifiedFields = 0; return copy; } finally { p.recycle(); } }, "Ignoring timestamps"); "Ignoring timestamp and userModifiedFields"); private ZenRule expectedImplicitRule(String ownerPkg, int zenMode, ZenPolicy policy, @Nullable Boolean conditionActive) { Loading Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +1 −2 Original line number Diff line number Diff line Loading @@ -5931,8 +5931,7 @@ public class NotificationManagerService extends SystemService { newVisualEffects, policy.priorityConversationSenders); if (shouldApplyAsImplicitRule) { mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(pkg, callingUid, policy, origin); mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(pkg, callingUid, policy); } else { ZenLog.traceSetNotificationPolicy(pkg, applicationInfo.targetSdkVersion, policy); Loading
services/core/java/com/android/server/notification/ZenModeHelper.java +17 −6 Original line number Diff line number Diff line Loading @@ -605,7 +605,11 @@ public class ZenModeHelper { rule = newImplicitZenRule(callingPkg); newConfig.automaticRules.put(rule.id, rule); } // If the user has changed the rule's *zenMode*, then don't let app overwrite it. // We allow the update if the user has only changed other aspects of the rule. if ((rule.userModifiedFields & AutomaticZenRule.FIELD_INTERRUPTION_FILTER) == 0) { rule.zenMode = zenMode; } rule.snoozing = false; rule.condition = new Condition(rule.conditionId, mContext.getString(R.string.zen_mode_implicit_activated), Loading @@ -628,7 +632,7 @@ public class ZenModeHelper { * {@link Global#ZEN_MODE_IMPORTANT_INTERRUPTIONS}. */ void applyGlobalPolicyAsImplicitZenRule(String callingPkg, int callingUid, NotificationManager.Policy policy, @ConfigChangeOrigin int origin) { NotificationManager.Policy policy) { if (!android.app.Flags.modesApi()) { Log.wtf(TAG, "applyGlobalPolicyAsImplicitZenRule called with flag off!"); return; Loading @@ -644,12 +648,19 @@ public class ZenModeHelper { rule.zenMode = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; newConfig.automaticRules.put(rule.id, rule); } // TODO: b/308673679 - Keep user customization of this rule! rule.zenPolicy = ZenAdapters.notificationPolicyToZenPolicy(policy); setConfigLocked(newConfig, /* triggeringComponent= */ null, origin, // If the user has changed the rule's *ZenPolicy*, then don't let app overwrite it. // We allow the update if the user has only changed other aspects of the rule. if (rule.zenPolicyUserModifiedFields == 0) { updatePolicy( rule, ZenAdapters.notificationPolicyToZenPolicy(policy), /* updateBitmask= */ false); setConfigLocked(newConfig, /* triggeringComponent= */ null, UPDATE_ORIGIN_APP, "applyGlobalPolicyAsImplicitZenRule", callingUid); } } } /** * Returns the {@link Policy} associated to the "implicit" {@link ZenRule} of a package that has Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +2 −3 Original line number Diff line number Diff line Loading @@ -13792,8 +13792,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { NotificationManager.Policy policy = new NotificationManager.Policy(0, 0, 0); mBinderService.setNotificationPolicy("package", policy, false); verify(zenHelper).applyGlobalPolicyAsImplicitZenRule(eq("package"), anyInt(), eq(policy), eq(ZenModeConfig.UPDATE_ORIGIN_APP)); verify(zenHelper).applyGlobalPolicyAsImplicitZenRule(eq("package"), anyInt(), eq(policy)); } @Test Loading Loading @@ -13859,7 +13858,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { verify(zenModeHelper).setNotificationPolicy(eq(policy), anyInt(), anyInt()); } else { verify(zenModeHelper).applyGlobalPolicyAsImplicitZenRule(anyString(), anyInt(), eq(policy), anyInt()); eq(policy)); } }
services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +148 −13 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.provider.Settings.Global.ZEN_MODE_ALARMS; import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS; import static android.provider.Settings.Global.ZEN_MODE_OFF; import static android.service.notification.Condition.SOURCE_SCHEDULE; import static android.service.notification.Condition.SOURCE_USER_ACTION; Loading @@ -67,6 +68,7 @@ import static com.android.os.dnd.DNDProtoEnums.STATE_ALLOW; import static com.android.os.dnd.DNDProtoEnums.STATE_DISALLOW; import static com.android.server.notification.ZenModeHelper.RULE_LIMIT_PER_PACKAGE; import static com.google.common.collect.Iterables.getOnlyElement; import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertEquals; Loading Loading @@ -295,6 +297,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { when(appInfoSpy.loadLabel(any())).thenReturn(CUSTOM_APP_LABEL); when(mPackageManager.getApplicationInfo(eq(CUSTOM_PKG_NAME), anyInt())) .thenReturn(appInfoSpy); when(mPackageManager.getApplicationInfo(eq(mContext.getPackageName()), anyInt())) .thenReturn(appInfoSpy); mZenModeHelper.mPm = mPackageManager; mZenModeEventLogger.reset(); Loading Loading @@ -4578,7 +4582,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { ZEN_MODE_IMPORTANT_INTERRUPTIONS); assertThat(mZenModeHelper.mConfig.automaticRules.values()) .comparingElementsUsing(IGNORE_TIMESTAMPS) .comparingElementsUsing(IGNORE_METADATA) .containsExactly( expectedImplicitRule(CUSTOM_PKG_NAME, ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, true)); Loading @@ -4598,11 +4602,74 @@ public class ZenModeHelperTest extends UiServiceTestCase { ZEN_MODE_ALARMS); assertThat(mZenModeHelper.mConfig.automaticRules.values()) .comparingElementsUsing(IGNORE_TIMESTAMPS) .comparingElementsUsing(IGNORE_METADATA) .containsExactly( expectedImplicitRule(CUSTOM_PKG_NAME, ZEN_MODE_ALARMS, null, true)); } @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) public void applyGlobalZenModeAsImplicitZenRule_ruleCustomized_doesNotUpdateRule() { mZenModeHelper.mConfig.automaticRules.clear(); String pkg = mContext.getPackageName(); // From app, call "setInterruptionFilter" and create and implicit rule. mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(pkg, CUSTOM_PKG_UID, ZEN_MODE_IMPORTANT_INTERRUPTIONS); String ruleId = getOnlyElement(mZenModeHelper.mConfig.automaticRules.keySet()); assertThat(getOnlyElement(mZenModeHelper.mConfig.automaticRules.values()).zenMode) .isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS); // From user, update that rule's interruption filter. AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(ruleId); AutomaticZenRule userUpdateRule = new AutomaticZenRule.Builder(rule) .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS) .build(); mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdateRule, UPDATE_ORIGIN_USER, "reason", Process.SYSTEM_UID); // From app, call "setInterruptionFilter" again. mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(pkg, CUSTOM_PKG_UID, ZEN_MODE_NO_INTERRUPTIONS); // The app's update was ignored, and the user's update is still current, and the current // mode is the one they chose. assertThat(getOnlyElement(mZenModeHelper.mConfig.automaticRules.values()).zenMode) .isEqualTo(ZEN_MODE_ALARMS); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_ALARMS); } @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) public void applyGlobalZenModeAsImplicitZenRule_ruleCustomizedButNotFilter_updatesRule() { mZenModeHelper.mConfig.automaticRules.clear(); String pkg = mContext.getPackageName(); // From app, call "setInterruptionFilter" and create and implicit rule. mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(pkg, CUSTOM_PKG_UID, ZEN_MODE_IMPORTANT_INTERRUPTIONS); String ruleId = getOnlyElement(mZenModeHelper.mConfig.automaticRules.keySet()); assertThat(getOnlyElement(mZenModeHelper.mConfig.automaticRules.values()).zenMode) .isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS); // From user, update something in that rule, but not the interruption filter. AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(ruleId); AutomaticZenRule userUpdateRule = new AutomaticZenRule.Builder(rule) .setName("Renamed") .build(); mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdateRule, UPDATE_ORIGIN_USER, "reason", Process.SYSTEM_UID); // From app, call "setInterruptionFilter" again. mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(pkg, CUSTOM_PKG_UID, ZEN_MODE_NO_INTERRUPTIONS); // The app's update was accepted, and the current mode is the one that they wanted. assertThat(getOnlyElement(mZenModeHelper.mConfig.automaticRules.values()).zenMode) .isEqualTo(ZEN_MODE_NO_INTERRUPTIONS); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_NO_INTERRUPTIONS); } @Test public void applyGlobalZenModeAsImplicitZenRule_modeOff_deactivatesImplicitRule() { mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API); Loading Loading @@ -4673,8 +4740,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { Policy policy = new Policy(PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_CONVERSATIONS, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED, Policy.getAllSuppressedVisualEffects(), CONVERSATION_SENDERS_IMPORTANT); mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(CUSTOM_PKG_NAME, CUSTOM_PKG_UID, policy, UPDATE_ORIGIN_APP); mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(CUSTOM_PKG_NAME, CUSTOM_PKG_UID, policy); ZenPolicy expectedZenPolicy = new ZenPolicy.Builder() .disallowAllSounds() Loading @@ -4684,7 +4750,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .allowPriorityChannels(true) .build(); assertThat(mZenModeHelper.mConfig.automaticRules.values()) .comparingElementsUsing(IGNORE_TIMESTAMPS) .comparingElementsUsing(IGNORE_METADATA) .containsExactly( expectedImplicitRule(CUSTOM_PKG_NAME, ZEN_MODE_IMPORTANT_INTERRUPTIONS, expectedZenPolicy, /* conditionActive= */ null)); Loading @@ -4699,14 +4765,13 @@ public class ZenModeHelperTest extends UiServiceTestCase { PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED, Policy.getAllSuppressedVisualEffects(), CONVERSATION_SENDERS_IMPORTANT); mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(CUSTOM_PKG_NAME, CUSTOM_PKG_UID, original, UPDATE_ORIGIN_APP); original); // Change priorityCallSenders: contacts -> starred. Policy updated = new Policy(PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_CONVERSATIONS, PRIORITY_SENDERS_STARRED, PRIORITY_SENDERS_STARRED, Policy.getAllSuppressedVisualEffects(), CONVERSATION_SENDERS_IMPORTANT); mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(CUSTOM_PKG_NAME, CUSTOM_PKG_UID, updated, UPDATE_ORIGIN_APP); mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(CUSTOM_PKG_NAME, CUSTOM_PKG_UID, updated); ZenPolicy expectedZenPolicy = new ZenPolicy.Builder() .disallowAllSounds() Loading @@ -4716,12 +4781,79 @@ public class ZenModeHelperTest extends UiServiceTestCase { .allowPriorityChannels(true) .build(); assertThat(mZenModeHelper.mConfig.automaticRules.values()) .comparingElementsUsing(IGNORE_TIMESTAMPS) .comparingElementsUsing(IGNORE_METADATA) .containsExactly( expectedImplicitRule(CUSTOM_PKG_NAME, ZEN_MODE_IMPORTANT_INTERRUPTIONS, expectedZenPolicy, /* conditionActive= */ null)); } @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) public void applyGlobalPolicyAsImplicitZenRule_ruleCustomized_doesNotUpdateRule() { mZenModeHelper.mConfig.automaticRules.clear(); String pkg = mContext.getPackageName(); // From app, call "setNotificationPolicy" and create and implicit rule. Policy originalPolicy = new Policy(PRIORITY_CATEGORY_MEDIA, 0, 0); mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(pkg, CUSTOM_PKG_UID, originalPolicy); String ruleId = getOnlyElement(mZenModeHelper.mConfig.automaticRules.keySet()); // From user, update that rule's policy. AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(ruleId); ZenPolicy userUpdateZenPolicy = new ZenPolicy.Builder().disallowAllSounds() .allowAlarms(true).build(); AutomaticZenRule userUpdateRule = new AutomaticZenRule.Builder(rule) .setZenPolicy(userUpdateZenPolicy) .build(); mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdateRule, UPDATE_ORIGIN_USER, "reason", Process.SYSTEM_UID); // From app, call "setNotificationPolicy" again. Policy appUpdatePolicy = new Policy(PRIORITY_CATEGORY_SYSTEM, 0, 0); mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(pkg, CUSTOM_PKG_UID, appUpdatePolicy); // The app's update was ignored, and the user's update is still current. assertThat(mZenModeHelper.mConfig.automaticRules.values()) .comparingElementsUsing(IGNORE_METADATA) .containsExactly( expectedImplicitRule(pkg, ZEN_MODE_IMPORTANT_INTERRUPTIONS, userUpdateZenPolicy, /* conditionActive= */ null)); } @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) public void applyGlobalPolicyAsImplicitZenRule_ruleCustomizedButNotZenPolicy_updatesRule() { mZenModeHelper.mConfig.automaticRules.clear(); String pkg = mContext.getPackageName(); // From app, call "setNotificationPolicy" and create and implicit rule. Policy originalPolicy = new Policy(PRIORITY_CATEGORY_MEDIA, 0, 0); mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(pkg, CUSTOM_PKG_UID, originalPolicy); String ruleId = getOnlyElement(mZenModeHelper.mConfig.automaticRules.keySet()); // From user, update something in that rule, but not the ZenPolicy. AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(ruleId); AutomaticZenRule userUpdateRule = new AutomaticZenRule.Builder(rule) .setName("Rule renamed, not touching policy") .build(); mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdateRule, UPDATE_ORIGIN_USER, "reason", Process.SYSTEM_UID); // From app, call "setNotificationPolicy" again. Policy appUpdatePolicy = new Policy(PRIORITY_CATEGORY_SYSTEM, 0, 0); mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(pkg, CUSTOM_PKG_UID, appUpdatePolicy); // The app's update was applied. ZenPolicy appsSecondZenPolicy = new ZenPolicy.Builder() .disallowAllSounds() .allowSystem(true) .allowPriorityChannels(true) .build(); assertThat(getOnlyElement(mZenModeHelper.mConfig.automaticRules.values()).zenPolicy) .isEqualTo(appsSecondZenPolicy); } @Test public void applyGlobalPolicyAsImplicitZenRule_flagOff_ignored() { mSetFlagsRule.disableFlags(android.app.Flags.FLAG_MODES_API); Loading @@ -4729,7 +4861,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { withoutWtfCrash( () -> mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(CUSTOM_PKG_NAME, CUSTOM_PKG_UID, new Policy(0, 0, 0), UPDATE_ORIGIN_APP)); CUSTOM_PKG_UID, new Policy(0, 0, 0))); assertThat(mZenModeHelper.mConfig.automaticRules).isEmpty(); } Loading @@ -4742,7 +4874,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { Policy.getAllSuppressedVisualEffects(), STATE_FALSE, CONVERSATION_SENDERS_IMPORTANT); mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(CUSTOM_PKG_NAME, CUSTOM_PKG_UID, writtenPolicy, UPDATE_ORIGIN_APP); writtenPolicy); Policy readPolicy = mZenModeHelper.getNotificationPolicyFromImplicitZenRule( CUSTOM_PKG_NAME); Loading Loading @@ -4782,7 +4914,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertThat(readPolicy.allowConversations()).isFalse(); } private static final Correspondence<ZenRule, ZenRule> IGNORE_TIMESTAMPS = private static final Correspondence<ZenRule, ZenRule> IGNORE_METADATA = Correspondence.transforming(zr -> { Parcel p = Parcel.obtain(); try { Loading @@ -4790,12 +4922,15 @@ public class ZenModeHelperTest extends UiServiceTestCase { p.setDataPosition(0); ZenRule copy = new ZenRule(p); copy.creationTime = 0; copy.userModifiedFields = 0; copy.zenPolicyUserModifiedFields = 0; copy.zenDeviceEffectsUserModifiedFields = 0; return copy; } finally { p.recycle(); } }, "Ignoring timestamps"); "Ignoring timestamp and userModifiedFields"); private ZenRule expectedImplicitRule(String ownerPkg, int zenMode, ZenPolicy policy, @Nullable Boolean conditionActive) { Loading