summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Matías Hernández <matiashe@google.com> 2023-11-17 16:06:49 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2023-11-17 16:06:49 +0000
commit77d95dbc5f635bb3febb97601348ceaf25bf9fc7 (patch)
treeee1ac02d6b64a89cf4abcbd179983e8e6fc2a2d4
parent173f2b4d70b802e2fb11ced71c0cbbfc7d7b372d (diff)
parent18225951a4066f238bf1bcdc3ba9095814c0a9b6 (diff)
Merge "Save/load ZenDeviceEffects as part of ZenRule" into main
-rw-r--r--core/java/android/service/notification/ZenDeviceEffects.java10
-rw-r--r--core/java/android/service/notification/ZenModeConfig.java85
-rw-r--r--core/java/android/service/notification/ZenModeDiff.java35
-rw-r--r--services/core/java/com/android/server/notification/ZenModeHelper.java4
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenDeviceEffectsTest.java14
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java16
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java70
7 files changed, 207 insertions, 27 deletions
diff --git a/core/java/android/service/notification/ZenDeviceEffects.java b/core/java/android/service/notification/ZenDeviceEffects.java
index 5b096c641f78..db0b7ffa0913 100644
--- a/core/java/android/service/notification/ZenDeviceEffects.java
+++ b/core/java/android/service/notification/ZenDeviceEffects.java
@@ -178,6 +178,16 @@ public final class ZenDeviceEffects implements Parcelable {
return mMaximizeDoze;
}
+ /**
+ * Whether any of the effects are set up.
+ * @hide
+ */
+ public boolean hasEffects() {
+ return mGrayscale || mSuppressAmbientDisplay || mDimWallpaper || mNightMode
+ || mDisableAutoBrightness || mDisableTapToWake || mDisableTiltToWake
+ || mDisableTouch || mMinimizeRadioUsage || mMaximizeDoze;
+ }
+
/** {@link Parcelable.Creator} that instantiates {@link ZenDeviceEffects} objects. */
@NonNull
public static final Creator<ZenDeviceEffects> CREATOR = new Creator<ZenDeviceEffects>() {
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index fedad895961d..f1d35b5b1185 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -25,6 +25,7 @@ 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 android.annotation.FlaggedApi;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.AlarmManager;
@@ -185,6 +186,18 @@ public class ZenModeConfig implements Parcelable {
private static final String RULE_ATT_ICON = "rule_icon";
private static final String RULE_ATT_TRIGGER_DESC = "triggerDesc";
+ private static final String DEVICE_EFFECT_DISPLAY_GRAYSCALE = "zdeDisplayGrayscale";
+ private static final String DEVICE_EFFECT_SUPPRESS_AMBIENT_DISPLAY =
+ "zdeSuppressAmbientDisplay";
+ private static final String DEVICE_EFFECT_DIM_WALLPAPER = "zdeDimWallpaper";
+ private static final String DEVICE_EFFECT_USE_NIGHT_MODE = "zdeUseNightMode";
+ private static final String DEVICE_EFFECT_DISABLE_AUTO_BRIGHTNESS = "zdeDisableAutoBrightness";
+ private static final String DEVICE_EFFECT_DISABLE_TAP_TO_WAKE = "zdeDisableTapToWake";
+ private static final String DEVICE_EFFECT_DISABLE_TILT_TO_WAKE = "zdeDisableTiltToWake";
+ private static final String DEVICE_EFFECT_DISABLE_TOUCH = "zdeDisableTouch";
+ private static final String DEVICE_EFFECT_MINIMIZE_RADIO_USAGE = "zdeMinimizeRadioUsage";
+ private static final String DEVICE_EFFECT_MAXIMIZE_DOZE = "zdeMaximizeDoze";
+
@UnsupportedAppUsage
public boolean allowAlarms = DEFAULT_ALLOW_ALARMS;
public boolean allowMedia = DEFAULT_ALLOW_MEDIA;
@@ -630,6 +643,7 @@ public class ZenModeConfig implements Parcelable {
rt.modified = safeBoolean(parser, RULE_ATT_MODIFIED, false);
rt.zenPolicy = readZenPolicyXml(parser);
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.triggerDescription = parser.getAttributeValue(null, RULE_ATT_TRIGGER_DESC);
@@ -667,6 +681,9 @@ public class ZenModeConfig implements Parcelable {
if (rule.zenPolicy != null) {
writeZenPolicyXml(rule.zenPolicy, out);
}
+ if (Flags.modesApi() && rule.zenDeviceEffects != null) {
+ writeZenDeviceEffectsXml(rule.zenDeviceEffects, out);
+ }
out.attributeBoolean(null, RULE_ATT_MODIFIED, rule.modified);
if (Flags.modesApi()) {
out.attributeBoolean(null, RULE_ATT_ALLOW_MANUAL, rule.allowManualInvocation);
@@ -859,6 +876,57 @@ public class ZenModeConfig implements Parcelable {
}
}
+ @Nullable
+ private static ZenDeviceEffects readZenDeviceEffectsXml(TypedXmlPullParser parser) {
+ ZenDeviceEffects deviceEffects = new ZenDeviceEffects.Builder()
+ .setShouldDisplayGrayscale(
+ safeBoolean(parser, DEVICE_EFFECT_DISPLAY_GRAYSCALE, false))
+ .setShouldSuppressAmbientDisplay(
+ safeBoolean(parser, DEVICE_EFFECT_SUPPRESS_AMBIENT_DISPLAY, false))
+ .setShouldDimWallpaper(safeBoolean(parser, DEVICE_EFFECT_DIM_WALLPAPER, false))
+ .setShouldUseNightMode(safeBoolean(parser, DEVICE_EFFECT_USE_NIGHT_MODE, false))
+ .setShouldDisableAutoBrightness(
+ safeBoolean(parser, DEVICE_EFFECT_DISABLE_AUTO_BRIGHTNESS, false))
+ .setShouldDisableTapToWake(
+ safeBoolean(parser, DEVICE_EFFECT_DISABLE_TAP_TO_WAKE, false))
+ .setShouldDisableTiltToWake(
+ safeBoolean(parser, DEVICE_EFFECT_DISABLE_TILT_TO_WAKE, false))
+ .setShouldDisableTouch(safeBoolean(parser, DEVICE_EFFECT_DISABLE_TOUCH, false))
+ .setShouldMinimizeRadioUsage(
+ safeBoolean(parser, DEVICE_EFFECT_MINIMIZE_RADIO_USAGE, false))
+ .setShouldMaximizeDoze(safeBoolean(parser, DEVICE_EFFECT_MAXIMIZE_DOZE, false))
+ .build();
+
+ return deviceEffects.hasEffects() ? deviceEffects : null;
+ }
+
+ private static void writeZenDeviceEffectsXml(ZenDeviceEffects deviceEffects,
+ TypedXmlSerializer out) throws IOException {
+ writeBooleanIfTrue(out, DEVICE_EFFECT_DISPLAY_GRAYSCALE,
+ deviceEffects.shouldDisplayGrayscale());
+ writeBooleanIfTrue(out, DEVICE_EFFECT_SUPPRESS_AMBIENT_DISPLAY,
+ deviceEffects.shouldSuppressAmbientDisplay());
+ writeBooleanIfTrue(out, DEVICE_EFFECT_DIM_WALLPAPER, deviceEffects.shouldDimWallpaper());
+ writeBooleanIfTrue(out, DEVICE_EFFECT_USE_NIGHT_MODE, deviceEffects.shouldUseNightMode());
+ writeBooleanIfTrue(out, DEVICE_EFFECT_DISABLE_AUTO_BRIGHTNESS,
+ deviceEffects.shouldDisableAutoBrightness());
+ writeBooleanIfTrue(out, DEVICE_EFFECT_DISABLE_TAP_TO_WAKE,
+ deviceEffects.shouldDisableTapToWake());
+ writeBooleanIfTrue(out, DEVICE_EFFECT_DISABLE_TILT_TO_WAKE,
+ deviceEffects.shouldDisableTiltToWake());
+ writeBooleanIfTrue(out, DEVICE_EFFECT_DISABLE_TOUCH, deviceEffects.shouldDisableTouch());
+ writeBooleanIfTrue(out, DEVICE_EFFECT_MINIMIZE_RADIO_USAGE,
+ deviceEffects.shouldMinimizeRadioUsage());
+ writeBooleanIfTrue(out, DEVICE_EFFECT_MAXIMIZE_DOZE, deviceEffects.shouldMaximizeDoze());
+ }
+
+ private static void writeBooleanIfTrue(TypedXmlSerializer out, String att, boolean value)
+ throws IOException {
+ if (value) {
+ out.attributeBoolean(null, att, true);
+ }
+ }
+
public static boolean isValidHour(int val) {
return val >= 0 && val < 24;
}
@@ -1755,6 +1823,8 @@ public class ZenModeConfig implements Parcelable {
// package name, only used for manual rules when they have turned DND on.
public String enabler;
public ZenPolicy zenPolicy;
+ @FlaggedApi(Flags.FLAG_MODES_API)
+ @Nullable public ZenDeviceEffects zenDeviceEffects;
public boolean modified; // rule has been modified from initial creation
public String pkg;
public int type = AutomaticZenRule.TYPE_UNKNOWN;
@@ -1784,6 +1854,9 @@ public class ZenModeConfig implements Parcelable {
enabler = source.readString();
}
zenPolicy = source.readParcelable(null, android.service.notification.ZenPolicy.class);
+ if (Flags.modesApi()) {
+ zenDeviceEffects = source.readParcelable(null, ZenDeviceEffects.class);
+ }
modified = source.readInt() == 1;
pkg = source.readString();
if (Flags.modesApi()) {
@@ -1828,6 +1901,9 @@ public class ZenModeConfig implements Parcelable {
dest.writeInt(0);
}
dest.writeParcelable(zenPolicy, 0);
+ if (Flags.modesApi()) {
+ dest.writeParcelable(zenDeviceEffects, 0);
+ }
dest.writeInt(modified ? 1 : 0);
dest.writeString(pkg);
if (Flags.modesApi()) {
@@ -1859,7 +1935,8 @@ public class ZenModeConfig implements Parcelable {
.append(",condition=").append(condition);
if (Flags.modesApi()) {
- sb.append(",allowManualInvocation=").append(allowManualInvocation)
+ sb.append(",deviceEffects=").append(zenDeviceEffects)
+ .append(",allowManualInvocation=").append(allowManualInvocation)
.append(",iconResId=").append(iconResId)
.append(",triggerDescription=").append(triggerDescription)
.append(",type=").append(type);
@@ -1917,6 +1994,7 @@ public class ZenModeConfig implements Parcelable {
if (Flags.modesApi()) {
return finalEquals
+ && Objects.equals(other.zenDeviceEffects, zenDeviceEffects)
&& other.allowManualInvocation == allowManualInvocation
&& other.iconResId == iconResId
&& Objects.equals(other.triggerDescription, triggerDescription)
@@ -1930,8 +2008,9 @@ public class ZenModeConfig implements Parcelable {
public int hashCode() {
if (Flags.modesApi()) {
return Objects.hash(enabled, snoozing, name, zenMode, conditionId, condition,
- component, configurationActivity, pkg, id, enabler, zenPolicy, modified,
- allowManualInvocation, iconResId, triggerDescription, type);
+ component, configurationActivity, pkg, id, enabler, zenPolicy,
+ zenDeviceEffects, modified, allowManualInvocation, iconResId,
+ triggerDescription, type);
}
return Objects.hash(enabled, snoozing, name, zenMode, conditionId, condition,
component, configurationActivity, pkg, id, enabler, zenPolicy, modified);
diff --git a/core/java/android/service/notification/ZenModeDiff.java b/core/java/android/service/notification/ZenModeDiff.java
index eb55e40f2c7b..f345d7cb88fd 100644
--- a/core/java/android/service/notification/ZenModeDiff.java
+++ b/core/java/android/service/notification/ZenModeDiff.java
@@ -452,11 +452,12 @@ public class ZenModeDiff {
public static final String FIELD_CREATION_TIME = "creationTime";
public static final String FIELD_ENABLER = "enabler";
public static final String FIELD_ZEN_POLICY = "zenPolicy";
+ public static final String FIELD_ZEN_DEVICE_EFFECTS = "zenDeviceEffects";
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_TRIGGER = "triggerDescription";
+ 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
@@ -534,19 +535,25 @@ public class ZenModeDiff {
if (!Objects.equals(from.pkg, to.pkg)) {
addField(FIELD_PKG, new FieldDiff<>(from.pkg, to.pkg));
}
- if (!Objects.equals(from.triggerDescription, to.triggerDescription)) {
- addField(FIELD_TRIGGER,
- new FieldDiff<>(from.triggerDescription, to.triggerDescription));
- }
- if (from.type != to.type) {
- addField(FIELD_TYPE, new FieldDiff<>(from.type, to.type));
- }
- if (from.allowManualInvocation != to.allowManualInvocation) {
- 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 (android.app.Flags.modesApi()) {
+ if (!Objects.equals(from.zenDeviceEffects, to.zenDeviceEffects)) {
+ addField(FIELD_ZEN_DEVICE_EFFECTS,
+ new FieldDiff<>(from.zenDeviceEffects, to.zenDeviceEffects));
+ }
+ if (!Objects.equals(from.triggerDescription, to.triggerDescription)) {
+ addField(FIELD_TRIGGER_DESCRIPTION,
+ new FieldDiff<>(from.triggerDescription, to.triggerDescription));
+ }
+ if (from.type != to.type) {
+ addField(FIELD_TYPE, new FieldDiff<>(from.type, to.type));
+ }
+ if (from.allowManualInvocation != to.allowManualInvocation) {
+ 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));
+ }
}
}
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index a1704c6619ad..cb05084ea3f0 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -860,6 +860,9 @@ public class ZenModeHelper {
rule.enabled = automaticZenRule.isEnabled();
rule.modified = automaticZenRule.isModified();
rule.zenPolicy = automaticZenRule.getZenPolicy();
+ if (Flags.modesApi()) {
+ rule.zenDeviceEffects = automaticZenRule.getDeviceEffects();
+ }
rule.zenMode = NotificationManager.zenModeFromInterruptionFilter(
automaticZenRule.getInterruptionFilter(), Global.ZEN_MODE_OFF);
rule.configurationActivity = automaticZenRule.getConfigurationActivity();
@@ -888,6 +891,7 @@ public class ZenModeHelper {
.setIconResId(rule.iconResId)
.setType(rule.type)
.setZenPolicy(rule.zenPolicy)
+ .setDeviceEffects(rule.zenDeviceEffects)
.setEnabled(rule.enabled)
.setInterruptionFilter(
NotificationManager.zenModeToInterruptionFilter(rule.zenMode))
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenDeviceEffectsTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenDeviceEffectsTest.java
index 8dcf89bb8438..999e33c24322 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenDeviceEffectsTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenDeviceEffectsTest.java
@@ -102,4 +102,18 @@ public class ZenDeviceEffectsTest extends UiServiceTestCase {
assertThat(copy.shouldSuppressAmbientDisplay()).isTrue();
assertThat(copy.shouldDisplayGrayscale()).isFalse();
}
+
+ @Test
+ public void hasEffects_none_returnsFalse() {
+ ZenDeviceEffects effects = new ZenDeviceEffects.Builder().build();
+ assertThat(effects.hasEffects()).isFalse();
+ }
+
+ @Test
+ public void hasEffects_some_returnsTrue() {
+ ZenDeviceEffects effects = new ZenDeviceEffects.Builder()
+ .setShouldDimWallpaper(true)
+ .build();
+ assertThat(effects.hasEffects()).isTrue();
+ }
}
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 261b5d33b635..d4661075a552 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
@@ -33,6 +33,7 @@ import android.os.Parcel;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import android.service.notification.Condition;
+import android.service.notification.ZenDeviceEffects;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeConfig.EventInfo;
import android.service.notification.ZenPolicy;
@@ -327,7 +328,6 @@ public class ZenModeConfigTest extends UiServiceTestCase {
rule.conditionId = CONDITION_ID;
rule.condition = CONDITION;
rule.enabled = ENABLED;
- rule.creationTime = 123;
rule.id = "id";
rule.zenMode = INTERRUPTION_FILTER;
rule.modified = true;
@@ -335,6 +335,18 @@ public class ZenModeConfigTest extends UiServiceTestCase {
rule.snoozing = true;
rule.pkg = OWNER.getPackageName();
rule.zenPolicy = POLICY;
+ rule.zenDeviceEffects = new ZenDeviceEffects.Builder()
+ .setShouldDisplayGrayscale(false)
+ .setShouldSuppressAmbientDisplay(true)
+ .setShouldDimWallpaper(false)
+ .setShouldUseNightMode(true)
+ .setShouldDisableAutoBrightness(false)
+ .setShouldDisableTapToWake(true)
+ .setShouldDisableTiltToWake(false)
+ .setShouldDisableTouch(true)
+ .setShouldMinimizeRadioUsage(false)
+ .setShouldMaximizeDoze(true)
+ .build();
rule.creationTime = CREATION_TIME;
rule.allowManualInvocation = ALLOW_MANUAL;
@@ -362,6 +374,8 @@ public class ZenModeConfigTest extends UiServiceTestCase {
assertEquals(rule.name, fromXml.name);
assertEquals(rule.zenMode, fromXml.zenMode);
assertEquals(rule.creationTime, fromXml.creationTime);
+ assertEquals(rule.zenPolicy, fromXml.zenPolicy);
+ assertEquals(rule.zenDeviceEffects, fromXml.zenDeviceEffects);
assertEquals(rule.allowManualInvocation, fromXml.allowManualInvocation);
assertEquals(rule.type, fromXml.type);
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 fd3d5e9bf863..ed7e8ae5c6e5 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java
@@ -16,6 +16,8 @@
package com.android.server.notification;
+import static com.google.common.truth.Truth.assertThat;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
@@ -28,8 +30,10 @@ import android.content.ComponentName;
import android.net.Uri;
import android.provider.Settings;
import android.service.notification.Condition;
+import android.service.notification.ZenDeviceEffects;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeDiff;
+import android.service.notification.ZenModeDiff.RuleDiff;
import android.service.notification.ZenPolicy;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -42,10 +46,14 @@ import com.android.server.UiServiceTestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
+import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
+import java.util.Optional;
import java.util.Set;
@SmallTest
@@ -56,6 +64,15 @@ public class ZenModeDiffTest extends UiServiceTestCase {
public static final Set<String> ZEN_MODE_CONFIG_EXEMPT_FIELDS =
Set.of("version", "manualRule", "automaticRules");
+ // Differences for flagged fields are only generated if the flag is enabled.
+ // TODO: b/310620812 - Remove this exempt list when flag is inlined.
+ private static final Set<String> ZEN_RULE_EXEMPT_FIELDS =
+ android.app.Flags.modesApi()
+ ? Set.of()
+ : Set.of(RuleDiff.FIELD_TYPE, RuleDiff.FIELD_TRIGGER_DESCRIPTION,
+ RuleDiff.FIELD_ICON_RES, RuleDiff.FIELD_ALLOW_MANUAL,
+ RuleDiff.FIELD_ZEN_DEVICE_EFFECTS);
+
@Test
public void testRuleDiff_addRemoveSame() {
// Test add, remove, and both sides same
@@ -86,7 +103,7 @@ public class ZenModeDiffTest extends UiServiceTestCase {
ArrayMap<String, Object> expectedFrom = new ArrayMap<>();
ArrayMap<String, Object> expectedTo = new ArrayMap<>();
List<Field> fieldsForDiff = getFieldsForDiffCheck(
- ZenModeConfig.ZenRule.class, Set.of()); // actually no exempt fields for ZenRule
+ ZenModeConfig.ZenRule.class, ZEN_RULE_EXEMPT_FIELDS);
generateFieldDiffs(r1, r2, fieldsForDiff, expectedFrom, expectedTo);
ZenModeDiff.RuleDiff d = new ZenModeDiff.RuleDiff(r1, r2);
@@ -230,16 +247,21 @@ public class ZenModeDiffTest extends UiServiceTestCase {
rule.name = "name";
rule.snoozing = true;
rule.pkg = "a";
- rule.allowManualInvocation = true;
- rule.type = AutomaticZenRule.TYPE_SCHEDULE_TIME;
- rule.iconResId = 123;
- rule.triggerDescription = "At night";
+ if (android.app.Flags.modesApi()) {
+ rule.allowManualInvocation = true;
+ rule.type = AutomaticZenRule.TYPE_SCHEDULE_TIME;
+ rule.iconResId = 123;
+ rule.triggerDescription = "At night";
+ rule.zenDeviceEffects = new ZenDeviceEffects.Builder()
+ .setShouldDimWallpaper(true)
+ .build();
+ }
return rule;
}
// Get the fields on which we would want to check a diff. The requirements are: not final or/
// static (as these should/can never change), and not in a specific list that's exempted.
- private List<Field> getFieldsForDiffCheck(Class c, Set<String> exemptNames)
+ private List<Field> getFieldsForDiffCheck(Class<?> c, Set<String> exemptNames)
throws SecurityException {
Field[] fields = c.getDeclaredFields();
ArrayList<Field> out = new ArrayList<>();
@@ -272,7 +294,7 @@ public class ZenModeDiffTest extends UiServiceTestCase {
f.setAccessible(true);
// Just double-check also that the fields actually are for the class declared
assertEquals(f.getDeclaringClass(), a.getClass());
- Class t = f.getType();
+ Class<?> t = f.getType();
// handle the full set of primitive types first
if (boolean.class.equals(t)) {
f.setBoolean(a, true);
@@ -305,8 +327,8 @@ public class ZenModeDiffTest extends UiServiceTestCase {
f.set(a, null);
expectedA.put(f.getName(), null);
try {
- f.set(b, t.getDeclaredConstructor().newInstance());
- expectedB.put(f.getName(), t.getDeclaredConstructor().newInstance());
+ f.set(b, newInstanceOf(t));
+ expectedB.put(f.getName(), newInstanceOf(t));
} catch (Exception e) {
// No default constructor, or blithely attempting to construct something doesn't
// work for some reason. If the default value isn't null, then keep it.
@@ -321,4 +343,34 @@ public class ZenModeDiffTest extends UiServiceTestCase {
}
}
}
+
+ private static Object newInstanceOf(Class<?> clazz) throws ReflectiveOperationException {
+ try {
+ Constructor<?> defaultConstructor = clazz.getDeclaredConstructor();
+ return defaultConstructor.newInstance();
+ } catch (Exception e) {
+ // No default constructor, continue below.
+ }
+
+ // Look for a suitable builder.
+ Optional<Class<?>> clazzBuilder =
+ Arrays.stream(clazz.getDeclaredClasses())
+ .filter(maybeBuilder -> maybeBuilder.getSimpleName().equals("Builder"))
+ .filter(maybeBuilder ->
+ Arrays.stream(maybeBuilder.getMethods()).anyMatch(
+ m -> m.getName().equals("build")
+ && m.getParameterCount() == 0
+ && m.getReturnType().equals(clazz)))
+ .findFirst();
+ if (clazzBuilder.isPresent()) {
+ Object builder = newInstanceOf(clazzBuilder.get());
+ Method buildMethod = builder.getClass().getMethod("build");
+ Object built = buildMethod.invoke(builder);
+ assertThat(built).isInstanceOf(clazz);
+ return built;
+ }
+
+ throw new ReflectiveOperationException(
+ "Sorry! Couldn't figure out how to create an instance of " + clazz.getName());
+ }
}