From 49ba9a60190d3ef58a4c30a6fd1ddeff32f83295 Mon Sep 17 00:00:00 2001 From: Beverly Date: Fri, 2 Nov 2018 13:19:31 -0400 Subject: [PATCH] Only update zen rule name on locale change Test: atest ZenModeHelperTest Change-Id: I9154c812f9955d145fe461b9e17faf9fe9ccf1c9 Fixes: 118789422 --- core/java/android/app/AutomaticZenRule.java | 33 +++++- .../server/notification/ZenModeHelper.java | 20 ++-- .../notification/ZenModeHelperTest.java | 106 ++++++++++++++++-- 3 files changed, 135 insertions(+), 24 deletions(-) diff --git a/core/java/android/app/AutomaticZenRule.java b/core/java/android/app/AutomaticZenRule.java index 9d68133c01da0..e2f2075f0a329 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; } /** @@ -147,6 +152,14 @@ public final class AutomaticZenRule implements Parcelable { return enabled; } + /** + * Returns whether this rule's name has been modified by the user. + * @hide + */ + public boolean isModified() { + return mModified; + } + /** * Gets the zen policy. */ @@ -190,6 +203,14 @@ public final class AutomaticZenRule implements Parcelable { this.enabled = enabled; } + /** + * Sets modified state of this rule. + * @hide + */ + public void setModified(boolean modified) { + this.mModified = modified; + } + /** * Sets the zen policy. */ @@ -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 CREATOR diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index fc9bd37a0f804..f279af03753ed 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 mCallbacks = new ArrayList(); 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 b19cc86a34047..38d8e3990e005 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" - + "\n" - + "\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 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 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 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;