diff options
3 files changed, 135 insertions, 24 deletions
diff --git a/core/java/android/app/AutomaticZenRule.java b/core/java/android/app/AutomaticZenRule.java index 9d68133c01da..e2f2075f0a32 100644 --- a/core/java/android/app/AutomaticZenRule.java +++ b/core/java/android/app/AutomaticZenRule.java @@ -31,7 +31,10 @@ import java.util.Objects; * Rule instance information for zen mode. */ public final class AutomaticZenRule implements Parcelable { - + /* @hide */ + private static final int ENABLED = 1; + /* @hide */ + private static final int DISABLED = 0; private boolean enabled = false; private String name; private @InterruptionFilter int interruptionFilter; @@ -39,6 +42,7 @@ public final class AutomaticZenRule implements Parcelable { private ComponentName owner; private long creationTime; private ZenPolicy mZenPolicy; + private boolean mModified = false; /** * Creates an automatic zen rule. @@ -101,8 +105,8 @@ public final class AutomaticZenRule implements Parcelable { } public AutomaticZenRule(Parcel source) { - enabled = source.readInt() == 1; - if (source.readInt() == 1) { + enabled = source.readInt() == ENABLED; + if (source.readInt() == ENABLED) { name = source.readString(); } interruptionFilter = source.readInt(); @@ -110,6 +114,7 @@ public final class AutomaticZenRule implements Parcelable { owner = source.readParcelable(null); creationTime = source.readLong(); mZenPolicy = source.readParcelable(null); + mModified = source.readInt() == ENABLED; } /** @@ -148,6 +153,14 @@ public final class AutomaticZenRule implements Parcelable { } /** + * Returns whether this rule's name has been modified by the user. + * @hide + */ + public boolean isModified() { + return mModified; + } + + /** * Gets the zen policy. */ public ZenPolicy getZenPolicy() { @@ -191,6 +204,14 @@ public final class AutomaticZenRule implements Parcelable { } /** + * Sets modified state of this rule. + * @hide + */ + public void setModified(boolean modified) { + this.mModified = modified; + } + + /** * Sets the zen policy. */ public void setZenPolicy(ZenPolicy zenPolicy) { @@ -204,7 +225,7 @@ public final class AutomaticZenRule implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(enabled ? 1 : 0); + dest.writeInt(enabled ? ENABLED : DISABLED); if (name != null) { dest.writeInt(1); dest.writeString(name); @@ -216,6 +237,7 @@ public final class AutomaticZenRule implements Parcelable { dest.writeParcelable(owner, 0); dest.writeLong(creationTime); dest.writeParcelable(mZenPolicy, 0); + dest.writeInt(mModified ? ENABLED : DISABLED); } @Override @@ -237,6 +259,7 @@ public final class AutomaticZenRule implements Parcelable { if (o == this) return true; final AutomaticZenRule other = (AutomaticZenRule) o; return other.enabled == enabled + && other.mModified == mModified && Objects.equals(other.name, name) && other.interruptionFilter == interruptionFilter && Objects.equals(other.conditionId, conditionId) @@ -248,7 +271,7 @@ public final class AutomaticZenRule implements Parcelable { @Override public int hashCode() { return Objects.hash(enabled, name, interruptionFilter, conditionId, owner, creationTime, - mZenPolicy); + mZenPolicy, mModified); } public static final Parcelable.Creator<AutomaticZenRule> CREATOR diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index fc9bd37a0f80..f279af03753e 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -96,7 +96,7 @@ public class ZenModeHelper { private final SettingsObserver mSettingsObserver; @VisibleForTesting protected final AppOpsManager mAppOps; @VisibleForTesting protected final NotificationManager mNotificationManager; - protected ZenModeConfig mDefaultConfig; + @VisibleForTesting protected ZenModeConfig mDefaultConfig; private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>(); private final ZenModeFiltering mFiltering; protected final RingerModeDelegate mRingerModeDelegate = new @@ -309,9 +309,6 @@ public class ZenModeHelper { newConfig = mConfig.copy(); ZenRule rule = new ZenRule(); populateZenRule(automaticZenRule, rule, true); - if (newConfig.automaticRules.put(rule.id, rule) != null) { - rule.modified = true; - } if (setConfigLocked(newConfig, reason, rule.component, true)) { return rule.id; } else { @@ -341,9 +338,6 @@ public class ZenModeHelper { } } populateZenRule(automaticZenRule, rule, false); - if (newConfig.automaticRules.put(ruleId, rule) != null) { - rule.modified = true; - } return setConfigLocked(newConfig, reason, rule.component, true); } } @@ -431,13 +425,16 @@ public class ZenModeHelper { updateDefaultAutomaticRuleNames(); for (ZenRule defaultRule : mDefaultConfig.automaticRules.values()) { ZenRule currRule = mConfig.automaticRules.get(defaultRule.id); - // if default rule wasn't modified, use localized name instead of previous - if (currRule != null && !currRule.modified && !defaultRule.name.equals(currRule.name)) { - if (canManageAutomaticZenRule(defaultRule)) { + // if default rule wasn't user-modified nor enabled, use localized name + // instead of previous system name + if (currRule != null && !currRule.modified && !currRule.enabled + && !defaultRule.name.equals(currRule.name)) { + if (canManageAutomaticZenRule(currRule)) { if (DEBUG) Slog.d(TAG, "Locale change - updating default zen rule name " + "from " + currRule.name + " to " + defaultRule.name); // update default rule (if locale changed, name of rule will change) - updateAutomaticZenRule(defaultRule.id, createAutomaticZenRule(defaultRule), + currRule.name = defaultRule.name; + updateAutomaticZenRule(defaultRule.id, createAutomaticZenRule(currRule), "locale changed"); } } @@ -481,6 +478,7 @@ public class ZenModeHelper { rule.condition = null; rule.conditionId = automaticZenRule.getConditionId(); rule.enabled = automaticZenRule.isEnabled(); + rule.modified = automaticZenRule.isModified(); if (automaticZenRule.getZenPolicy() != null) { rule.zenPolicy = automaticZenRule.getZenPolicy(); } 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 b19cc86a3404..38d8e3990e00 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java @@ -21,13 +21,14 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCRE import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK; -import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertFalse; import static junit.framework.TestCase.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doNothing; @@ -45,13 +46,14 @@ import android.app.NotificationManager.Policy; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; +import android.content.pm.PackageManager; import android.content.res.Resources; import android.content.res.XmlResourceParser; import android.media.AudioAttributes; import android.media.AudioManager; import android.media.AudioManagerInternal; -import android.media.VolumePolicy; import android.media.AudioSystem; +import android.media.VolumePolicy; import android.net.Uri; import android.provider.Settings; import android.provider.Settings.Global; @@ -67,9 +69,9 @@ import android.util.Xml; import com.android.internal.R; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; -import com.android.server.notification.ManagedServices.UserProfiles; import com.android.internal.util.FastXmlSerializer; import com.android.server.UiServiceTestCase; +import com.android.server.notification.ManagedServices.UserProfiles; import org.junit.Before; import org.junit.Test; @@ -87,12 +89,16 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.Reader; +import java.util.Objects; @SmallTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class ZenModeHelperTest extends UiServiceTestCase { + private static final String EVENTS_DEFAULT_RULE_ID = "EVENTS_DEFAULT_RULE"; + private static final String SCHEDULE_DEFAULT_RULE_ID = "EVERY_NIGHT_DEFAULT_RULE"; + ConditionProviders mConditionProviders; @Mock NotificationManager mNotificationManager; private Resources mResources; @@ -108,7 +114,6 @@ public class ZenModeHelperTest extends UiServiceTestCase { mTestableLooper = TestableLooper.get(this); mContext = spy(getContext()); mContentResolver = mContext.getContentResolver(); - mResources = spy(mContext.getResources()); try { when(mResources.getXml(R.xml.default_zen_mode_config)).thenReturn( @@ -132,12 +137,13 @@ public class ZenModeHelperTest extends UiServiceTestCase { + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" " + "visualScreenOff=\"true\" alarms=\"true\" " + "media=\"true\" system=\"false\" />\n" - + "<automatic ruleId=\"EVENTS_DEFAULT_RULE\" enabled=\"false\" snoozing=\"false\"" + + "<automatic ruleId=\"" + EVENTS_DEFAULT_RULE_ID + + "\" enabled=\"false\" snoozing=\"false\"" + " name=\"Event\" zen=\"1\"" + " component=\"android/com.android.server.notification.EventConditionProvider\"" + " conditionId=\"condition://android/event?userId=-10000&calendar=&" + "reply=1\"/>\n" - + "<automatic ruleId=\"EVERY_NIGHT_DEFAULT_RULE\" enabled=\"false\"" + + "<automatic ruleId=\"" + SCHEDULE_DEFAULT_RULE_ID + "\" enabled=\"false\"" + " snoozing=\"false\" name=\"Sleeping\" zen=\"1\"" + " component=\"android/com.android.server.notification.ScheduleConditionProvider\"" + " conditionId=\"condition://android/schedule?days=1.2.3.4.5.6.7 &start=22.0" @@ -770,8 +776,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeHelperSpy.readXml(parser, false); assertEquals(SUPPRESSED_EFFECT_FULL_SCREEN_INTENT - | SUPPRESSED_EFFECT_LIGHTS - | SUPPRESSED_EFFECT_PEEK, + | SUPPRESSED_EFFECT_LIGHTS + | SUPPRESSED_EFFECT_PEEK, mZenModeHelperSpy.mConfig.suppressedVisualEffects); xml = "<zen version=\"6\" user=\"0\">\n" @@ -1007,6 +1013,90 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeHelperSpy.updateDefaultZenRules(); // shouldn't throw null pointer } + @Test + public void testDoNotUpdateModifiedDefaultAutoRule() { + // mDefaultConfig is set to default config in setup by getDefaultConfigParser + when(mContext.checkCallingPermission(anyString())) + .thenReturn(PackageManager.PERMISSION_GRANTED); + + // shouldn't update rule that's been modified + ZenModeConfig.ZenRule updatedDefaultRule = new ZenModeConfig.ZenRule(); + updatedDefaultRule.modified = true; + updatedDefaultRule.enabled = false; + updatedDefaultRule.creationTime = 0; + updatedDefaultRule.id = SCHEDULE_DEFAULT_RULE_ID; + updatedDefaultRule.name = "Schedule Default Rule"; + updatedDefaultRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + updatedDefaultRule.conditionId = ZenModeConfig.toScheduleConditionId(new ScheduleInfo()); + updatedDefaultRule.component = new ComponentName("android", "ScheduleConditionProvider"); + + ArrayMap<String, ZenModeConfig.ZenRule> autoRules = new ArrayMap<>(); + autoRules.put(SCHEDULE_DEFAULT_RULE_ID, updatedDefaultRule); + mZenModeHelperSpy.mConfig.automaticRules = autoRules; + + mZenModeHelperSpy.updateDefaultZenRules(); + assertEquals(updatedDefaultRule, + mZenModeHelperSpy.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID)); + } + + @Test + public void testDoNotUpdateEnabledDefaultAutoRule() { + // mDefaultConfig is set to default config in setup by getDefaultConfigParser + when(mContext.checkCallingPermission(anyString())) + .thenReturn(PackageManager.PERMISSION_GRANTED); + + // shouldn't update the rule that's enabled + ZenModeConfig.ZenRule updatedDefaultRule = new ZenModeConfig.ZenRule(); + updatedDefaultRule.enabled = true; + updatedDefaultRule.modified = false; + updatedDefaultRule.creationTime = 0; + updatedDefaultRule.id = SCHEDULE_DEFAULT_RULE_ID; + updatedDefaultRule.name = "Schedule Default Rule"; + updatedDefaultRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + updatedDefaultRule.conditionId = ZenModeConfig.toScheduleConditionId(new ScheduleInfo()); + updatedDefaultRule.component = new ComponentName("android", "ScheduleConditionProvider"); + + ArrayMap<String, ZenModeConfig.ZenRule> autoRules = new ArrayMap<>(); + autoRules.put(SCHEDULE_DEFAULT_RULE_ID, updatedDefaultRule); + mZenModeHelperSpy.mConfig.automaticRules = autoRules; + + mZenModeHelperSpy.updateDefaultZenRules(); + assertEquals(updatedDefaultRule, + mZenModeHelperSpy.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID)); + } + + @Test + public void testUpdateDefaultAutoRule() { + // mDefaultConfig is set to default config in setup by getDefaultConfigParser + final String defaultRuleName = "rule name test"; + when(mContext.checkCallingPermission(anyString())) + .thenReturn(PackageManager.PERMISSION_GRANTED); + + // will update rule that is not enabled and modified + ZenModeConfig.ZenRule customDefaultRule = new ZenModeConfig.ZenRule(); + customDefaultRule.enabled = false; + customDefaultRule.modified = false; + customDefaultRule.creationTime = 0; + customDefaultRule.id = SCHEDULE_DEFAULT_RULE_ID; + customDefaultRule.name = "Schedule Default Rule"; + customDefaultRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + customDefaultRule.conditionId = ZenModeConfig.toScheduleConditionId(new ScheduleInfo()); + customDefaultRule.component = new ComponentName("android", "ScheduleConditionProvider"); + + ArrayMap<String, ZenModeConfig.ZenRule> autoRules = new ArrayMap<>(); + autoRules.put(SCHEDULE_DEFAULT_RULE_ID, customDefaultRule); + mZenModeHelperSpy.mConfig.automaticRules = autoRules; + + mZenModeHelperSpy.updateDefaultZenRules(); + ZenModeConfig.ZenRule ruleAfterUpdating = + mZenModeHelperSpy.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID); + assertEquals(customDefaultRule.enabled, ruleAfterUpdating.enabled); + assertEquals(customDefaultRule.modified, ruleAfterUpdating.modified); + assertEquals(customDefaultRule.id, ruleAfterUpdating.id); + assertEquals(customDefaultRule.conditionId, ruleAfterUpdating.conditionId); + assertFalse(Objects.equals(defaultRuleName, ruleAfterUpdating.name)); // update name + } + private void setupZenConfig() { mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; mZenModeHelperSpy.mConfig.allowAlarms = false; |