From 3b62c233100a00bad3070f65bdb261a1e7921ce4 Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Mon, 17 Jun 2024 09:15:57 -0400 Subject: [PATCH] Design refresh for modes that don't filter notifications And fix a crash noticed in ZenModeAppsLinkPreferenceController Test: atest com/android/settings/notification/modes Fixes: 308820027 Flag: android.app.modes_ui Change-Id: I0cfe4e10ca7ff97dac3b3b8756cc36f4d6f91ea2 --- res/values/strings.xml | 7 +- res/xml/modes_rule_settings.xml | 7 +- ...nterruptionFilterPreferenceController.java | 62 ++++++++ .../settings/notification/modes/ZenMode.java | 49 +----- .../modes/ZenModeAppsFragment.java | 4 - .../ZenModeAppsLinkPreferenceController.java | 17 ++- .../ZenModeAppsPreferenceController.java | 11 -- .../notification/modes/ZenModeFragment.java | 2 + .../modes/ZenModeFragmentBase.java | 5 +- ...nModeNotifVisLinkPreferenceController.java | 7 + .../ZenModeOtherLinkPreferenceController.java | 7 + ...ZenModePeopleLinkPreferenceController.java | 7 + .../modes/ZenModeSummaryHelper.java | 6 +- ...ruptionFilterPreferenceControllerTest.java | 143 ++++++++++++++++++ ...nModeAppsLinkPreferenceControllerTest.java | 22 ++- .../ZenModeAppsPreferenceControllerTest.java | 110 +------------- .../notification/modes/ZenModeTest.java | 77 ---------- .../modes/ZenModesSummaryHelperTest.java | 14 -- 18 files changed, 281 insertions(+), 276 deletions(-) create mode 100644 src/com/android/settings/notification/modes/InterruptionFilterPreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/notification/modes/InterruptionFilterPreferenceControllerTest.java diff --git a/res/values/strings.xml b/res/values/strings.xml index 386ece3caf4..6560e5446f1 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -8016,7 +8016,7 @@ Allow visual signals - Notifications that can reach you + Stay focused Additional actions @@ -8060,7 +8060,10 @@ other {{effect_1}, {effect_2}, and # more} } - + + Filter interruptions + + No interruptions are filtered Display options for filtered diff --git a/res/xml/modes_rule_settings.xml b/res/xml/modes_rule_settings.xml index cf090be46d3..0df9f80f851 100644 --- a/res/xml/modes_rule_settings.xml +++ b/res/xml/modes_rule_settings.xml @@ -35,13 +35,18 @@ + + + + android:title="@string/zen_category_apps"/> { + zenMode.getRule().setInterruptionFilter(filterNotifications + ? INTERRUPTION_FILTER_PRIORITY + : INTERRUPTION_FILTER_ALL); + return zenMode; + }); + } +} diff --git a/src/com/android/settings/notification/modes/ZenMode.java b/src/com/android/settings/notification/modes/ZenMode.java index 1040d1e0021..4ece2e3046d 100644 --- a/src/com/android/settings/notification/modes/ZenMode.java +++ b/src/com/android/settings/notification/modes/ZenMode.java @@ -59,26 +59,8 @@ class ZenMode { private static final String TAG = "ZenMode"; - /** - * Additional value for the {@code @ZenPolicy.ChannelType} enumeration that indicates that all - * channels can bypass DND when this policy is active. - * - *

