diff options
3 files changed, 99 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index f089c3acdd70..b39b6fde6258 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -16,6 +16,7 @@ package com.android.server.notification; +import static android.app.AutomaticZenRule.TYPE_DRIVING; import static android.app.AutomaticZenRule.TYPE_UNKNOWN; import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_ACTIVATED; import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_DEACTIVATED; @@ -46,6 +47,7 @@ import static android.service.notification.ZenModeConfig.isImplicitRuleId; import static com.android.internal.util.FrameworkStatsLog.DND_MODE_RULE; import static com.android.internal.util.Preconditions.checkArgument; +import static com.android.server.notification.Flags.preventZenDeviceEffectsWhileDriving; import static java.util.Objects.requireNonNull; @@ -2379,6 +2381,26 @@ public class ZenModeHelper { } if (Flags.modesApi()) { + // Prevent other rules from applying grayscale if Driving is active (but allow it + // if _Driving itself_ wants grayscale). + if (Flags.modesUi() && preventZenDeviceEffectsWhileDriving()) { + boolean hasActiveDriving = false; + boolean hasActiveDrivingWithGrayscale = false; + for (ZenRule rule : mConfig.automaticRules.values()) { + if (rule.isActive() && rule.type == TYPE_DRIVING) { + hasActiveDriving = true; + if (rule.zenDeviceEffects != null + && rule.zenDeviceEffects.shouldDisplayGrayscale()) { + hasActiveDrivingWithGrayscale = true; + break; // Further rules won't affect decision. + } + } + } + if (hasActiveDriving && !hasActiveDrivingWithGrayscale) { + deviceEffectsBuilder.setShouldDisplayGrayscale(false); + } + } + ZenDeviceEffects deviceEffects = deviceEffectsBuilder.build(); if (!deviceEffects.equals(mConsolidatedDeviceEffects)) { mConsolidatedDeviceEffects = deviceEffects; diff --git a/services/core/java/com/android/server/notification/flags.aconfig b/services/core/java/com/android/server/notification/flags.aconfig index b4a8aee66c7c..822ff48c831c 100644 --- a/services/core/java/com/android/server/notification/flags.aconfig +++ b/services/core/java/com/android/server/notification/flags.aconfig @@ -190,3 +190,13 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "prevent_zen_device_effects_while_driving" + namespace: "systemui" + description: "Don't apply certain device effects (such as grayscale) from active zen rules, if a rule of TYPE_DRIVING is active" + bug: "390389174" + metadata { + purpose: PURPOSE_BUGFIX + } +} 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 96fddf13cdd0..31b9cf72584c 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java @@ -17,8 +17,10 @@ package com.android.server.notification; import static android.app.AutomaticZenRule.TYPE_BEDTIME; +import static android.app.AutomaticZenRule.TYPE_DRIVING; import static android.app.AutomaticZenRule.TYPE_IMMERSIVE; import static android.app.AutomaticZenRule.TYPE_SCHEDULE_TIME; +import static android.app.AutomaticZenRule.TYPE_THEATER; import static android.app.AutomaticZenRule.TYPE_UNKNOWN; import static android.app.Flags.FLAG_BACKUP_RESTORE_LOGGING; import static android.app.Flags.FLAG_MODES_API; @@ -87,6 +89,7 @@ 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.Flags.FLAG_PREVENT_ZEN_DEVICE_EFFECTS_WHILE_DRIVING; import static com.android.server.notification.ZenModeEventLogger.ACTIVE_RULE_TYPE_MANUAL; import static com.android.server.notification.ZenModeHelper.RULE_LIMIT_PER_PACKAGE; @@ -5518,8 +5521,72 @@ public class ZenModeHelperTest extends UiServiceTestCase { eq(ORIGIN_INIT_USER)); } + @Test + @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI, FLAG_PREVENT_ZEN_DEVICE_EFFECTS_WHILE_DRIVING}) + public void testDeviceEffects_allowsGrayscale() { + mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier); + reset(mDeviceEffectsApplier); + ZenDeviceEffects grayscale = new ZenDeviceEffects.Builder() + .setShouldDisplayGrayscale(true) + .build(); + String ruleId = addRuleWithEffects(TYPE_THEATER, grayscale); + + mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId, CONDITION_TRUE, + ORIGIN_APP, CUSTOM_PKG_UID); + mTestableLooper.processAllMessages(); + + verify(mDeviceEffectsApplier).apply(eq(grayscale), anyInt()); + } + + @Test + @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI, FLAG_PREVENT_ZEN_DEVICE_EFFECTS_WHILE_DRIVING}) + public void testDeviceEffects_whileDriving_avoidsGrayscale() { + mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier); + reset(mDeviceEffectsApplier); + ZenDeviceEffects grayscale = new ZenDeviceEffects.Builder() + .setShouldDisplayGrayscale(true) + .build(); + String ruleWithGrayscale = addRuleWithEffects(TYPE_THEATER, grayscale); + String drivingRule = addRuleWithEffects(TYPE_DRIVING, null); + + mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleWithGrayscale, + CONDITION_TRUE, ORIGIN_APP, CUSTOM_PKG_UID); + mTestableLooper.processAllMessages(); + + verify(mDeviceEffectsApplier).apply(eq(grayscale), anyInt()); + + mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, drivingRule, CONDITION_TRUE, + ORIGIN_APP, CUSTOM_PKG_UID); + mTestableLooper.processAllMessages(); + + verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), anyInt()); + } + + @Test + @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI, FLAG_PREVENT_ZEN_DEVICE_EFFECTS_WHILE_DRIVING}) + public void testDeviceEffects_whileDrivingWithGrayscale_allowsGrayscale() { + mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier); + reset(mDeviceEffectsApplier); + ZenDeviceEffects grayscale = new ZenDeviceEffects.Builder() + .setShouldDisplayGrayscale(true) + .build(); + String weirdoDrivingWithGrayscale = addRuleWithEffects(TYPE_DRIVING, grayscale); + + mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, weirdoDrivingWithGrayscale, + CONDITION_TRUE, ORIGIN_APP, CUSTOM_PKG_UID); + mTestableLooper.processAllMessages(); + + verify(mDeviceEffectsApplier).apply(eq(grayscale), anyInt()); + } + private String addRuleWithEffects(ZenDeviceEffects effects) { + return addRuleWithEffects(TYPE_UNKNOWN, effects); + } + + private String addRuleWithEffects(int type, @Nullable ZenDeviceEffects effects) { AutomaticZenRule rule = new AutomaticZenRule.Builder("Test", CONDITION_ID) + .setPackage(mContext.getPackageName()) + .setType(type) .setDeviceEffects(effects) .build(); return mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mContext.getPackageName(), |