Merge "Keep legacy suppressed-effect Policy fields in MODES_UI" into main
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index e16a6a1..7ca248d 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -211,6 +211,9 @@
SUPPRESSED_EFFECT_SCREEN_OFF | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
| SUPPRESSED_EFFECT_LIGHTS | SUPPRESSED_EFFECT_PEEK | SUPPRESSED_EFFECT_AMBIENT;
+ private static final int LEGACY_SUPPRESSED_EFFECTS =
+ Policy.SUPPRESSED_EFFECT_SCREEN_ON | Policy.SUPPRESSED_EFFECT_SCREEN_OFF;
+
// ZenModeConfig XML versions distinguishing key changes.
public static final int XML_VERSION_ZEN_UPGRADE = 8;
public static final int XML_VERSION_MODES_API = 11;
@@ -284,6 +287,7 @@
private static final String RULE_ATT_TRIGGER_DESC = "triggerDesc";
private static final String RULE_ATT_DELETION_INSTANT = "deletionInstant";
private static final String RULE_ATT_DISABLED_ORIGIN = "disabledOrigin";
+ private static final String RULE_ATT_LEGACY_SUPPRESSED_EFFECTS = "legacySuppressedEffects";
private static final String DEVICE_EFFECT_DISPLAY_GRAYSCALE = "zdeDisplayGrayscale";
private static final String DEVICE_EFFECT_SUPPRESS_AMBIENT_DISPLAY =
@@ -1171,6 +1175,8 @@
if (Flags.modesUi()) {
rt.disabledOrigin = safeInt(parser, RULE_ATT_DISABLED_ORIGIN,
UPDATE_ORIGIN_UNKNOWN);
+ rt.legacySuppressedEffects = safeInt(parser,
+ RULE_ATT_LEGACY_SUPPRESSED_EFFECTS, 0);
}
}
return rt;
@@ -1228,6 +1234,8 @@
}
if (Flags.modesUi()) {
out.attributeInt(null, RULE_ATT_DISABLED_ORIGIN, rule.disabledOrigin);
+ out.attributeInt(null, RULE_ATT_LEGACY_SUPPRESSED_EFFECTS,
+ rule.legacySuppressedEffects);
}
}
}
@@ -1903,6 +1911,13 @@
ZenPolicy.VISUAL_EFFECT_NOTIFICATION_LIST))) {
suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST;
}
+
+ // Restore legacy suppressed effects (obsolete fields which are not in ZenPolicy).
+ // These are deprecated and have no effect on behavior, however apps should get them
+ // back if provided to setNotificationPolicy() earlier.
+ suppressedVisualEffects &= ~LEGACY_SUPPRESSED_EFFECTS;
+ suppressedVisualEffects |=
+ (LEGACY_SUPPRESSED_EFFECTS & manualRule.legacySuppressedEffects);
} else {
if (isAllowConversations()) {
priorityCategories |= Policy.PRIORITY_CATEGORY_CONVERSATIONS;
@@ -1996,6 +2011,8 @@
if (policy == null) return;
if (Flags.modesUi()) {
manualRule.zenPolicy = ZenAdapters.notificationPolicyToZenPolicy(policy);
+ manualRule.legacySuppressedEffects =
+ LEGACY_SUPPRESSED_EFFECTS & policy.suppressedVisualEffects;
} else {
setAllowAlarms((policy.priorityCategories & Policy.PRIORITY_CATEGORY_ALARMS) != 0);
allowMedia = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_MEDIA) != 0;
@@ -2521,6 +2538,10 @@
@Nullable public Instant deletionInstant; // Only set on deleted rules.
@FlaggedApi(Flags.FLAG_MODES_UI)
@ConfigChangeOrigin public int disabledOrigin = UPDATE_ORIGIN_UNKNOWN;
+ // The obsolete suppressed effects in NM.Policy (SCREEN_ON, SCREEN_OFF) cannot be put in a
+ // ZenPolicy, so we store them here, only for the manual rule.
+ @FlaggedApi(Flags.FLAG_MODES_UI)
+ int legacySuppressedEffects;
public ZenRule() { }
@@ -2561,6 +2582,7 @@
}
if (Flags.modesUi()) {
disabledOrigin = source.readInt();
+ legacySuppressedEffects = source.readInt();
}
}
}
@@ -2638,6 +2660,7 @@
}
if (Flags.modesUi()) {
dest.writeInt(disabledOrigin);
+ dest.writeInt(legacySuppressedEffects);
}
}
}
@@ -2686,6 +2709,7 @@
}
if (Flags.modesUi()) {
sb.append(",disabledOrigin=").append(disabledOrigin);
+ sb.append(",legacySuppressedEffects=").append(legacySuppressedEffects);
}
}
@@ -2754,7 +2778,8 @@
if (Flags.modesUi()) {
finalEquals = finalEquals
- && other.disabledOrigin == disabledOrigin;
+ && other.disabledOrigin == disabledOrigin
+ && other.legacySuppressedEffects == legacySuppressedEffects;
}
}
@@ -2769,15 +2794,15 @@
component, configurationActivity, pkg, id, enabler, zenPolicy,
zenDeviceEffects, modified, allowManualInvocation, iconResName,
triggerDescription, type, userModifiedFields,
- zenPolicyUserModifiedFields,
- zenDeviceEffectsUserModifiedFields, deletionInstant, disabledOrigin);
+ zenPolicyUserModifiedFields, zenDeviceEffectsUserModifiedFields,
+ deletionInstant, disabledOrigin, legacySuppressedEffects);
} else {
return Objects.hash(enabled, snoozing, name, zenMode, conditionId, condition,
component, configurationActivity, pkg, id, enabler, zenPolicy,
zenDeviceEffects, modified, allowManualInvocation, iconResName,
triggerDescription, type, userModifiedFields,
- zenPolicyUserModifiedFields,
- zenDeviceEffectsUserModifiedFields, deletionInstant);
+ zenPolicyUserModifiedFields, zenDeviceEffectsUserModifiedFields,
+ deletionInstant);
}
}
return Objects.hash(enabled, snoozing, name, zenMode, conditionId, condition,
diff --git a/core/java/android/service/notification/ZenModeDiff.java b/core/java/android/service/notification/ZenModeDiff.java
index 91ef11c..a37e227 100644
--- a/core/java/android/service/notification/ZenModeDiff.java
+++ b/core/java/android/service/notification/ZenModeDiff.java
@@ -472,6 +472,7 @@
public static final String FIELD_ICON_RES = "iconResName";
public static final String FIELD_TRIGGER_DESCRIPTION = "triggerDescription";
public static final String FIELD_TYPE = "type";
+ public static final String FIELD_LEGACY_SUPPRESSED_EFFECTS = "legacySuppressedEffects";
// NOTE: new field strings must match the variable names in ZenModeConfig.ZenRule
// Special field to track whether this rule became active or inactive
@@ -567,6 +568,13 @@
if (!Objects.equals(from.iconResName, to.iconResName)) {
addField(FIELD_ICON_RES, new FieldDiff<>(from.iconResName, to.iconResName));
}
+ if (android.app.Flags.modesUi()) {
+ if (from.legacySuppressedEffects != to.legacySuppressedEffects) {
+ addField(FIELD_LEGACY_SUPPRESSED_EFFECTS,
+ new FieldDiff<>(from.legacySuppressedEffects,
+ to.legacySuppressedEffects));
+ }
+ }
}
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
index f7340ab..3c3c2f3 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
@@ -19,12 +19,18 @@
import static android.app.AutomaticZenRule.TYPE_BEDTIME;
import static android.app.Flags.FLAG_MODES_UI;
import static android.app.Flags.modesUi;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
+import static android.app.NotificationManager.Policy.suppressedEffectsToString;
import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
import static android.provider.Settings.Global.ZEN_MODE_OFF;
import static android.service.notification.Condition.SOURCE_UNKNOWN;
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.ZenPolicy.CONVERSATION_SENDERS_IMPORTANT;
import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_NONE;
import static android.service.notification.ZenPolicy.PEOPLE_TYPE_ANYONE;
@@ -219,8 +225,8 @@
priorityCategories |= Policy.PRIORITY_CATEGORY_REMINDERS;
priorityCategories |= Policy.PRIORITY_CATEGORY_EVENTS;
priorityCategories |= Policy.PRIORITY_CATEGORY_CONVERSATIONS;
- suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_LIGHTS;
- suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_AMBIENT;
+ suppressedVisualEffects |= SUPPRESSED_EFFECT_LIGHTS;
+ suppressedVisualEffects |= SUPPRESSED_EFFECT_AMBIENT;
Policy expectedPolicy = new Policy(priorityCategories, priorityCallSenders,
priorityMessageSenders, suppressedVisualEffects, 0, priorityConversationsSenders);
@@ -256,8 +262,8 @@
priorityCategories |= Policy.PRIORITY_CATEGORY_REMINDERS;
priorityCategories |= Policy.PRIORITY_CATEGORY_EVENTS;
priorityCategories |= Policy.PRIORITY_CATEGORY_CONVERSATIONS;
- suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_LIGHTS;
- suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_AMBIENT;
+ suppressedVisualEffects |= SUPPRESSED_EFFECT_LIGHTS;
+ suppressedVisualEffects |= SUPPRESSED_EFFECT_AMBIENT;
Policy expectedPolicy = new Policy(priorityCategories, priorityCallSenders,
priorityMessageSenders, suppressedVisualEffects,
@@ -309,8 +315,8 @@
config.setAllowMessagesFrom(Policy.PRIORITY_SENDERS_STARRED);
config.setAllowConversationsFrom(CONVERSATION_SENDERS_NONE);
config.setSuppressedVisualEffects(config.getSuppressedVisualEffects()
- | Policy.SUPPRESSED_EFFECT_BADGE | Policy.SUPPRESSED_EFFECT_LIGHTS
- | Policy.SUPPRESSED_EFFECT_AMBIENT);
+ | Policy.SUPPRESSED_EFFECT_BADGE | SUPPRESSED_EFFECT_LIGHTS
+ | SUPPRESSED_EFFECT_AMBIENT);
}
ZenPolicy actual = config.getZenPolicy();
@@ -357,8 +363,8 @@
config.setAllowConversationsFrom(CONVERSATION_SENDERS_NONE);
config.setAllowPriorityChannels(false);
config.setSuppressedVisualEffects(config.getSuppressedVisualEffects()
- | Policy.SUPPRESSED_EFFECT_BADGE | Policy.SUPPRESSED_EFFECT_LIGHTS
- | Policy.SUPPRESSED_EFFECT_AMBIENT);
+ | Policy.SUPPRESSED_EFFECT_BADGE | SUPPRESSED_EFFECT_LIGHTS
+ | SUPPRESSED_EFFECT_AMBIENT);
}
ZenPolicy actual = config.getZenPolicy();
@@ -1063,6 +1069,43 @@
.isEqualTo("name");
}
+ @Test
+ public void toNotificationPolicy_withNewSuppressedEffects_returnsSuppressedEffects() {
+ ZenModeConfig config = getCustomConfig();
+ // From LegacyNotificationManagerTest.testSetNotificationPolicy_preP_setNewFields
+ // When a pre-P app sets SUPPRESSED_EFFECT_NOTIFICATION_LIST, it's converted by NMS into:
+ Policy policy = new Policy(0, 0, 0,
+ SUPPRESSED_EFFECT_FULL_SCREEN_INTENT | SUPPRESSED_EFFECT_LIGHTS
+ | SUPPRESSED_EFFECT_PEEK | SUPPRESSED_EFFECT_AMBIENT);
+
+ config.applyNotificationPolicy(policy);
+ Policy result = config.toNotificationPolicy();
+
+ assertThat(suppressedEffectsOf(result)).isEqualTo(suppressedEffectsOf(policy));
+ }
+
+ @Test
+ public void toNotificationPolicy_withOldAndNewSuppressedEffects_returnsSuppressedEffects() {
+ ZenModeConfig config = getCustomConfig();
+ // From LegacyNotificationManagerTest.testSetNotificationPolicy_preP_setOldNewFields.
+ // When a pre-P app sets SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_STATUS_BAR, it's
+ // converted by NMS into:
+ Policy policy = new Policy(0, 0, 0,
+ SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
+ | SUPPRESSED_EFFECT_LIGHTS | SUPPRESSED_EFFECT_PEEK
+ | SUPPRESSED_EFFECT_AMBIENT);
+
+ config.applyNotificationPolicy(policy);
+ Policy result = config.toNotificationPolicy();
+
+ assertThat(suppressedEffectsOf(result)).isEqualTo(suppressedEffectsOf(policy));
+ }
+
+ private static String suppressedEffectsOf(Policy policy) {
+ return suppressedEffectsToString(policy.suppressedVisualEffects) + "("
+ + policy.suppressedVisualEffects + ")";
+ }
+
private ZenModeConfig getMutedRingerConfig() {
ZenModeConfig config = new ZenModeConfig();
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java
index 57587f7..9af0021 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java
@@ -61,6 +61,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
@@ -80,19 +81,6 @@
? Set.of("version", "manualRule", "automaticRules", "deletedRules")
: Set.of("version", "manualRule", "automaticRules");
- // Differences for flagged fields are only generated if the flag is enabled.
- // "Metadata" fields (userModifiedFields, deletionInstant, disabledOrigin) are not compared.
- private static final Set<String> ZEN_RULE_EXEMPT_FIELDS =
- android.app.Flags.modesApi()
- ? Set.of("userModifiedFields", "zenPolicyUserModifiedFields",
- "zenDeviceEffectsUserModifiedFields", "deletionInstant",
- "disabledOrigin")
- : Set.of(RuleDiff.FIELD_TYPE, RuleDiff.FIELD_TRIGGER_DESCRIPTION,
- RuleDiff.FIELD_ICON_RES, RuleDiff.FIELD_ALLOW_MANUAL,
- RuleDiff.FIELD_ZEN_DEVICE_EFFECTS, "userModifiedFields",
- "zenPolicyUserModifiedFields", "zenDeviceEffectsUserModifiedFields",
- "deletionInstant", "disabledOrigin");
-
// allowPriorityChannels is flagged by android.app.modes_api
public static final Set<String> ZEN_MODE_CONFIG_FLAGGED_FIELDS =
Set.of("allowPriorityChannels");
@@ -102,8 +90,7 @@
@Parameters(name = "{0}")
public static List<FlagsParameterization> getParams() {
- return FlagsParameterization.allCombinationsOf(
- FLAG_MODES_UI);
+ return FlagsParameterization.progressionOf(FLAG_MODES_API, FLAG_MODES_UI);
}
public ZenModeDiffTest(FlagsParameterization flags) {
@@ -140,7 +127,7 @@
ArrayMap<String, Object> expectedFrom = new ArrayMap<>();
ArrayMap<String, Object> expectedTo = new ArrayMap<>();
List<Field> fieldsForDiff = getFieldsForDiffCheck(
- ZenModeConfig.ZenRule.class, ZEN_RULE_EXEMPT_FIELDS);
+ ZenModeConfig.ZenRule.class, getZenRuleExemptFields());
generateFieldDiffs(r1, r2, fieldsForDiff, expectedFrom, expectedTo);
ZenModeDiff.RuleDiff d = new ZenModeDiff.RuleDiff(r1, r2);
@@ -158,6 +145,25 @@
}
}
+ private static Set<String> getZenRuleExemptFields() {
+ // "Metadata" fields are never compared.
+ Set<String> exemptFields = new LinkedHashSet<>(
+ Set.of("userModifiedFields", "zenPolicyUserModifiedFields",
+ "zenDeviceEffectsUserModifiedFields", "deletionInstant", "disabledOrigin"));
+ // Flagged fields are only compared if their flag is on.
+ if (!Flags.modesApi()) {
+ exemptFields.addAll(
+ Set.of(RuleDiff.FIELD_TYPE, RuleDiff.FIELD_TRIGGER_DESCRIPTION,
+ RuleDiff.FIELD_ICON_RES, RuleDiff.FIELD_ALLOW_MANUAL,
+ RuleDiff.FIELD_ZEN_DEVICE_EFFECTS,
+ RuleDiff.FIELD_LEGACY_SUPPRESSED_EFFECTS));
+ }
+ if (!(Flags.modesApi() && Flags.modesUi())) {
+ exemptFields.add(RuleDiff.FIELD_LEGACY_SUPPRESSED_EFFECTS);
+ }
+ return exemptFields;
+ }
+
@Test
public void testConfigDiff_addRemoveSame() {
// Default config, will test add, remove, and no change