summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Julia Reynolds <juliacr@google.com> 2023-12-05 17:02:52 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2023-12-05 17:02:52 +0000
commit2faf8430032cac0ac0d09989fe445b86b92a2a3c (patch)
treeeaef6d899ad7c9e7ff844edf1a94b51173a49ecd
parent6e42edd25e507411a74ff0bf9457089ed8b7053b (diff)
parent25cc875af2119c9ea32bd78fa17e24ba31faec30 (diff)
Merge "Store rule icon res name" into main
-rw-r--r--core/java/android/service/notification/ZenModeConfig.java19
-rw-r--r--core/java/android/service/notification/ZenModeDiff.java6
-rw-r--r--services/core/java/com/android/server/notification/ZenModeHelper.java53
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java10
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java2
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java61
6 files changed, 116 insertions, 35 deletions
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index c486b6a6a46e..f6128ea80c3b 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -683,7 +683,7 @@ public class ZenModeConfig implements Parcelable {
if (Flags.modesApi()) {
rt.zenDeviceEffects = readZenDeviceEffectsXml(parser);
rt.allowManualInvocation = safeBoolean(parser, RULE_ATT_ALLOW_MANUAL, false);
- rt.iconResId = safeInt(parser, RULE_ATT_ICON, 0);
+ rt.iconResName = parser.getAttributeValue(null, RULE_ATT_ICON);
rt.triggerDescription = parser.getAttributeValue(null, RULE_ATT_TRIGGER_DESC);
rt.type = safeInt(parser, RULE_ATT_TYPE, AutomaticZenRule.TYPE_UNKNOWN);
}
@@ -725,7 +725,9 @@ public class ZenModeConfig implements Parcelable {
out.attributeBoolean(null, RULE_ATT_MODIFIED, rule.modified);
if (Flags.modesApi()) {
out.attributeBoolean(null, RULE_ATT_ALLOW_MANUAL, rule.allowManualInvocation);
- out.attributeInt(null, RULE_ATT_ICON, rule.iconResId);
+ if (rule.iconResName != null) {
+ out.attribute(null, RULE_ATT_ICON, rule.iconResName);
+ }
if (rule.triggerDescription != null) {
out.attribute(null, RULE_ATT_TRIGGER_DESC, rule.triggerDescription);
}
@@ -1918,8 +1920,7 @@ public class ZenModeConfig implements Parcelable {
public String pkg;
public int type = AutomaticZenRule.TYPE_UNKNOWN;
public String triggerDescription;
- // TODO (b/308672670): switch to string res name
- public int iconResId;
+ public String iconResName;
public boolean allowManualInvocation;
public ZenRule() { }
@@ -1950,7 +1951,7 @@ public class ZenModeConfig implements Parcelable {
pkg = source.readString();
if (Flags.modesApi()) {
allowManualInvocation = source.readBoolean();
- iconResId = source.readInt();
+ iconResName = source.readString();
triggerDescription = source.readString();
type = source.readInt();
}
@@ -1997,7 +1998,7 @@ public class ZenModeConfig implements Parcelable {
dest.writeString(pkg);
if (Flags.modesApi()) {
dest.writeBoolean(allowManualInvocation);
- dest.writeInt(iconResId);
+ dest.writeString(iconResName);
dest.writeString(triggerDescription);
dest.writeInt(type);
}
@@ -2026,7 +2027,7 @@ public class ZenModeConfig implements Parcelable {
if (Flags.modesApi()) {
sb.append(",deviceEffects=").append(zenDeviceEffects)
.append(",allowManualInvocation=").append(allowManualInvocation)
- .append(",iconResId=").append(iconResId)
+ .append(",iconResName=").append(iconResName)
.append(",triggerDescription=").append(triggerDescription)
.append(",type=").append(type);
}
@@ -2085,7 +2086,7 @@ public class ZenModeConfig implements Parcelable {
return finalEquals
&& Objects.equals(other.zenDeviceEffects, zenDeviceEffects)
&& other.allowManualInvocation == allowManualInvocation
- && other.iconResId == iconResId
+ && Objects.equals(other.iconResName, iconResName)
&& Objects.equals(other.triggerDescription, triggerDescription)
&& other.type == type;
}
@@ -2098,7 +2099,7 @@ public class ZenModeConfig implements Parcelable {
if (Flags.modesApi()) {
return Objects.hash(enabled, snoozing, name, zenMode, conditionId, condition,
component, configurationActivity, pkg, id, enabler, zenPolicy,
- zenDeviceEffects, modified, allowManualInvocation, iconResId,
+ zenDeviceEffects, modified, allowManualInvocation, iconResName,
triggerDescription, type);
}
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 9538df1db43a..d87e75884802 100644
--- a/core/java/android/service/notification/ZenModeDiff.java
+++ b/core/java/android/service/notification/ZenModeDiff.java
@@ -464,7 +464,7 @@ public class ZenModeDiff {
public static final String FIELD_MODIFIED = "modified";
public static final String FIELD_PKG = "pkg";
public static final String FIELD_ALLOW_MANUAL = "allowManualInvocation";
- public static final String FIELD_ICON_RES = "iconResId";
+ public static final String FIELD_ICON_RES = "iconResName";
public static final String FIELD_TRIGGER_DESCRIPTION = "triggerDescription";
public static final String FIELD_TYPE = "type";
// NOTE: new field strings must match the variable names in ZenModeConfig.ZenRule
@@ -559,8 +559,8 @@ public class ZenModeDiff {
addField(FIELD_ALLOW_MANUAL,
new FieldDiff<>(from.allowManualInvocation, to.allowManualInvocation));
}
- if (!Objects.equals(from.iconResId, to.iconResId)) {
- addField(FIELD_ICON_RES, new FieldDiff<>(from.iconResId, to.iconResId));
+ if (!Objects.equals(from.iconResName, to.iconResName)) {
+ addField(FIELD_ICON_RES, new FieldDiff<>(from.iconResName, to.iconResName));
}
}
}
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index d0ded63162db..5c37eeaba180 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -28,6 +28,8 @@ import static android.service.notification.NotificationServiceProto.ROOT_CONFIG;
import static com.android.internal.util.FrameworkStatsLog.DND_MODE_RULE;
import android.annotation.IntDef;
+import android.annotation.DrawableRes;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.annotation.UserIdInt;
@@ -79,6 +81,7 @@ import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeConfig.ZenRule;
import android.service.notification.ZenModeProto;
import android.service.notification.ZenPolicy;
+import android.text.TextUtils;
import android.util.AndroidRuntimeException;
import android.util.ArrayMap;
import android.util.Log;
@@ -868,12 +871,13 @@ public class ZenModeHelper {
return null;
}
- private static void populateZenRule(String pkg, AutomaticZenRule automaticZenRule, ZenRule rule,
+ @VisibleForTesting
+ void populateZenRule(String pkg, AutomaticZenRule automaticZenRule, ZenRule rule,
boolean isNew, @ChangeOrigin int origin) {
- // TODO: b/308671593,b/311406021 - Handle origins more precisely:
- // - FROM_USER can override anything and updates bitmask of user-modified fields;
- // - FROM_SYSTEM_OR_SYSTEMUI can override anything and preserves bitmask;
- // - FROM_APP can only update if not user-modified.
+ // TODO: b/308671593,b/311406021 - Handle origins more precisely:
+ // - FROM_USER can override anything and updates bitmask of user-modified fields;
+ // - FROM_SYSTEM_OR_SYSTEMUI can override anything and preserves bitmask;
+ // - FROM_APP can only update if not user-modified.
if (rule.enabled != automaticZenRule.isEnabled()) {
rule.snoozing = false;
}
@@ -902,14 +906,14 @@ public class ZenModeHelper {
if (Flags.modesApi()) {
rule.allowManualInvocation = automaticZenRule.isManualInvocationAllowed();
- rule.iconResId = automaticZenRule.getIconResId();
+ rule.iconResName = drawableResIdToResName(rule.pkg, automaticZenRule.getIconResId());
rule.triggerDescription = automaticZenRule.getTriggerDescription();
rule.type = automaticZenRule.getType();
}
}
- /** "
- * Fix" {@link ZenDeviceEffects} that are being stored as part of a new or updated ZenRule.
+ /**
+ * Fix {@link ZenDeviceEffects} that are being stored as part of a new or updated ZenRule.
*
* <ul>
* <li> Apps cannot turn on hidden effects (those tagged as {@code @hide}) since they are
@@ -952,13 +956,13 @@ public class ZenModeHelper {
}
}
- private static AutomaticZenRule zenRuleToAutomaticZenRule(ZenRule rule) {
+ private AutomaticZenRule zenRuleToAutomaticZenRule(ZenRule rule) {
AutomaticZenRule azr;
if (Flags.modesApi()) {
azr = new AutomaticZenRule.Builder(rule.name, rule.conditionId)
.setManualInvocationAllowed(rule.allowManualInvocation)
.setCreationTime(rule.creationTime)
- .setIconResId(rule.iconResId)
+ .setIconResId(drawableResNameToResId(rule.pkg, rule.iconResName))
.setType(rule.type)
.setZenPolicy(rule.zenPolicy)
.setDeviceEffects(rule.zenDeviceEffects)
@@ -1942,6 +1946,35 @@ public class ZenModeHelper {
.build();
}
+ private int drawableResNameToResId(String packageName, String resourceName) {
+ if (TextUtils.isEmpty(resourceName)) {
+ return 0;
+ }
+ try {
+ final Resources res = mPm.getResourcesForApplication(packageName);
+ return res.getIdentifier(resourceName, null, null);
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.w(TAG, "cannot load rule icon for pkg", e);
+ }
+ return 0;
+ }
+
+ private String drawableResIdToResName(String packageName, @DrawableRes int resId) {
+ if (resId == 0) {
+ return null;
+ }
+ try {
+ final Resources res = mPm.getResourcesForApplication(packageName);
+ final String fullName = res.getResourceName(resId);
+
+ return fullName;
+ } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) {
+ Log.e(TAG, "Resource name for ID=" + resId + " not found in package " + packageName
+ + ". Resource IDs may change when the application is upgraded, and the system"
+ + " may not be able to find the correct resource.");
+ return null;
+ }
+ }
private final class Metrics extends Callback {
private static final String COUNTER_MODE_PREFIX = "dnd_mode_";
private static final String COUNTER_TYPE_PREFIX = "dnd_type_";
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 cad8bacab8e0..3185c50c27ef 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
@@ -75,7 +75,7 @@ public class ZenModeConfigTest extends UiServiceTestCase {
private final String TRIGGER_DESC = "Every Night, 10pm to 6am";
private final int TYPE = TYPE_BEDTIME;
private final boolean ALLOW_MANUAL = true;
- private final int ICON_RES_ID = 1234;
+ private final String ICON_RES_NAME = "icon_res";
private final int INTERRUPTION_FILTER = Settings.Global.ZEN_MODE_ALARMS;
private final boolean ENABLED = true;
private final int CREATION_TIME = 123;
@@ -347,7 +347,7 @@ public class ZenModeConfigTest extends UiServiceTestCase {
rule.allowManualInvocation = ALLOW_MANUAL;
rule.type = TYPE;
- rule.iconResId = ICON_RES_ID;
+ rule.iconResName = ICON_RES_NAME;
rule.triggerDescription = TRIGGER_DESC;
Parcel parcel = Parcel.obtain();
@@ -369,7 +369,7 @@ public class ZenModeConfigTest extends UiServiceTestCase {
assertEquals(rule.zenMode, parceled.zenMode);
assertEquals(rule.allowManualInvocation, parceled.allowManualInvocation);
- assertEquals(rule.iconResId, parceled.iconResId);
+ assertEquals(rule.iconResName, parceled.iconResName);
assertEquals(rule.type, parceled.type);
assertEquals(rule.triggerDescription, parceled.triggerDescription);
assertEquals(rule.zenPolicy, parceled.zenPolicy);
@@ -448,7 +448,7 @@ public class ZenModeConfigTest extends UiServiceTestCase {
rule.allowManualInvocation = ALLOW_MANUAL;
rule.type = TYPE;
- rule.iconResId = ICON_RES_ID;
+ rule.iconResName = ICON_RES_NAME;
rule.triggerDescription = TRIGGER_DESC;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -477,7 +477,7 @@ public class ZenModeConfigTest extends UiServiceTestCase {
assertEquals(rule.allowManualInvocation, fromXml.allowManualInvocation);
assertEquals(rule.type, fromXml.type);
assertEquals(rule.triggerDescription, fromXml.triggerDescription);
- assertEquals(rule.iconResId, fromXml.iconResId);
+ assertEquals(rule.iconResName, fromXml.iconResName);
}
@Test
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 4e684d0eb036..93cd44eb7966 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java
@@ -299,7 +299,7 @@ public class ZenModeDiffTest extends UiServiceTestCase {
if (android.app.Flags.modesApi()) {
rule.allowManualInvocation = true;
rule.type = AutomaticZenRule.TYPE_SCHEDULE_TIME;
- rule.iconResId = 123;
+ rule.iconResName = "res";
rule.triggerDescription = "At night";
rule.zenDeviceEffects = new ZenDeviceEffects.Builder()
.setShouldDimWallpaper(true)
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 4d25eaab1f49..b1fdec911d86 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -81,6 +81,7 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
@@ -192,8 +193,12 @@ public class ZenModeHelperTest extends UiServiceTestCase {
private static final String TRIGGER_DESC = "Every Night, 10pm to 6am";
private static final int TYPE = TYPE_BEDTIME;
private static final boolean ALLOW_MANUAL = true;
- private static final int ICON_RES_ID = 1234;
- private static final int INTERRUPTION_FILTER = Settings.Global.ZEN_MODE_ALARMS;
+ private static final String ICON_RES_NAME = "com.android.server.notification:drawable/res_name";
+ private static final int ICON_RES_ID = 123;
+ private static final int INTERRUPTION_FILTER_ZR = Settings.Global.ZEN_MODE_ALARMS;
+
+ private static final int INTERRUPTION_FILTER_AZR
+ = NotificationManager.INTERRUPTION_FILTER_ALARMS;
private static final boolean ENABLED = true;
private static final int CREATION_TIME = 123;
@@ -216,8 +221,10 @@ public class ZenModeHelperTest extends UiServiceTestCase {
MockitoAnnotations.initMocks(this);
mTestableLooper = TestableLooper.get(this);
+ mContext.ensureTestableResources();
mContentResolver = mContext.getContentResolver();
- mResources = spy(mContext.getResources());
+ mResources = mock(Resources.class, withSettings()
+ .spiedInstance(mContext.getResources()));
String pkg = mContext.getPackageName();
try {
when(mResources.getXml(R.xml.default_zen_mode_config)).thenReturn(
@@ -226,6 +233,10 @@ public class ZenModeHelperTest extends UiServiceTestCase {
Log.d("ZenModeHelperTest", "Couldn't mock default zen mode config xml file err=" +
e.toString());
}
+ when(mResources.getIdentifier(ICON_RES_NAME, null, null)).thenReturn(ICON_RES_ID);
+ when(mResources.getResourceName(ICON_RES_ID)).thenReturn(ICON_RES_NAME);
+ when(mPackageManager.getResourcesForApplication(anyString())).thenReturn(
+ mResources);
when(mContext.getSystemService(AppOpsManager.class)).thenReturn(mAppOps);
when(mContext.getSystemService(NotificationManager.class)).thenReturn(mNotificationManager);
@@ -3053,7 +3064,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
rule.enabled = ENABLED;
rule.creationTime = 123;
rule.id = "id";
- rule.zenMode = INTERRUPTION_FILTER;
+ rule.zenMode = INTERRUPTION_FILTER_ZR;
rule.modified = true;
rule.name = NAME;
rule.snoozing = true;
@@ -3062,7 +3073,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
rule.allowManualInvocation = ALLOW_MANUAL;
rule.type = TYPE;
- rule.iconResId = ICON_RES_ID;
+ rule.iconResName = ICON_RES_NAME;
rule.triggerDescription = TRIGGER_DESC;
mZenModeHelper.mConfig.automaticRules.put(rule.id, rule);
@@ -3071,8 +3082,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
assertEquals(NAME, actual.getName());
assertEquals(OWNER, actual.getOwner());
assertEquals(CONDITION_ID, actual.getConditionId());
- assertEquals(NotificationManager.INTERRUPTION_FILTER_ALARMS,
- actual.getInterruptionFilter());
+ assertEquals(INTERRUPTION_FILTER_AZR, actual.getInterruptionFilter());
assertEquals(ENABLED, actual.isEnabled());
assertEquals(POLICY, actual.getZenPolicy());
assertEquals(CONFIG_ACTIVITY, actual.getConfigurationActivity());
@@ -3085,6 +3095,43 @@ public class ZenModeHelperTest extends UiServiceTestCase {
}
@Test
+ public void automaticZenRuleToZenRule_allFields() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_MODES_API);
+ when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(
+ new String[] {OWNER.getPackageName()});
+
+ AutomaticZenRule azr = new AutomaticZenRule.Builder(NAME, CONDITION_ID)
+ .setEnabled(true)
+ .setConfigurationActivity(CONFIG_ACTIVITY)
+ .setTriggerDescription(TRIGGER_DESC)
+ .setCreationTime(CREATION_TIME)
+ .setIconResId(ICON_RES_ID)
+ .setZenPolicy(POLICY)
+ .setInterruptionFilter(INTERRUPTION_FILTER_AZR)
+ .setType(TYPE)
+ .setOwner(OWNER)
+ .setManualInvocationAllowed(ALLOW_MANUAL)
+ .build();
+
+ ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
+
+ mZenModeHelper.populateZenRule(OWNER.getPackageName(), azr, rule, true, FROM_APP);
+
+ assertEquals(NAME, rule.name);
+ assertEquals(OWNER, rule.component);
+ assertEquals(CONDITION_ID, rule.conditionId);
+ assertEquals(INTERRUPTION_FILTER_ZR, rule.zenMode);
+ assertEquals(ENABLED, rule.enabled);
+ assertEquals(POLICY, rule.zenPolicy);
+ assertEquals(CONFIG_ACTIVITY, rule.configurationActivity);
+ assertEquals(TYPE, rule.type);
+ assertEquals(ALLOW_MANUAL, rule.allowManualInvocation);
+ assertEquals(OWNER.getPackageName(), rule.getPkg());
+ assertEquals(ICON_RES_NAME, rule.iconResName);
+ assertEquals(TRIGGER_DESC, rule.triggerDescription);
+ }
+
+ @Test
public void testUpdateAutomaticRule_disabled_triggersBroadcast() throws Exception {
setupZenConfig();