This value shouldn't be used on "real" ZenPolicy objects sent to or returned from - * {@link android.app.NotificationManager}; it's a way of representing rules with interruption - * filter = {@link NotificationManager#INTERRUPTION_FILTER_ALL} in the UI. - */ - public static final int CHANNEL_POLICY_ALL = -1; - static final String MANUAL_DND_MODE_ID = "manual_dnd"; - @SuppressLint("WrongConstant") - private static final ZenPolicy POLICY_INTERRUPTION_FILTER_ALL = - new ZenPolicy.Builder() - .allowChannels(CHANNEL_POLICY_ALL) - .allowAllSounds() - .showAllVisualEffects() - .build(); - // Must match com.android.server.notification.ZenModeHelper#applyCustomPolicy. private static final ZenPolicy POLICY_INTERRUPTION_FILTER_ALARMS = new ZenPolicy.Builder() @@ -141,10 +123,8 @@ class ZenMode { public ZenPolicy getPolicy() { switch (mRule.getInterruptionFilter()) { case INTERRUPTION_FILTER_PRIORITY: - return requireNonNull(mRule.getZenPolicy()); - case NotificationManager.INTERRUPTION_FILTER_ALL: - return POLICY_INTERRUPTION_FILTER_ALL; + return requireNonNull(mRule.getZenPolicy()); case NotificationManager.INTERRUPTION_FILTER_ALARMS: return POLICY_INTERRUPTION_FILTER_ALARMS; @@ -172,31 +152,8 @@ class ZenMode { return; } - // A policy with CHANNEL_POLICY_ALL is only a UI representation of the - // INTERRUPTION_FILTER_ALL filter. Thus, switching to or away to this value only updates - // the filter, discarding the rest of the supplied policy. - if (policy.getAllowedChannels() == CHANNEL_POLICY_ALL - && currentPolicy.getAllowedChannels() != CHANNEL_POLICY_ALL) { - if (mIsManualDnd) { - throw new IllegalArgumentException("Manual DND cannot have CHANNEL_POLICY_ALL"); - } - mRule.setInterruptionFilter(INTERRUPTION_FILTER_ALL); - // Preserve the existing policy, e.g. if the user goes PRIORITY -> ALL -> PRIORITY that - // shouldn't discard all other policy customizations. The existing policy will be a - // synthetic one if the rule originally had filter NONE or ALARMS_ONLY and that's fine. - if (mRule.getZenPolicy() == null) { - mRule.setZenPolicy(currentPolicy); - } - return; - } else if (policy.getAllowedChannels() != CHANNEL_POLICY_ALL - && currentPolicy.getAllowedChannels() == CHANNEL_POLICY_ALL) { - mRule.setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY); - // Go back to whatever policy the rule had before, unless the rule never had one, in - // which case we use the supplied policy (which we know has a valid allowedChannels). - if (mRule.getZenPolicy() == null) { - mRule.setZenPolicy(policy); - } - return; + if (mRule.getInterruptionFilter() == INTERRUPTION_FILTER_ALL) { + Log.wtf(TAG, "Able to change policy without filtering being enabled"); } // If policy is customized from any of the "special" ones, make the rule PRIORITY. diff --git a/src/com/android/settings/notification/modes/ZenModeAppsFragment.java b/src/com/android/settings/notification/modes/ZenModeAppsFragment.java index 73329a242fd..19035ddcf78 100644 --- a/src/com/android/settings/notification/modes/ZenModeAppsFragment.java +++ b/src/com/android/settings/notification/modes/ZenModeAppsFragment.java @@ -37,10 +37,6 @@ public class ZenModeAppsFragment extends ZenModeFragmentBase { context, ZenModeAppsPreferenceController.KEY_PRIORITY, mBackend)); controllers.add(new ZenModeAppsPreferenceController( context, ZenModeAppsPreferenceController.KEY_NONE, mBackend)); - // TODO: b/308819928 - The manual DND mode cannot have the ALL type; - // unify the controllers into one and only create a preference if isManualDnd is false. - controllers.add(new ZenModeAppsPreferenceController( - context, ZenModeAppsPreferenceController.KEY_ALL, mBackend)); return controllers; } diff --git a/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceController.java index 691c92e2e3c..6835e6cd853 100644 --- a/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceController.java +++ b/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceController.java @@ -16,6 +16,8 @@ package com.android.settings.notification.modes; +import static android.app.NotificationManager.INTERRUPTION_FILTER_ALL; + import static com.android.settings.notification.modes.ZenModeFragmentBase.MODE_ID; import android.content.Context; @@ -45,10 +47,12 @@ class ZenModeAppsLinkPreferenceController extends AbstractZenModePreferenceContr private static final String TAG = "ZenModeAppsLinkPreferenceController"; private final ZenModeSummaryHelper mSummaryHelper; + private final ApplicationsState mApplicationsState; private ApplicationsState.Session mAppSession; private final ZenHelperBackend mHelperBackend; private ZenMode mZenMode; private Preference mPreference; + private final Fragment mHost; ZenModeAppsLinkPreferenceController(Context context, String key, Fragment host, ApplicationsState applicationsState, ZenModesBackend backend, @@ -56,9 +60,13 @@ class ZenModeAppsLinkPreferenceController extends AbstractZenModePreferenceContr super(context, key, backend); mSummaryHelper = new ZenModeSummaryHelper(mContext, helperBackend); mHelperBackend = helperBackend; - if (applicationsState != null && host != null) { - mAppSession = applicationsState.newSession(mAppSessionCallbacks, host.getLifecycle()); - } + mApplicationsState = applicationsState; + mHost = host; + } + + @Override + public boolean isAvailable(ZenMode zenMode) { + return zenMode.getRule().getInterruptionFilter() != INTERRUPTION_FILTER_ALL; } @Override @@ -73,6 +81,9 @@ class ZenModeAppsLinkPreferenceController extends AbstractZenModePreferenceContr .toIntent()); mZenMode = zenMode; mPreference = preference; + if (mApplicationsState != null && mHost != null) { + mAppSession = mApplicationsState.newSession(mAppSessionCallbacks, mHost.getLifecycle()); + } triggerUpdateAppsBypassingDndSummaryText(); } diff --git a/src/com/android/settings/notification/modes/ZenModeAppsPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeAppsPreferenceController.java index 704bce04504..d5ef0440b5e 100644 --- a/src/com/android/settings/notification/modes/ZenModeAppsPreferenceController.java +++ b/src/com/android/settings/notification/modes/ZenModeAppsPreferenceController.java @@ -38,11 +38,9 @@ public class ZenModeAppsPreferenceController extends static final String KEY_PRIORITY = "zen_mode_apps_priority"; static final String KEY_NONE = "zen_mode_apps_none"; - static final String KEY_ALL = "zen_mode_apps_all"; String mModeId; - public ZenModeAppsPreferenceController(@NonNull Context context, @NonNull String key, @Nullable ZenModesBackend backend) { super(context, key, backend); @@ -79,13 +77,6 @@ public class ZenModeAppsPreferenceController extends == ZenPolicy.CHANNEL_POLICY_NONE; pref.setChecked(policy_none); break; - case KEY_ALL: - // A UI-only setting; the underlying policy never actually has this value, - // but ZenMode acts as though it does for the sake of UI consistency. - boolean policy_all = zenMode.getPolicy().getAllowedChannels() - == ZenMode.CHANNEL_POLICY_ALL; - pref.setChecked(policy_all); - break; } } @@ -96,8 +87,6 @@ public class ZenModeAppsPreferenceController extends return savePolicy(p -> p.allowChannels(ZenPolicy.CHANNEL_POLICY_PRIORITY)); case KEY_NONE: return savePolicy(p -> p.allowChannels(ZenPolicy.CHANNEL_POLICY_NONE)); - case KEY_ALL: - return savePolicy(p -> p.allowChannels(ZenMode.CHANNEL_POLICY_ALL)); } return true; } diff --git a/src/com/android/settings/notification/modes/ZenModeFragment.java b/src/com/android/settings/notification/modes/ZenModeFragment.java index ee497ae74df..f2f47b99ceb 100644 --- a/src/com/android/settings/notification/modes/ZenModeFragment.java +++ b/src/com/android/settings/notification/modes/ZenModeFragment.java @@ -53,6 +53,8 @@ public class ZenModeFragment extends ZenModeFragmentBase { context, "mode_display_settings", mBackend, mHelperBackend)); prefControllers.add(new ZenModeSetTriggerLinkPreferenceController(context, "zen_automatic_trigger_category", this, mBackend)); + prefControllers.add(new InterruptionFilterPreferenceController( + context, "allow_filtering", mBackend)); return prefControllers; } diff --git a/src/com/android/settings/notification/modes/ZenModeFragmentBase.java b/src/com/android/settings/notification/modes/ZenModeFragmentBase.java index e086524a427..67cc13beb4a 100644 --- a/src/com/android/settings/notification/modes/ZenModeFragmentBase.java +++ b/src/com/android/settings/notification/modes/ZenModeFragmentBase.java @@ -120,10 +120,6 @@ abstract class ZenModeFragmentBase extends ZenModesFragmentBase { } for (List list : getPreferenceControllers()) { for (AbstractPreferenceController controller : list) { - if (!controller.isAvailable()) { - continue; - } - try { // Find preference associated with controller final String key = controller.getPreferenceKey(); @@ -137,6 +133,7 @@ abstract class ZenModeFragmentBase extends ZenModesFragmentBase { String.format("Cannot find preference with key %s in Controller %s", key, controller.getClass().getSimpleName())); } + controller.displayPreference(screen); } catch (ClassCastException e) { // Skip any controllers that aren't AbstractZenModePreferenceController. Log.d(TAG, "Could not cast: " + controller.getClass().getSimpleName()); diff --git a/src/com/android/settings/notification/modes/ZenModeNotifVisLinkPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeNotifVisLinkPreferenceController.java index 15da96ec605..1b1fec4e3f6 100644 --- a/src/com/android/settings/notification/modes/ZenModeNotifVisLinkPreferenceController.java +++ b/src/com/android/settings/notification/modes/ZenModeNotifVisLinkPreferenceController.java @@ -16,6 +16,8 @@ package com.android.settings.notification.modes; +import static android.app.NotificationManager.INTERRUPTION_FILTER_ALL; + import static com.android.settings.notification.modes.ZenModeFragmentBase.MODE_ID; import android.content.Context; @@ -36,6 +38,11 @@ class ZenModeNotifVisLinkPreferenceController extends AbstractZenModePreferenceC mSummaryBuilder = new ZenModeSummaryHelper(context, helperBackend); } + @Override + public boolean isAvailable(ZenMode zenMode) { + return zenMode.getRule().getInterruptionFilter() != INTERRUPTION_FILTER_ALL; + } + @Override public void updateState(Preference preference, @NonNull ZenMode zenMode) { Bundle bundle = new Bundle(); diff --git a/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceController.java index 89b719eadb5..f6df9e3e3d7 100644 --- a/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceController.java +++ b/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceController.java @@ -16,6 +16,8 @@ package com.android.settings.notification.modes; +import static android.app.NotificationManager.INTERRUPTION_FILTER_ALL; + import static com.android.settings.notification.modes.ZenModeFragmentBase.MODE_ID; import android.content.Context; @@ -39,6 +41,11 @@ class ZenModeOtherLinkPreferenceController extends AbstractZenModePreferenceCont mSummaryHelper = new ZenModeSummaryHelper(mContext, helperBackend); } + @Override + public boolean isAvailable(ZenMode zenMode) { + return zenMode.getRule().getInterruptionFilter() != INTERRUPTION_FILTER_ALL; + } + @Override public void updateState(Preference preference, @NonNull ZenMode zenMode) { Bundle bundle = new Bundle(); diff --git a/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceController.java b/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceController.java index 271ca724b32..db8e135e5a2 100644 --- a/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceController.java +++ b/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceController.java @@ -16,6 +16,8 @@ package com.android.settings.notification.modes; +import static android.app.NotificationManager.INTERRUPTION_FILTER_ALL; + import static com.android.settings.notification.modes.ZenModeFragmentBase.MODE_ID; import android.content.Context; @@ -39,6 +41,11 @@ class ZenModePeopleLinkPreferenceController extends AbstractZenModePreferenceCon mSummaryHelper = new ZenModeSummaryHelper(mContext, helperBackend); } + @Override + public boolean isAvailable(ZenMode zenMode) { + return zenMode.getRule().getInterruptionFilter() != INTERRUPTION_FILTER_ALL; + } + @Override public void updateState(Preference preference, @NonNull ZenMode zenMode) { Bundle bundle = new Bundle(); diff --git a/src/com/android/settings/notification/modes/ZenModeSummaryHelper.java b/src/com/android/settings/notification/modes/ZenModeSummaryHelper.java index bf0bac9f166..bd0b798a309 100644 --- a/src/com/android/settings/notification/modes/ZenModeSummaryHelper.java +++ b/src/com/android/settings/notification/modes/ZenModeSummaryHelper.java @@ -15,6 +15,7 @@ */ package com.android.settings.notification.modes; +import static android.app.NotificationManager.INTERRUPTION_FILTER_ALL; import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_ANYONE; import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_IMPORTANT; import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_NONE; @@ -187,7 +188,8 @@ class ZenModeSummaryHelper { String getDisplayEffectsSummary(ZenMode zenMode) { boolean isFirst = true; List enabledEffects = new ArrayList<>(); - if (!zenMode.getPolicy().shouldShowAllVisualEffects()) { + if (!zenMode.getPolicy().shouldShowAllVisualEffects() + && zenMode.getRule().getInterruptionFilter() != INTERRUPTION_FILTER_ALL) { enabledEffects.add(getBlockedEffectsSummary(zenMode)); isFirst = false; } @@ -411,8 +413,6 @@ class ZenModeSummaryHelper { return formatAppsList(appsBypassing); } else if (zenMode.getPolicy().getAllowedChannels() == ZenPolicy.CHANNEL_POLICY_NONE) { return mContext.getResources().getString(R.string.zen_mode_apps_none_apps); - } else if (zenMode.getPolicy().getAllowedChannels() == ZenMode.CHANNEL_POLICY_ALL) { - return mContext.getResources().getString(R.string.zen_mode_apps_all_apps); } return ""; } diff --git a/tests/robotests/src/com/android/settings/notification/modes/InterruptionFilterPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/InterruptionFilterPreferenceControllerTest.java new file mode 100644 index 00000000000..aeb1b8ed8c4 --- /dev/null +++ b/tests/robotests/src/com/android/settings/notification/modes/InterruptionFilterPreferenceControllerTest.java @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.notification.modes; + +import static android.app.NotificationManager.INTERRUPTION_FILTER_ALL; +import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY; +import static android.service.notification.ZenPolicy.STATE_ALLOW; +import static android.service.notification.ZenPolicy.STATE_DISALLOW; +import static android.service.notification.ZenPolicy.STATE_UNSET; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import android.app.AutomaticZenRule; +import android.app.Flags; +import android.content.Context; +import android.net.Uri; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; +import android.service.notification.ZenPolicy; + +import androidx.preference.Preference; +import androidx.preference.TwoStatePreference; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +@EnableFlags(Flags.FLAG_MODES_UI) +public final class InterruptionFilterPreferenceControllerTest { + + private InterruptionFilterPreferenceController mController; + + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + + private Context mContext; + @Mock private ZenModesBackend mBackend; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + + mContext = RuntimeEnvironment.application; + mController = new InterruptionFilterPreferenceController(mContext, "something", mBackend); + } + + @Test + public void testUpdateState_all() { + TwoStatePreference preference = mock(TwoStatePreference.class); + ZenMode zenMode = new ZenMode("id", + new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) + .setType(AutomaticZenRule.TYPE_DRIVING) + .setInterruptionFilter(INTERRUPTION_FILTER_ALL) + .setZenPolicy(new ZenPolicy.Builder().allowAlarms(true).build()) + .build(), true); + mController.updateZenMode(preference, zenMode); + + verify(preference).setChecked(false); + } + + @Test + public void testOnPreferenceChange_fromAll() { + TwoStatePreference preference = mock(TwoStatePreference.class); + ZenMode zenMode = new ZenMode("id", + new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) + .setType(AutomaticZenRule.TYPE_DRIVING) + .setInterruptionFilter(INTERRUPTION_FILTER_ALL) + .setZenPolicy(new ZenPolicy.Builder().allowAlarms(false).build()) + .build(), true); + + mController.updateZenMode(preference, zenMode); + + mController.onPreferenceChange(preference, true); + + ArgumentCaptor captor = ArgumentCaptor.forClass(ZenMode.class); + verify(mBackend).updateMode(captor.capture()); + assertThat(captor.getValue().getPolicy().getPriorityCategoryAlarms()) + .isEqualTo(STATE_DISALLOW); + assertThat(captor.getValue().getRule().getInterruptionFilter()) + .isEqualTo(INTERRUPTION_FILTER_PRIORITY); + } + + @Test + public void testUpdateState_priority() { + TwoStatePreference preference = mock(TwoStatePreference.class); + ZenMode zenMode = new ZenMode("id", + new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) + .setType(AutomaticZenRule.TYPE_DRIVING) + .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) + .setZenPolicy(new ZenPolicy.Builder().allowAlarms(true).build()) + .build(), true); + mController.updateZenMode(preference, zenMode); + + verify(preference).setChecked(true); + } + + @Test + public void testOnPreferenceChange_fromPriority() { + TwoStatePreference preference = mock(TwoStatePreference.class); + ZenMode zenMode = new ZenMode("id", + new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) + .setType(AutomaticZenRule.TYPE_DRIVING) + .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) + .setZenPolicy(new ZenPolicy.Builder().allowAlarms(false).build()) + .build(), true); + + mController.updateZenMode(preference, zenMode); + + mController.onPreferenceChange(preference, false); + + ArgumentCaptor captor = ArgumentCaptor.forClass(ZenMode.class); + verify(mBackend).updateMode(captor.capture()); + assertThat(captor.getValue().getPolicy().getPriorityCategoryAlarms()) + .isEqualTo(STATE_DISALLOW); + assertThat(captor.getValue().getRule().getInterruptionFilter()) + .isEqualTo(INTERRUPTION_FILTER_ALL); + } +} \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceControllerTest.java index 8205f3a5f4a..b199a2bf922 100644 --- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceControllerTest.java @@ -25,6 +25,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -180,13 +181,30 @@ public final class ZenModeAppsLinkPreferenceControllerTest { @Test public void testOnPackageListChangedTriggersRebuild() { - mController.mAppSessionCallbacks.onPackageListChanged(); + SelectorWithWidgetPreference preference = mock(SelectorWithWidgetPreference.class); + // Create a zen mode that allows priority channels to breakthrough. + ZenMode zenMode = createPriorityChannelsZenMode(); + mController.updateState(preference, zenMode); verify(mSession).rebuild(any(), any(), eq(false)); + + mController.mAppSessionCallbacks.onPackageListChanged(); + verify(mSession, times(2)).rebuild(any(), any(), eq(false)); } @Test public void testOnLoadEntriesCompletedTriggersRebuild() { - mController.mAppSessionCallbacks.onLoadEntriesCompleted(); + SelectorWithWidgetPreference preference = mock(SelectorWithWidgetPreference.class); + // Create a zen mode that allows priority channels to breakthrough. + ZenMode zenMode = createPriorityChannelsZenMode(); + mController.updateState(preference, zenMode); verify(mSession).rebuild(any(), any(), eq(false)); + + mController.mAppSessionCallbacks.onLoadEntriesCompleted(); + verify(mSession, times(2)).rebuild(any(), any(), eq(false)); + } + + @Test + public void testNoCrashIfAppsReadyBeforeRuleAvailable() { + mController.mAppSessionCallbacks.onLoadEntriesCompleted(); } } diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeAppsPreferenceControllerTest.java index 750453dabe6..b67d3328fec 100644 --- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeAppsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeAppsPreferenceControllerTest.java @@ -20,7 +20,6 @@ import static android.app.NotificationManager.INTERRUPTION_FILTER_ALL; import static android.app.NotificationManager.INTERRUPTION_FILTER_NONE; import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY; -import static com.android.settings.notification.modes.ZenModeAppsPreferenceController.KEY_ALL; import static com.android.settings.notification.modes.ZenModeAppsPreferenceController.KEY_NONE; import static com.android.settings.notification.modes.ZenModeAppsPreferenceController.KEY_PRIORITY; @@ -62,11 +61,9 @@ public final class ZenModeAppsPreferenceControllerTest { @Mock private ZenModesBackend mBackend; private ZenModeAppsPreferenceController mPriorityController; - private ZenModeAppsPreferenceController mAllController; private ZenModeAppsPreferenceController mNoneController; private SelectorWithWidgetPreference mPriorityPref; - private SelectorWithWidgetPreference mAllPref; private SelectorWithWidgetPreference mNonePref; private PreferenceCategory mPrefCategory; private PreferenceScreen mPreferenceScreen; @@ -81,10 +78,8 @@ public final class ZenModeAppsPreferenceControllerTest { mPriorityController = new ZenModeAppsPreferenceController(mContext, KEY_PRIORITY, mBackend); mNoneController = new ZenModeAppsPreferenceController(mContext, KEY_NONE, mBackend); - mAllController = new ZenModeAppsPreferenceController(mContext, KEY_ALL, mBackend); mPriorityPref = makePreference(KEY_PRIORITY, mPriorityController); - mAllPref = makePreference(KEY_ALL, mAllController); mNonePref = makePreference(KEY_NONE, mNoneController); mPrefCategory = new PreferenceCategory(mContext); @@ -95,10 +90,8 @@ public final class ZenModeAppsPreferenceControllerTest { mPreferenceScreen.addPreference(mPrefCategory); mPrefCategory.addPreference(mPriorityPref); - mPrefCategory.addPreference(mAllPref); mPrefCategory.addPreference(mNonePref); - mAllController.displayPreference(mPreferenceScreen); mPriorityController.displayPreference(mPreferenceScreen); mNoneController.displayPreference(mPreferenceScreen); } @@ -111,36 +104,6 @@ public final class ZenModeAppsPreferenceControllerTest { return pref; } - @Test - public void testUpdateState_All() { - TwoStatePreference preference = mock(TwoStatePreference.class); - ZenMode zenMode = new ZenMode("id", - new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) - .setType(AutomaticZenRule.TYPE_DRIVING) - .setZenPolicy(new ZenPolicy.Builder() - .allowChannels(ZenMode.CHANNEL_POLICY_ALL) - .build()) - .build(), true); - mAllController.updateZenMode(preference, zenMode); - - verify(preference).setChecked(true); - } - - @Test - public void testUpdateState_All_Unchecked() { - TwoStatePreference preference = mock(TwoStatePreference.class); - ZenMode zenMode = new ZenMode("id", - new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) - .setType(AutomaticZenRule.TYPE_DRIVING) - .setZenPolicy(new ZenPolicy.Builder() - .allowChannels(ZenPolicy.CHANNEL_POLICY_NONE) - .build()) - .build(), true); - mAllController.updateZenMode(preference, zenMode); - - verify(preference).setChecked(false); - } - @Test public void testUpdateState_None() { TwoStatePreference preference = mock(TwoStatePreference.class); @@ -163,7 +126,7 @@ public final class ZenModeAppsPreferenceControllerTest { new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) .setType(AutomaticZenRule.TYPE_DRIVING) .setZenPolicy(new ZenPolicy.Builder() - .allowChannels(ZenMode.CHANNEL_POLICY_ALL) + .allowChannels(ZenPolicy.CHANNEL_POLICY_PRIORITY) .build()) .build(), true); mNoneController.updateZenMode(preference, zenMode); @@ -201,67 +164,6 @@ public final class ZenModeAppsPreferenceControllerTest { verify(preference).setChecked(false); } - @Test - public void testOnPreferenceChange_All() { - TwoStatePreference preference = mock(TwoStatePreference.class); - ZenMode zenMode = new ZenMode("id", - new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) - .setType(AutomaticZenRule.TYPE_DRIVING) - .setInterruptionFilter(INTERRUPTION_FILTER_NONE) - .setZenPolicy(new ZenPolicy.Builder() - .allowChannels(ZenMode.CHANNEL_POLICY_ALL) - .build()) - .build(), true); - - mAllController.updateZenMode(preference, zenMode); - mAllController.onPreferenceChange(preference, true); - ArgumentCaptor captor = ArgumentCaptor.forClass(ZenMode.class); - verify(mBackend).updateMode(captor.capture()); - - assertThat(captor.getValue().getPolicy().getAllowedChannels()) - .isEqualTo(ZenMode.CHANNEL_POLICY_ALL); - } - - @Test - public void testPreferenceClick_passesCorrectCheckedState_All() { - ZenMode zenMode = new ZenMode("id", - new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) - .setType(AutomaticZenRule.TYPE_DRIVING) - .setZenPolicy(new ZenPolicy.Builder() - .allowChannels(ZenPolicy.CHANNEL_POLICY_NONE) - .build()) - .build(), true); - - - mAllController.updateZenMode(mAllPref, zenMode); - mNoneController.updateZenMode(mNonePref, zenMode); - mPriorityController.updateZenMode(mPriorityPref, zenMode); - - // MPME is checked; ALL and PRIORITY are unchecked. - assertThat(((SelectorWithWidgetPreference) mPrefCategory.findPreference(KEY_NONE)) - .isChecked()); - assertThat(!((SelectorWithWidgetPreference) mPrefCategory.findPreference(KEY_ALL)) - .isChecked()); - assertThat(!((SelectorWithWidgetPreference) mPrefCategory.findPreference(KEY_PRIORITY)) - .isChecked()); - - mPrefCategory.findPreference(KEY_ALL).performClick(); - - ArgumentCaptor captor = ArgumentCaptor.forClass(ZenMode.class); - verify(mBackend).updateMode(captor.capture()); - // Checks the policy value for ALL is set. - // The important part is that the interruption filter is propagated to the backend. - assertThat(captor.getValue().getRule().getInterruptionFilter()) - .isEqualTo(INTERRUPTION_FILTER_ALL); - // ALL is now checked; others are unchecked. - assertThat(((SelectorWithWidgetPreference) mPrefCategory.findPreference(KEY_ALL)) - .isChecked()); - assertThat(!((SelectorWithWidgetPreference) mPrefCategory.findPreference(KEY_NONE)) - .isChecked()); - assertThat(!((SelectorWithWidgetPreference) mPrefCategory.findPreference(KEY_PRIORITY)) - .isChecked()); - } - @Test public void testPreferenceClick_passesCorrectCheckedState_None() { ZenMode zenMode = new ZenMode("id", @@ -272,12 +174,9 @@ public final class ZenModeAppsPreferenceControllerTest { .build()) .build(), true); - mAllController.updateZenMode(mAllPref, zenMode); mNoneController.updateZenMode(mNonePref, zenMode); mPriorityController.updateZenMode(mPriorityPref, zenMode); - assertThat(((SelectorWithWidgetPreference) mPrefCategory.findPreference(KEY_ALL)) - .isChecked()); assertThat(!((SelectorWithWidgetPreference) mPrefCategory.findPreference(KEY_NONE)) .isChecked()); assertThat(!((SelectorWithWidgetPreference) mPrefCategory.findPreference(KEY_PRIORITY)) @@ -296,8 +195,6 @@ public final class ZenModeAppsPreferenceControllerTest { // NONE is now checked; others are unchecked. assertThat(((SelectorWithWidgetPreference) mPrefCategory.findPreference(KEY_NONE)) .isChecked()); - assertThat(!((SelectorWithWidgetPreference) mPrefCategory.findPreference(KEY_ALL)) - .isChecked()); assertThat(!((SelectorWithWidgetPreference) mPrefCategory.findPreference(KEY_PRIORITY)) .isChecked()); } @@ -312,14 +209,11 @@ public final class ZenModeAppsPreferenceControllerTest { .build()) .build(), true); - mAllController.updateZenMode(mAllPref, zenMode); mNoneController.updateZenMode(mNonePref, zenMode); mPriorityController.updateZenMode(mPriorityPref, zenMode); assertThat(((SelectorWithWidgetPreference) mPrefCategory.findPreference(KEY_NONE)) .isChecked()); - assertThat(!((SelectorWithWidgetPreference) mPrefCategory.findPreference(KEY_ALL)) - .isChecked()); assertThat(!((SelectorWithWidgetPreference) mPrefCategory.findPreference(KEY_PRIORITY)) .isChecked()); @@ -334,8 +228,6 @@ public final class ZenModeAppsPreferenceControllerTest { // PRIORITY is now checked; others are unchecked. assertThat(((SelectorWithWidgetPreference) mPrefCategory.findPreference(KEY_PRIORITY)) .isChecked()); - assertThat(!((SelectorWithWidgetPreference) mPrefCategory.findPreference(KEY_ALL)) - .isChecked()); assertThat(!((SelectorWithWidgetPreference) mPrefCategory.findPreference(KEY_NONE)) .isChecked()); } diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeTest.java index 05286212e12..37b71a5ba34 100644 --- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeTest.java +++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeTest.java @@ -70,18 +70,6 @@ public class ZenModeTest { assertThat(zenMode.getPolicy()).isEqualTo(ZEN_POLICY); } - @Test - public void getPolicy_interruptionFilterAll_returnsPolicyAllowingAll() { - ZenMode zenMode = new ZenMode("id", new AutomaticZenRule.Builder("Rule", Uri.EMPTY) - .setInterruptionFilter(INTERRUPTION_FILTER_ALL) - .setZenPolicy(ZEN_POLICY) // should be ignored - .build(), false); - - assertThat(zenMode.getPolicy()).isEqualTo( - new ZenPolicy.Builder().allowChannels(ZenMode.CHANNEL_POLICY_ALL) - .allowAllSounds().showAllVisualEffects().build()); - } - @Test public void getPolicy_interruptionFilterAlarms_returnsPolicyAllowingAlarms() { ZenMode zenMode = new ZenMode("id", new AutomaticZenRule.Builder("Rule", Uri.EMPTY) @@ -126,69 +114,4 @@ public class ZenModeTest { assertThat(zenMode.getPolicy()).isEqualTo(ZEN_POLICY); assertThat(zenMode.getRule().getZenPolicy()).isEqualTo(ZEN_POLICY); } - - @Test - public void setPolicy_withAllChannelsAllowed_setsInterruptionFilterAll() { - ZenMode zenMode = new ZenMode("id", new AutomaticZenRule.Builder("Rule", Uri.EMPTY) - .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS) - .setZenPolicy(ZEN_POLICY) - .build(), false); - - zenMode.setPolicy( - new ZenPolicy.Builder().allowChannels(ZenMode.CHANNEL_POLICY_ALL).build()); - - assertThat(zenMode.getRule().getInterruptionFilter()).isEqualTo(INTERRUPTION_FILTER_ALL); - assertThat(zenMode.getPolicy()).isEqualTo( - new ZenPolicy.Builder().allowChannels(ZenMode.CHANNEL_POLICY_ALL) - .allowAllSounds().showAllVisualEffects().build()); - } - - @Test - public void setPolicy_priorityToAllChannelsAndBack_restoresOldPolicy() { - ZenMode zenMode = new ZenMode("id", new AutomaticZenRule.Builder("Rule", Uri.EMPTY) - .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) - .setZenPolicy(ZEN_POLICY) - .build(), false); - - zenMode.setPolicy( - new ZenPolicy.Builder().allowChannels(ZenMode.CHANNEL_POLICY_ALL).build()); - assertThat(zenMode.getRule().getInterruptionFilter()).isEqualTo(INTERRUPTION_FILTER_ALL); - assertThat(zenMode.getPolicy()).isEqualTo( - new ZenPolicy.Builder().allowChannels(ZenMode.CHANNEL_POLICY_ALL) - .allowAllSounds().showAllVisualEffects().build()); - - zenMode.setPolicy( - new ZenPolicy.Builder().allowChannels(ZenPolicy.CHANNEL_POLICY_PRIORITY).build()); - - assertThat(zenMode.getRule().getInterruptionFilter()).isEqualTo( - INTERRUPTION_FILTER_PRIORITY); - assertThat(zenMode.getPolicy()).isEqualTo(ZEN_POLICY); - assertThat(zenMode.getRule().getZenPolicy()).isEqualTo(ZEN_POLICY); - } - - @Test - public void setPolicy_alarmsOnlyToAllChannelsAndBack_restoresPolicySimilarToAlarmsOnly() { - ZenMode zenMode = new ZenMode("id", new AutomaticZenRule.Builder("Rule", Uri.EMPTY) - .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS) - .build(), false); - - zenMode.setPolicy( - new ZenPolicy.Builder().allowChannels(ZenMode.CHANNEL_POLICY_ALL).build()); - assertThat(zenMode.getRule().getInterruptionFilter()).isEqualTo(INTERRUPTION_FILTER_ALL); - assertThat(zenMode.getPolicy()).isEqualTo( - new ZenPolicy.Builder().allowChannels(ZenMode.CHANNEL_POLICY_ALL) - .allowAllSounds().showAllVisualEffects().build()); - - zenMode.setPolicy( - new ZenPolicy.Builder().allowChannels(ZenPolicy.CHANNEL_POLICY_PRIORITY).build()); - - // We don't go back to ALARMS, but the policy must be the one the user was seeing before. - ZenPolicy alarmsOnlyLikePolicy = new ZenPolicy.Builder().disallowAllSounds() - .allowAlarms(true).allowMedia(true).allowPriorityChannels(false) - .build(); - assertThat(zenMode.getRule().getInterruptionFilter()).isEqualTo( - INTERRUPTION_FILTER_PRIORITY); - assertThat(zenMode.getPolicy()).isEqualTo(alarmsOnlyLikePolicy); - assertThat(zenMode.getRule().getZenPolicy()).isEqualTo(alarmsOnlyLikePolicy); - } } diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModesSummaryHelperTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModesSummaryHelperTest.java index 13ae4eb108b..51368c557ef 100644 --- a/tests/robotests/src/com/android/settings/notification/modes/ZenModesSummaryHelperTest.java +++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModesSummaryHelperTest.java @@ -331,20 +331,6 @@ public class ZenModesSummaryHelperTest { "Notifications partially hidden, grayscale, and 2 more"); } - @Test - public void getAppsSummary_all() { - AutomaticZenRule rule = new AutomaticZenRule.Builder("Bedtime", Uri.parse("bed")) - .setType(AutomaticZenRule.TYPE_BEDTIME) - .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) - .setZenPolicy(new ZenPolicy.Builder() - .allowChannels(ZenMode.CHANNEL_POLICY_ALL) - .build()) - .build(); - ZenMode zenMode = new ZenMode("id", rule, true); - - assertThat(mSummaryHelper.getAppsSummary(zenMode, new LinkedHashSet<>())).isEqualTo("All"); - } - @Test public void getAppsSummary_none() { AutomaticZenRule rule = new AutomaticZenRule.Builder("Bedtime", Uri.parse("bed"))