diff options
| author | 2023-11-23 16:46:50 +0000 | |
|---|---|---|
| committer | 2023-11-23 16:46:50 +0000 | |
| commit | 123cbf80b1a850a5022b86869522b093f9db2fbb (patch) | |
| tree | 6ba7be084b994da26b3b6aface62b9ec08836ec6 | |
| parent | 529f64a2d0d4f13a268ba7f022227601974b5613 (diff) | |
| parent | 62bf63573a0a9d04955caf0162de27e579f73fb6 (diff) | |
Merge "Prevent apps from supplying non-public ZenDeviceEffects" into main
4 files changed, 319 insertions, 63 deletions
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 1b640fcb7e20..2707b4502f54 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -1765,8 +1765,7 @@ public class NotificationManagerService extends SystemService { if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) { // update system notification channels SystemNotificationChannels.createAll(context); - mZenModeHelper.updateDefaultZenRules(Binder.getCallingUid(), - isCallerIsSystemOrSystemUi()); + mZenModeHelper.updateDefaultZenRules(Binder.getCallingUid()); mPreferencesHelper.onLocaleChanged(context, ActivityManager.getCurrentUser()); } } @@ -5316,7 +5315,9 @@ public class NotificationManagerService extends SystemService { return mZenModeHelper.addAutomaticZenRule(rulePkg, automaticZenRule, "addAutomaticZenRule", Binder.getCallingUid(), - isCallerIsSystemOrSystemUi()); + // TODO: b/308670715: Distinguish FROM_APP from FROM_USER + isCallerIsSystemOrSystemUi() ? ZenModeHelper.FROM_SYSTEM_OR_SYSTEMUI + : ZenModeHelper.FROM_APP); } @Override @@ -5334,7 +5335,9 @@ public class NotificationManagerService extends SystemService { return mZenModeHelper.updateAutomaticZenRule(id, automaticZenRule, "updateAutomaticZenRule", Binder.getCallingUid(), - isCallerIsSystemOrSystemUi()); + // TODO: b/308670715: Distinguish FROM_APP from FROM_USER + isCallerIsSystemOrSystemUi() ? ZenModeHelper.FROM_SYSTEM_OR_SYSTEMUI + : ZenModeHelper.FROM_APP); } @Override diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index 2ef0ca64c9d6..89d820050b03 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -27,6 +27,7 @@ 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.Nullable; import android.annotation.SuppressLint; import android.annotation.UserIdInt; @@ -73,6 +74,7 @@ import android.provider.Settings; import android.provider.Settings.Global; import android.service.notification.Condition; import android.service.notification.ConditionProviderService; +import android.service.notification.ZenDeviceEffects; import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig.ZenRule; import android.service.notification.ZenModeProto; @@ -105,6 +107,8 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.io.PrintWriter; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -129,6 +133,21 @@ public class ZenModeHelper { @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM) static final long SEND_ACTIVATION_AZR_STATUSES = 308673617L; + /** A rule addition or update that is initiated by the System or SystemUI. */ + static final int FROM_SYSTEM_OR_SYSTEMUI = 1; + /** A rule addition or update that is initiated by the user (through system settings). */ + static final int FROM_USER = 2; + /** A rule addition or update that is initiated by an app (via NotificationManager APIs). */ + static final int FROM_APP = 3; + + @IntDef(prefix = { "FROM_" }, value = { + FROM_SYSTEM_OR_SYSTEMUI, + FROM_USER, + FROM_APP + }) + @Retention(RetentionPolicy.SOURCE) + @interface ChangeOrigin {} + // pkg|userId => uid @VisibleForTesting protected final ArrayMap<String, Integer> mRulesUidCache = new ArrayMap<>(); @@ -378,7 +397,7 @@ public class ZenModeHelper { } public String addAutomaticZenRule(String pkg, AutomaticZenRule automaticZenRule, - String reason, int callingUid, boolean fromSystemOrSystemUi) { + String reason, int callingUid, @ChangeOrigin int origin) { if (!ZenModeConfig.SYSTEM_AUTHORITY.equals(pkg)) { PackageItemInfo component = getServiceInfo(automaticZenRule.getOwner()); if (component == null) { @@ -412,10 +431,10 @@ public class ZenModeHelper { } newConfig = mConfig.copy(); ZenRule rule = new ZenRule(); - populateZenRule(pkg, automaticZenRule, rule, true); + populateZenRule(pkg, automaticZenRule, rule, true, origin); newConfig.automaticRules.put(rule.id, rule); if (setConfigLocked(newConfig, reason, rule.component, true, callingUid, - fromSystemOrSystemUi)) { + origin == FROM_SYSTEM_OR_SYSTEMUI)) { return rule.id; } else { throw new AndroidRuntimeException("Could not create rule"); @@ -424,7 +443,7 @@ public class ZenModeHelper { } public boolean updateAutomaticZenRule(String ruleId, AutomaticZenRule automaticZenRule, - String reason, int callingUid, boolean fromSystemOrSystemUi) { + String reason, int callingUid, @ChangeOrigin int origin) { ZenModeConfig newConfig; synchronized (mConfigLock) { if (mConfig == null) return false; @@ -452,9 +471,9 @@ public class ZenModeHelper { } } - populateZenRule(rule.pkg, automaticZenRule, rule, false); + populateZenRule(rule.pkg, automaticZenRule, rule, false, origin); return setConfigLocked(newConfig, reason, rule.component, true, callingUid, - fromSystemOrSystemUi); + origin == FROM_SYSTEM_OR_SYSTEMUI); } } @@ -790,7 +809,7 @@ public class ZenModeHelper { } } - protected void updateDefaultZenRules(int callingUid, boolean fromSystemOrSystemUi) { + protected void updateDefaultZenRules(int callingUid) { updateDefaultAutomaticRuleNames(); synchronized (mConfigLock) { for (ZenRule defaultRule : mDefaultConfig.automaticRules.values()) { @@ -807,7 +826,7 @@ public class ZenModeHelper { // update default rule (if locale changed, name of rule will change) currRule.name = defaultRule.name; updateAutomaticZenRule(defaultRule.id, zenRuleToAutomaticZenRule(currRule), - "locale changed", callingUid, fromSystemOrSystemUi); + "locale changed", callingUid, FROM_SYSTEM_OR_SYSTEMUI); } } } @@ -850,7 +869,11 @@ public class ZenModeHelper { } private static void populateZenRule(String pkg, AutomaticZenRule automaticZenRule, ZenRule rule, - boolean isNew) { + 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. if (rule.enabled != automaticZenRule.isEnabled()) { rule.snoozing = false; } @@ -861,7 +884,10 @@ public class ZenModeHelper { rule.modified = automaticZenRule.isModified(); rule.zenPolicy = automaticZenRule.getZenPolicy(); if (Flags.modesApi()) { - rule.zenDeviceEffects = automaticZenRule.getDeviceEffects(); + rule.zenDeviceEffects = fixZenDeviceEffects( + rule.zenDeviceEffects, + automaticZenRule.getDeviceEffects(), + origin); } rule.zenMode = NotificationManager.zenModeFromInterruptionFilter( automaticZenRule.getInterruptionFilter(), Global.ZEN_MODE_OFF); @@ -882,6 +908,50 @@ public class ZenModeHelper { } } + /** " + * 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 + * intended for platform-specific rules (e.g. wearables). If it's a new rule, we blank them + * out; if it's an update, we preserve the previous values. + * </ul> + */ + @Nullable + private static ZenDeviceEffects fixZenDeviceEffects(@Nullable ZenDeviceEffects oldEffects, + @Nullable ZenDeviceEffects newEffects, @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. + if (origin == FROM_SYSTEM_OR_SYSTEMUI || origin == FROM_USER) { + return newEffects; + } + + if (newEffects == null) { + return null; + } + if (oldEffects != null) { + return new ZenDeviceEffects.Builder(newEffects) + .setShouldDisableAutoBrightness(oldEffects.shouldDisableAutoBrightness()) + .setShouldDisableTapToWake(oldEffects.shouldDisableTapToWake()) + .setShouldDisableTiltToWake(oldEffects.shouldDisableTiltToWake()) + .setShouldDisableTouch(oldEffects.shouldDisableTouch()) + .setShouldMinimizeRadioUsage(oldEffects.shouldMinimizeRadioUsage()) + .setShouldMaximizeDoze(oldEffects.shouldMaximizeDoze()) + .build(); + } else { + return new ZenDeviceEffects.Builder(newEffects) + .setShouldDisableAutoBrightness(false) + .setShouldDisableTapToWake(false) + .setShouldDisableTiltToWake(false) + .setShouldDisableTouch(false) + .setShouldMinimizeRadioUsage(false) + .setShouldMaximizeDoze(false) + .build(); + } + } + private static AutomaticZenRule zenRuleToAutomaticZenRule(ZenRule rule) { AutomaticZenRule azr; if (Flags.modesApi()) { diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index b45dcd4d5403..09ffe71a6758 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -241,7 +241,6 @@ import androidx.test.InstrumentationRegistry; import com.android.internal.R; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; -import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.Flag; import com.android.internal.config.sysui.TestableFlagResolver; import com.android.internal.logging.InstanceIdSequence; import com.android.internal.logging.InstanceIdSequenceFake; @@ -5296,7 +5295,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { new Intent(Intent.ACTION_LOCALE_CHANGED)); verify(mZenModeHelper, times(1)).updateDefaultZenRules( - anyInt(), anyBoolean()); + anyInt()); } @Test @@ -8752,7 +8751,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // verify that zen mode helper gets passed in a package name of "android" verify(mockZenModeHelper).addAutomaticZenRule(eq("android"), eq(rule), anyString(), - anyInt(), eq(true)); // system call counts as "is system or system ui" + anyInt(), eq(ZenModeHelper.FROM_SYSTEM_OR_SYSTEMUI)); // system call } @Test @@ -8774,7 +8773,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // verify that zen mode helper gets passed in a package name of "android" verify(mockZenModeHelper).addAutomaticZenRule(eq("android"), eq(rule), anyString(), - anyInt(), eq(true)); // system call counts as "system or system ui" + anyInt(), eq(ZenModeHelper.FROM_SYSTEM_OR_SYSTEMUI)); // system call } @Test @@ -8795,7 +8794,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // verify that zen mode helper gets passed in the package name from the arg, not the owner verify(mockZenModeHelper).addAutomaticZenRule( eq("another.package"), eq(rule), anyString(), anyInt(), - eq(false)); // doesn't count as a system/systemui call + eq(ZenModeHelper.FROM_APP)); // doesn't count as a system/systemui call } @Test 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 0313aaa6e3a7..97b6b98a0b08 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java @@ -53,6 +53,9 @@ import static com.android.os.dnd.DNDProtoEnums.PEOPLE_STARRED; import static com.android.os.dnd.DNDProtoEnums.ROOT_CONFIG; 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.FROM_APP; +import static com.android.server.notification.ZenModeHelper.FROM_SYSTEM_OR_SYSTEMUI; +import static com.android.server.notification.ZenModeHelper.FROM_USER; import static com.android.server.notification.ZenModeHelper.RULE_LIMIT_PER_PACKAGE; import static com.google.common.truth.Truth.assertThat; @@ -108,6 +111,7 @@ import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; import android.provider.Settings.Global; import android.service.notification.Condition; +import android.service.notification.ZenDeviceEffects; import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig.ScheduleInfo; import android.service.notification.ZenModeConfig.ZenRule; @@ -1645,8 +1649,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { ZenModeConfig config = new ZenModeConfig(); config.automaticRules = new ArrayMap<>(); mZenModeHelper.mConfig = config; - mZenModeHelper.updateDefaultZenRules( - Process.SYSTEM_UID, true); // shouldn't throw null pointer + mZenModeHelper.updateDefaultZenRules(Process.SYSTEM_UID); // shouldn't throw null pointer mZenModeHelper.pullRules(events); // shouldn't throw null pointer } @@ -1671,7 +1674,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { autoRules.put(SCHEDULE_DEFAULT_RULE_ID, updatedDefaultRule); mZenModeHelper.mConfig.automaticRules = autoRules; - mZenModeHelper.updateDefaultZenRules(Process.SYSTEM_UID, true); + mZenModeHelper.updateDefaultZenRules(Process.SYSTEM_UID); assertEquals(updatedDefaultRule, mZenModeHelper.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID)); } @@ -1697,7 +1700,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { autoRules.put(SCHEDULE_DEFAULT_RULE_ID, updatedDefaultRule); mZenModeHelper.mConfig.automaticRules = autoRules; - mZenModeHelper.updateDefaultZenRules(Process.SYSTEM_UID, true); + mZenModeHelper.updateDefaultZenRules(Process.SYSTEM_UID); assertEquals(updatedDefaultRule, mZenModeHelper.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID)); } @@ -1724,7 +1727,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { autoRules.put(SCHEDULE_DEFAULT_RULE_ID, customDefaultRule); mZenModeHelper.mConfig.automaticRules = autoRules; - mZenModeHelper.updateDefaultZenRules(Process.SYSTEM_UID, true); + mZenModeHelper.updateDefaultZenRules(Process.SYSTEM_UID); ZenModeConfig.ZenRule ruleAfterUpdating = mZenModeHelper.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID); assertEquals(customDefaultRule.enabled, ruleAfterUpdating.enabled); @@ -1748,7 +1751,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { // We need the package name to be something that's not "android" so there aren't any // existing rules under that package. String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test", - CUSTOM_PKG_UID, false); + CUSTOM_PKG_UID, FROM_APP); assertNotNull(id); } try { @@ -1759,7 +1762,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test", - CUSTOM_PKG_UID, false); + CUSTOM_PKG_UID, FROM_APP); fail("allowed too many rules to be created"); } catch (IllegalArgumentException e) { // yay @@ -1780,7 +1783,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test", - CUSTOM_PKG_UID, false); + CUSTOM_PKG_UID, FROM_APP); assertNotNull(id); } try { @@ -1791,7 +1794,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test", - CUSTOM_PKG_UID, false); + CUSTOM_PKG_UID, FROM_APP); fail("allowed too many rules to be created"); } catch (IllegalArgumentException e) { // yay @@ -1812,7 +1815,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test", - CUSTOM_PKG_UID, false); + CUSTOM_PKG_UID, FROM_APP); assertNotNull(id); } try { @@ -1823,7 +1826,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test", - CUSTOM_PKG_UID, false); + CUSTOM_PKG_UID, FROM_APP); fail("allowed too many rules to be created"); } catch (IllegalArgumentException e) { // yay @@ -1839,7 +1842,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test", - Process.SYSTEM_UID, true); + Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); assertTrue(id != null); ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id); @@ -1860,7 +1863,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { ZenModeConfig.toScheduleConditionId(new ScheduleInfo()), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test", - Process.SYSTEM_UID, true); + Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); assertTrue(id != null); ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id); @@ -1884,7 +1887,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test", - CUSTOM_PKG_UID, false); + CUSTOM_PKG_UID, FROM_APP); mZenModeHelper.setAutomaticZenRuleState(zenRule.getConditionId(), new Condition(zenRule.getConditionId(), "", STATE_TRUE), CUSTOM_PKG_UID, false); @@ -1903,7 +1906,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test", - CUSTOM_PKG_UID, false); + CUSTOM_PKG_UID, FROM_APP); AutomaticZenRule zenRule2 = new AutomaticZenRule("NEW", null, @@ -1912,7 +1915,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); - mZenModeHelper.updateAutomaticZenRule(id, zenRule2, "", CUSTOM_PKG_UID, false); + mZenModeHelper.updateAutomaticZenRule(id, zenRule2, "", CUSTOM_PKG_UID, FROM_APP); ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id); assertEquals("NEW", ruleInConfig.name); @@ -1928,7 +1931,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test", - CUSTOM_PKG_UID, false); + CUSTOM_PKG_UID, FROM_APP); assertTrue(id != null); ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id); @@ -1948,7 +1951,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test", - CUSTOM_PKG_UID, false); + CUSTOM_PKG_UID, FROM_APP); assertTrue(id != null); ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id); @@ -1972,13 +1975,13 @@ public class ZenModeHelperTest extends UiServiceTestCase { sharedUri, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test", - Process.SYSTEM_UID, true); + Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); AutomaticZenRule zenRule2 = new AutomaticZenRule("name2", new ComponentName("android", "ScheduleConditionProvider"), sharedUri, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id2 = mZenModeHelper.addAutomaticZenRule("android", zenRule2, "test", - Process.SYSTEM_UID, true); + Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); Condition condition = new Condition(sharedUri, "", STATE_TRUE); mZenModeHelper.setAutomaticZenRuleState(sharedUri, condition, Process.SYSTEM_UID, true); @@ -2010,6 +2013,182 @@ public class ZenModeHelperTest extends UiServiceTestCase { } @Test + public void addAutomaticZenRule_fromApp_ignoresHiddenEffects() { + mSetFlagsRule.enableFlags(Flags.FLAG_MODES_API); + + ZenDeviceEffects zde = new ZenDeviceEffects.Builder() + .setShouldDisplayGrayscale(true) + .setShouldSuppressAmbientDisplay(true) + .setShouldDimWallpaper(true) + .setShouldUseNightMode(true) + .setShouldDisableAutoBrightness(true) + .setShouldDisableTapToWake(true) + .setShouldDisableTiltToWake(true) + .setShouldDisableTouch(true) + .setShouldMinimizeRadioUsage(true) + .setShouldMaximizeDoze(true) + .build(); + + String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), + new AutomaticZenRule.Builder("Rule", CONDITION_ID) + .setOwner(OWNER) + .setDeviceEffects(zde) + .build(), + "reasons", 0, FROM_APP); + + AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(ruleId); + assertThat(savedRule.getDeviceEffects()).isEqualTo( + new ZenDeviceEffects.Builder() + .setShouldDisplayGrayscale(true) + .setShouldSuppressAmbientDisplay(true) + .setShouldDimWallpaper(true) + .setShouldUseNightMode(true) + .build()); + } + + @Test + public void addAutomaticZenRule_fromSystem_respectsHiddenEffects() { + mSetFlagsRule.enableFlags(Flags.FLAG_MODES_API); + + ZenDeviceEffects zde = new ZenDeviceEffects.Builder() + .setShouldDisplayGrayscale(true) + .setShouldSuppressAmbientDisplay(true) + .setShouldDimWallpaper(true) + .setShouldUseNightMode(true) + .setShouldDisableAutoBrightness(true) + .setShouldDisableTapToWake(true) + .setShouldDisableTiltToWake(true) + .setShouldDisableTouch(true) + .setShouldMinimizeRadioUsage(true) + .setShouldMaximizeDoze(true) + .build(); + + String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), + new AutomaticZenRule.Builder("Rule", CONDITION_ID) + .setOwner(OWNER) + .setDeviceEffects(zde) + .build(), + "reasons", 0, FROM_SYSTEM_OR_SYSTEMUI); + + AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(ruleId); + assertThat(savedRule.getDeviceEffects()).isEqualTo(zde); + } + + @Test + public void addAutomaticZenRule_fromUser_respectsHiddenEffects() { + mSetFlagsRule.enableFlags(Flags.FLAG_MODES_API); + + ZenDeviceEffects zde = new ZenDeviceEffects.Builder() + .setShouldDisplayGrayscale(true) + .setShouldSuppressAmbientDisplay(true) + .setShouldDimWallpaper(true) + .setShouldUseNightMode(true) + .setShouldDisableAutoBrightness(true) + .setShouldDisableTapToWake(true) + .setShouldDisableTiltToWake(true) + .setShouldDisableTouch(true) + .setShouldMinimizeRadioUsage(true) + .setShouldMaximizeDoze(true) + .build(); + + String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), + new AutomaticZenRule.Builder("Rule", CONDITION_ID) + .setOwner(OWNER) + .setDeviceEffects(zde) + .build(), + "reasons", 0, FROM_USER); + + AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(ruleId); + assertThat(savedRule.getDeviceEffects()).isEqualTo(zde); + } + + @Test + public void updateAutomaticZenRule_fromApp_preservesPreviousHiddenEffects() { + mSetFlagsRule.enableFlags(Flags.FLAG_MODES_API); + ZenDeviceEffects original = new ZenDeviceEffects.Builder() + .setShouldDisableTapToWake(true) + .build(); + String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), + new AutomaticZenRule.Builder("Rule", CONDITION_ID) + .setOwner(OWNER) + .setDeviceEffects(original) + .build(), + "reasons", 0, FROM_SYSTEM_OR_SYSTEMUI); + + ZenDeviceEffects updateFromApp = new ZenDeviceEffects.Builder() + .setShouldUseNightMode(true) // Good + .setShouldMaximizeDoze(true) // Bad + .build(); + mZenModeHelper.updateAutomaticZenRule(ruleId, + new AutomaticZenRule.Builder("Rule", CONDITION_ID) + .setOwner(OWNER) + .setDeviceEffects(updateFromApp) + .build(), + "reasons", 0, FROM_APP); + + AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(ruleId); + assertThat(savedRule.getDeviceEffects()).isEqualTo( + new ZenDeviceEffects.Builder() + .setShouldUseNightMode(true) // From update. + .setShouldDisableTapToWake(true) // From original. + .build()); + } + + @Test + public void updateAutomaticZenRule_fromSystem_updatesHiddenEffects() { + mSetFlagsRule.enableFlags(Flags.FLAG_MODES_API); + ZenDeviceEffects original = new ZenDeviceEffects.Builder() + .setShouldDisableTapToWake(true) + .build(); + String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), + new AutomaticZenRule.Builder("Rule", CONDITION_ID) + .setOwner(OWNER) + .setDeviceEffects(original) + .build(), + "reasons", 0, FROM_SYSTEM_OR_SYSTEMUI); + + ZenDeviceEffects updateFromSystem = new ZenDeviceEffects.Builder() + .setShouldUseNightMode(true) // Good + .setShouldMaximizeDoze(true) // Also good + .build(); + mZenModeHelper.updateAutomaticZenRule(ruleId, + new AutomaticZenRule.Builder("Rule", CONDITION_ID) + .setDeviceEffects(updateFromSystem) + .build(), + "reasons", 0, FROM_SYSTEM_OR_SYSTEMUI); + + AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(ruleId); + assertThat(savedRule.getDeviceEffects()).isEqualTo(updateFromSystem); + } + + @Test + public void updateAutomaticZenRule_fromUser_updatesHiddenEffects() { + mSetFlagsRule.enableFlags(Flags.FLAG_MODES_API); + ZenDeviceEffects original = new ZenDeviceEffects.Builder() + .setShouldDisableTapToWake(true) + .build(); + String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), + new AutomaticZenRule.Builder("Rule", CONDITION_ID) + .setOwner(OWNER) + .setDeviceEffects(original) + .build(), + "reasons", 0, FROM_SYSTEM_OR_SYSTEMUI); + + ZenDeviceEffects updateFromUser = new ZenDeviceEffects.Builder() + .setShouldUseNightMode(true) // Good + .setShouldMaximizeDoze(true) // Also good + .build(); + mZenModeHelper.updateAutomaticZenRule(ruleId, + new AutomaticZenRule.Builder("Rule", CONDITION_ID) + .setDeviceEffects(updateFromUser) + .build(), + "reasons", 0, FROM_USER); + + AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(ruleId); + assertThat(savedRule.getDeviceEffects()).isEqualTo(updateFromUser); + } + + @Test public void testSetManualZenMode() { mSetFlagsRule.enableFlags(Flags.FLAG_MODES_API); setupZenConfig(); @@ -2119,7 +2298,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, - "test", Process.SYSTEM_UID, true); + "test", Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); // Event 1: Mimic the rule coming on automatically by setting the Condition to STATE_TRUE mZenModeHelper.setAutomaticZenRuleState(id, @@ -2128,7 +2307,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { // Event 2: "User" turns off the automatic rule (sets it to not enabled) zenRule.setEnabled(false); - mZenModeHelper.updateAutomaticZenRule(id, zenRule, "", Process.SYSTEM_UID, true); + mZenModeHelper.updateAutomaticZenRule(id, zenRule, "", Process.SYSTEM_UID, + FROM_SYSTEM_OR_SYSTEMUI); // Add a new system rule AutomaticZenRule systemRule = new AutomaticZenRule("systemRule", @@ -2138,7 +2318,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String systemId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), systemRule, - "test", Process.SYSTEM_UID, true); + "test", Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); // Event 3: turn on the system rule mZenModeHelper.setAutomaticZenRuleState(systemId, @@ -2270,7 +2450,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, "test", - Process.SYSTEM_UID, true); + Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); // Rule 2, same as rule 1 AutomaticZenRule zenRule2 = new AutomaticZenRule("name2", @@ -2280,7 +2460,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2, "test", - Process.SYSTEM_UID, true); + Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); // Rule 3, has stricter settings than the default settings ZenModeConfig ruleConfig = mZenModeHelper.mConfig.copy(); @@ -2294,7 +2474,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { ruleConfig.toZenPolicy(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id3 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule3, "test", - Process.SYSTEM_UID, true); + Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); // First: turn on rule 1 mZenModeHelper.setAutomaticZenRuleState(id, @@ -2394,7 +2574,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, "test", - Process.SYSTEM_UID, true); + Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); // Rule 2, same as rule 1 but owned by the system AutomaticZenRule zenRule2 = new AutomaticZenRule("name2", @@ -2404,7 +2584,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2, "test", - Process.SYSTEM_UID, true); + Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); // Turn on rule 1; call looks like it's from the system. Because setting a condition is // typically an automatic (non-user-initiated) action, expect the calling UID to be @@ -2422,7 +2602,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { // Disable rule 1. Because this looks like a user action, the UID should not be modified // from the system-provided one. zenRule.setEnabled(false); - mZenModeHelper.updateAutomaticZenRule(id, zenRule, "", Process.SYSTEM_UID, true); + mZenModeHelper.updateAutomaticZenRule(id, zenRule, "", Process.SYSTEM_UID, + FROM_SYSTEM_OR_SYSTEMUI); // Add a manual rule. Any manual rule changes should not get calling uids reassigned. mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "", @@ -2553,7 +2734,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, "test", - Process.SYSTEM_UID, true); + Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); // enable the rule mZenModeHelper.setAutomaticZenRuleState(id, @@ -2596,7 +2777,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { customPolicy, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, "test", - Process.SYSTEM_UID, true); + Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); // enable the rule; this will update the consolidated policy mZenModeHelper.setAutomaticZenRuleState(id, @@ -2632,7 +2813,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, "test", - Process.SYSTEM_UID, true); + Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); // enable rule 1 mZenModeHelper.setAutomaticZenRuleState(id, @@ -2656,7 +2837,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { customPolicy, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2, - "test", Process.SYSTEM_UID, true); + "test", Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); // enable rule 2; this will update the consolidated policy mZenModeHelper.setAutomaticZenRuleState(id2, @@ -2694,7 +2875,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { customPolicy, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, "test", - Process.SYSTEM_UID, true); + Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); // enable the rule; this will update the consolidated policy mZenModeHelper.setAutomaticZenRuleState(id, @@ -2716,7 +2897,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { strictPolicy, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2, - "test", Process.SYSTEM_UID, true); + "test", Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); // enable rule 2; this will update the consolidated policy mZenModeHelper.setAutomaticZenRuleState(id2, @@ -2784,7 +2965,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); final String createdId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - zenRule, "test", Process.SYSTEM_UID, true); + zenRule, "test", Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); CountDownLatch latch = new CountDownLatch(1); final int[] actualStatus = new int[1]; @@ -2800,7 +2981,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeHelper.addCallback(callback); zenRule.setEnabled(false); - mZenModeHelper.updateAutomaticZenRule(createdId, zenRule, "", Process.SYSTEM_UID, true); + mZenModeHelper.updateAutomaticZenRule(createdId, zenRule, "", Process.SYSTEM_UID, + FROM_SYSTEM_OR_SYSTEMUI); assertTrue(latch.await(500, TimeUnit.MILLISECONDS)); assertEquals(AUTOMATIC_RULE_STATUS_DISABLED, actualStatus[0]); @@ -2818,7 +3000,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, false); final String createdId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - zenRule, "test", Process.SYSTEM_UID, true); + zenRule, "test", Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); CountDownLatch latch = new CountDownLatch(1); final int[] actualStatus = new int[1]; @@ -2834,7 +3016,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeHelper.addCallback(callback); zenRule.setEnabled(true); - mZenModeHelper.updateAutomaticZenRule(createdId, zenRule, "", Process.SYSTEM_UID, true); + mZenModeHelper.updateAutomaticZenRule(createdId, zenRule, "", Process.SYSTEM_UID, + FROM_SYSTEM_OR_SYSTEMUI); assertTrue(latch.await(500, TimeUnit.MILLISECONDS)); assertEquals(AUTOMATIC_RULE_STATUS_ENABLED, actualStatus[0]); @@ -2853,7 +3036,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); final String createdId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - zenRule, "test", Process.SYSTEM_UID, true); + zenRule, "test", Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); CountDownLatch latch = new CountDownLatch(1); final int[] actualStatus = new int[1]; @@ -2889,7 +3072,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); final String createdId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - zenRule, "test", Process.SYSTEM_UID, true); + zenRule, "test", Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); CountDownLatch latch = new CountDownLatch(1); final int[] actualStatus = new int[2]; @@ -2929,7 +3112,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); final String createdId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - zenRule, "test", Process.SYSTEM_UID, true); + zenRule, "test", Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); CountDownLatch latch = new CountDownLatch(1); final int[] actualStatus = new int[2]; @@ -2969,7 +3152,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); final String createdId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - zenRule, "test", Process.SYSTEM_UID, true); + zenRule, "test", Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI); // Event 1: Mimic the rule coming on automatically by setting the Condition to STATE_TRUE mZenModeHelper.setAutomaticZenRuleState(createdId, @@ -2982,7 +3165,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { // Event 3: "User" turns off the automatic rule (sets it to not enabled) zenRule.setEnabled(false); - mZenModeHelper.updateAutomaticZenRule(createdId, zenRule, "", Process.SYSTEM_UID, true); + mZenModeHelper.updateAutomaticZenRule(createdId, zenRule, "", Process.SYSTEM_UID, + FROM_SYSTEM_OR_SYSTEMUI); assertEquals(false, mZenModeHelper.mConfig.automaticRules.get(createdId).snoozing); } |