Loading services/core/java/com/android/server/notification/NotificationManagerService.java +7 −4 Original line number Diff line number Diff line Loading @@ -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()); } } Loading Loading @@ -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 Loading @@ -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 Loading services/core/java/com/android/server/notification/ZenModeHelper.java +80 −10 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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<>(); Loading Loading @@ -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) { Loading Loading @@ -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"); Loading @@ -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; Loading Loading @@ -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); } } Loading Loading @@ -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()) { Loading @@ -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); } } } Loading Loading @@ -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; } Loading @@ -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); Loading @@ -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()) { Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +4 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -5296,7 +5295,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { new Intent(Intent.ACTION_LOCALE_CHANGED)); verify(mZenModeHelper, times(1)).updateDefaultZenRules( anyInt(), anyBoolean()); anyInt()); } @Test Loading Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +228 −44 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +7 −4 Original line number Diff line number Diff line Loading @@ -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()); } } Loading Loading @@ -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 Loading @@ -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 Loading
services/core/java/com/android/server/notification/ZenModeHelper.java +80 −10 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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<>(); Loading Loading @@ -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) { Loading Loading @@ -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"); Loading @@ -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; Loading Loading @@ -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); } } Loading Loading @@ -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()) { Loading @@ -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); } } } Loading Loading @@ -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; } Loading @@ -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); Loading @@ -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()) { Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +4 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -5296,7 +5295,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { new Intent(Intent.ACTION_LOCALE_CHANGED)); verify(mZenModeHelper, times(1)).updateDefaultZenRules( anyInt(), anyBoolean()); anyInt()); } @Test Loading Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading
services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +228 −44 File changed.Preview size limit exceeded, changes collapsed. Show changes