From a4c99767b7277d0e0ff801427eb196267eb90603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Hern=C3=A1ndez?= Date: Thu, 1 Aug 2024 20:47:50 +0200 Subject: [PATCH] Overhaul the message senders screen * Fix combinations of messages=all with other conversation values. * Correctly display policies with CONVERSATION_SENDERS_ANYONE. An additional checkbox is included, but _only_ if the policy has CONVERSATION_SENDERS_ANYONE when shown. * Changed updateState() to consider the possible cases one by one. Because multiple policies are mapped to the same checkbox states, the strategy of "checking whether the state matches what the checkbox wants to set" doesn't really work. * Fix messages summary and circles to support CONVERSATION_SENDERS_ANYONE. * Added a lot of tests (actually, hopefully ALL OF THEM) covering the user-visible behavior. :) Fixes: 354658240 Test: atest ZenModesSummaryHelperTest ZenModePrioritySendersPreferenceControllerTest Flag: android.app.modes_ui Change-Id: I727496ca3eb820e4baaab942b61d2e57cdb491fc --- res/values/strings.xml | 2 + .../notification/modes/ZenHelperBackend.java | 12 +- ...ZenModePeopleLinkPreferenceController.java | 5 +- ...dePrioritySendersPreferenceController.java | 162 +- .../modes/ZenModeSummaryHelper.java | 34 +- ...ioritySendersPreferenceControllerTest.java | 1407 ++++++++++++++--- .../modes/ZenModesSummaryHelperTest.java | 56 + 7 files changed, 1368 insertions(+), 310 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 28e1f05d584..a0fa1708b65 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -9177,6 +9177,8 @@ Conversations All conversations + + all conversations Priority conversations priority conversations diff --git a/src/com/android/settings/notification/modes/ZenHelperBackend.java b/src/com/android/settings/notification/modes/ZenHelperBackend.java index a2c3578af07..bf9167873cd 100644 --- a/src/com/android/settings/notification/modes/ZenHelperBackend.java +++ b/src/com/android/settings/notification/modes/ZenHelperBackend.java @@ -81,12 +81,20 @@ class ZenHelperBackend { } } - @SuppressWarnings("unchecked") + ImmutableList getAllConversations() { + return getConversations(false); + } + ImmutableList getImportantConversations() { + return getConversations(true); + } + + @SuppressWarnings("unchecked") + private ImmutableList getConversations(boolean onlyImportant) { try { ImmutableList.Builder list = new ImmutableList.Builder<>(); ParceledListSlice parceledList = mInm.getConversations( - /* onlyImportant= */ true); + onlyImportant); if (parceledList != null) { for (ConversationChannelWrapper conversation : parceledList.getList()) { if (!conversation.getNotificationChannel().isDemoted()) { diff --git a/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceController.java b/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceController.java index 0d3a7219099..4610c35ca82 100644 --- a/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceController.java +++ b/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceController.java @@ -189,8 +189,7 @@ class ZenModePeopleLinkPreferenceController extends AbstractZenModePreferenceCon : CONVERSATION_SENDERS_NONE; ImmutableList conversationsAllowed = ImmutableList.of(); if (conversationSendersAllowed == CONVERSATION_SENDERS_ANYONE) { - // TODO: b/354658240 - Need to handle CONVERSATION_SENDERS_ANYONE? - return; + conversationsAllowed = mHelperBackend.getAllConversations(); } else if (conversationSendersAllowed == CONVERSATION_SENDERS_IMPORTANT) { conversationsAllowed = mHelperBackend.getImportantConversations(); } @@ -223,7 +222,7 @@ class ZenModePeopleLinkPreferenceController extends AbstractZenModePreferenceCon peopleItem.conversation.getShortcutInfo(), peopleItem.conversation.getPkg(), peopleItem.conversation.getUid(), - /* important= */ true); + peopleItem.conversation.getNotificationChannel().isImportantConversation()); } else { throw new IllegalArgumentException("Neither all nor contact nor conversation!"); } diff --git a/src/com/android/settings/notification/modes/ZenModePrioritySendersPreferenceController.java b/src/com/android/settings/notification/modes/ZenModePrioritySendersPreferenceController.java index 32c6a9881f0..ab5e2d9e56b 100644 --- a/src/com/android/settings/notification/modes/ZenModePrioritySendersPreferenceController.java +++ b/src/com/android/settings/notification/modes/ZenModePrioritySendersPreferenceController.java @@ -26,6 +26,8 @@ import static android.service.notification.ZenPolicy.PEOPLE_TYPE_NONE; import static android.service.notification.ZenPolicy.PEOPLE_TYPE_STARRED; import static android.service.notification.ZenPolicy.PEOPLE_TYPE_UNSET; +import static com.google.common.base.Preconditions.checkNotNull; + import android.app.settings.SettingsEnums; import android.content.Context; import android.content.Intent; @@ -36,7 +38,6 @@ import android.service.notification.ZenPolicy; import android.view.View; import androidx.annotation.NonNull; -import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceScreen; @@ -48,11 +49,13 @@ import com.android.settingslib.notification.modes.ZenMode; import com.android.settingslib.notification.modes.ZenModesBackend; import com.android.settingslib.widget.SelectorWithWidgetPreference; -import java.util.ArrayList; +import com.google.common.collect.ImmutableSet; + import java.util.HashMap; -import java.util.List; +import java.util.LinkedHashMap; import java.util.Locale; import java.util.Map; +import java.util.Set; /** * Common preference controller functionality for zen mode priority senders preferences for both @@ -69,9 +72,11 @@ class ZenModePrioritySendersPreferenceController static final String KEY_ANY = "senders_anyone"; static final String KEY_CONTACTS = "senders_contacts"; static final String KEY_STARRED = "senders_starred_contacts"; - static final String KEY_IMPORTANT = "conversations_important"; + static final String KEY_IMPORTANT_CONVERSATIONS = "conversations_important"; + static final String KEY_ANY_CONVERSATIONS = "conversations_any"; static final String KEY_NONE = "senders_none"; + private int mNumAllConversations = 0; private int mNumImportantConversations = 0; private static final Intent ALL_CONTACTS_INTENT = @@ -86,7 +91,8 @@ class ZenModePrioritySendersPreferenceController private final ZenHelperBackend mHelperBackend; private final PackageManager mPackageManager; private PreferenceCategory mPreferenceCategory; - private List mSelectorPreferences = new ArrayList<>(); + private final LinkedHashMap mOptions = + new LinkedHashMap<>(); private final ZenModeSummaryHelper mZenModeSummaryHelper; @@ -110,53 +116,92 @@ class ZenModePrioritySendersPreferenceController @Override public void displayPreference(PreferenceScreen screen) { - mPreferenceCategory = screen.findPreference(getPreferenceKey()); + mPreferenceCategory = checkNotNull(screen.findPreference(getPreferenceKey())); if (mPreferenceCategory.getPreferenceCount() == 0) { makeSelectorPreference(KEY_STARRED, - com.android.settings.R.string.zen_mode_from_starred, mIsMessages); + com.android.settings.R.string.zen_mode_from_starred, mIsMessages, true); makeSelectorPreference(KEY_CONTACTS, - com.android.settings.R.string.zen_mode_from_contacts, mIsMessages); + com.android.settings.R.string.zen_mode_from_contacts, mIsMessages, true); if (mIsMessages) { - makeSelectorPreference(KEY_IMPORTANT, - com.android.settings.R.string.zen_mode_from_important_conversations, true); + // "Any conversations" will only be available as option if it is the current value. + // Because it's confusing and we don't want users setting it up that way, but apps + // could create such ZenPolicies and we must show that. + makeSelectorPreference(KEY_ANY_CONVERSATIONS, + com.android.settings.R.string.zen_mode_from_all_conversations, true, + /* isVisibleByDefault= */ false); + makeSelectorPreference(KEY_IMPORTANT_CONVERSATIONS, + com.android.settings.R.string.zen_mode_from_important_conversations, true, + true); } makeSelectorPreference(KEY_ANY, - com.android.settings.R.string.zen_mode_from_anyone, mIsMessages); + com.android.settings.R.string.zen_mode_from_anyone, mIsMessages, true); makeSelectorPreference(KEY_NONE, - com.android.settings.R.string.zen_mode_none_messages, mIsMessages); + com.android.settings.R.string.zen_mode_none_messages, mIsMessages, true); } super.displayPreference(screen); } @Override public void updateState(Preference preference, @NonNull ZenMode zenMode) { + final int contacts = getPrioritySenders(zenMode.getPolicy()); + final int conversations = getPriorityConversationSenders(zenMode.getPolicy()); + if (mIsMessages) { updateChannelCounts(); - } - final int currContactsSetting = getPrioritySenders(zenMode.getPolicy()); - final int currConversationsSetting = getPriorityConversationSenders(zenMode.getPolicy()); - for (SelectorWithWidgetPreference pref : mSelectorPreferences) { - // for each preference, check whether the current state matches what this state - // would look like if the button were checked. - final int[] checkedState = keyToSettingEndState(pref.getKey(), true); - final int checkedContactsSetting = checkedState[0]; - final int checkedConversationsSetting = checkedState[1]; - boolean match = checkedContactsSetting == currContactsSetting; - if (mIsMessages && checkedConversationsSetting != CONVERSATION_SENDERS_UNSET) { - // "CONVERSATION_SENDERS_UNSET" in checkedContactsSetting means this preference - // doesn't govern the priority senders setting, so the full match happens when - // either the priority senders setting matches or if it's CONVERSATION_SENDERS_UNSET - // so only the conversation setting needs to match. - match = (match || checkedContactsSetting == PEOPLE_TYPE_UNSET) - && (checkedConversationsSetting == currConversationsSetting); + if (contacts == PEOPLE_TYPE_ANYONE) { + setSelectedOption(KEY_ANY); + } else if (contacts == PEOPLE_TYPE_NONE && conversations == CONVERSATION_SENDERS_NONE) { + setSelectedOption(KEY_NONE); + } else { + ImmutableSet.Builder selectedOptions = new ImmutableSet.Builder<>(); + if (contacts == PEOPLE_TYPE_STARRED) { + selectedOptions.add(KEY_STARRED); + } else if (contacts == PEOPLE_TYPE_CONTACTS) { + selectedOptions.add(KEY_CONTACTS); + } + if (conversations == CONVERSATION_SENDERS_IMPORTANT) { + selectedOptions.add(KEY_IMPORTANT_CONVERSATIONS); + } else if (conversations == CONVERSATION_SENDERS_ANYONE) { + selectedOptions.add(KEY_ANY_CONVERSATIONS); + } + setSelectedOptions(selectedOptions.build()); + } + } else { + // Calls is easy! + switch (contacts) { + case PEOPLE_TYPE_ANYONE -> setSelectedOption(KEY_ANY); + case PEOPLE_TYPE_CONTACTS -> setSelectedOption(KEY_CONTACTS); + case PEOPLE_TYPE_STARRED -> setSelectedOption(KEY_STARRED); + case PEOPLE_TYPE_NONE -> setSelectedOption(KEY_NONE); + default -> throw new IllegalArgumentException("Unexpected PeopleType: " + contacts); } - - pref.setChecked(match); } + updateSummaries(); } + private void setSelectedOption(String key) { + setSelectedOptions(ImmutableSet.of(key)); + } + + private void setSelectedOptions(Set keys) { + if (keys.isEmpty()) { + throw new IllegalArgumentException("At least one option should be selected!"); + } + + for (SelectorWithWidgetPreference optionPreference : mOptions.values()) { + optionPreference.setChecked(keys.contains(optionPreference.getKey())); + if (optionPreference.isChecked()) { + // Ensure selected options are visible. This is to support "Any conversations" + // which is only shown if the policy has Conversations=Anyone (and doesn't have + // messages=Anyone), and then remains visible until the user exits the page + // (so that toggling back and forth is possible without the option disappearing). + optionPreference.setVisible(true); + } + } + } + public void onResume() { if (mIsMessages) { updateChannelCounts(); @@ -165,6 +210,7 @@ class ZenModePrioritySendersPreferenceController } private void updateChannelCounts() { + mNumAllConversations = mHelperBackend.getAllConversations().size(); mNumImportantConversations = mHelperBackend.getImportantConversations().size(); } @@ -183,13 +229,14 @@ class ZenModePrioritySendersPreferenceController return CONVERSATION_SENDERS_UNSET; } - private SelectorWithWidgetPreference makeSelectorPreference(String key, int titleId, - boolean isCheckbox) { + private void makeSelectorPreference(String key, int titleId, + boolean isCheckbox, boolean isVisibleByDefault) { final SelectorWithWidgetPreference pref = new SelectorWithWidgetPreference(mPreferenceCategory.getContext(), isCheckbox); pref.setKey(key); pref.setTitle(titleId); pref.setOnClickListener(mSelectorClickListener); + pref.setVisible(isVisibleByDefault); View.OnClickListener widgetClickListener = getWidgetClickListener(key); if (widgetClickListener != null) { @@ -197,12 +244,12 @@ class ZenModePrioritySendersPreferenceController } mPreferenceCategory.addPreference(pref); - mSelectorPreferences.add(pref); - return pref; + mOptions.put(key, pref); } private View.OnClickListener getWidgetClickListener(String key) { - if (!KEY_CONTACTS.equals(key) && !KEY_STARRED.equals(key) && !KEY_IMPORTANT.equals(key)) { + if (!KEY_CONTACTS.equals(key) && !KEY_STARRED.equals(key) + && !KEY_ANY_CONVERSATIONS.equals(key) && !KEY_IMPORTANT_CONVERSATIONS.equals(key)) { return null; } @@ -221,7 +268,8 @@ class ZenModePrioritySendersPreferenceController } else if (KEY_CONTACTS.equals(key) && ALL_CONTACTS_INTENT.resolveActivity(mPackageManager) != null) { mContext.startActivity(ALL_CONTACTS_INTENT); - } else if (KEY_IMPORTANT.equals(key)) { + } else if (KEY_ANY_CONVERSATIONS.equals(key) + || KEY_IMPORTANT_CONVERSATIONS.equals(key)) { // TODO: b/332937635 - set correct metrics category new SubSettingLauncher(mContext) .setDestination(ConversationListSettings.class.getName()) @@ -244,7 +292,7 @@ class ZenModePrioritySendersPreferenceController } void updateSummaries() { - for (SelectorWithWidgetPreference pref : mSelectorPreferences) { + for (SelectorWithWidgetPreference pref : mOptions.values()) { pref.setSummary(getSummary(pref.getKey())); } } @@ -255,7 +303,7 @@ class ZenModePrioritySendersPreferenceController // Returns an integer array with 2 entries. The first entry is the setting for priority senders // and the second entry is for priority conversation senders; if isMessages is false, then // no changes will ever be prescribed for conversation senders. - int[] keyToSettingEndState(String key, boolean checked) { + private int[] keyToSettingEndState(String key, boolean checked) { int[] endState = new int[]{ PEOPLE_TYPE_UNSET, CONVERSATION_SENDERS_UNSET }; if (!checked) { // Unchecking any priority-senders-based state should reset the state to NONE. @@ -268,11 +316,12 @@ class ZenModePrioritySendersPreferenceController endState[0] = PEOPLE_TYPE_NONE; } - // For messages, unchecking "priority conversations" and "any" should reset conversation - // state to "NONE" as well. + // For messages, unchecking "priority/any conversations" and "any" should reset + // conversation state to "NONE" as well. if (mIsMessages) { switch (key) { - case KEY_IMPORTANT: + case KEY_IMPORTANT_CONVERSATIONS: + case KEY_ANY_CONVERSATIONS: case KEY_ANY: case KEY_NONE: endState[1] = CONVERSATION_SENDERS_NONE; @@ -297,9 +346,10 @@ class ZenModePrioritySendersPreferenceController // In the messages case *only*, also handle changing of conversation settings. if (mIsMessages) { switch (key) { - case KEY_IMPORTANT: + case KEY_IMPORTANT_CONVERSATIONS: endState[1] = CONVERSATION_SENDERS_IMPORTANT; break; + case KEY_ANY_CONVERSATIONS: case KEY_ANY: endState[1] = CONVERSATION_SENDERS_ANYONE; break; @@ -335,7 +385,7 @@ class ZenModePrioritySendersPreferenceController // the contacts setting is additionally reset to "none". // - if "anyone" is previously selected, and the user clicks one of the contacts values, // then the conversations setting is additionally reset to "none". - int[] settingsToSaveOnClick(String key, boolean checked, + private int[] settingsToSaveOnClick(String key, boolean checked, int currSendersSetting, int currConvosSetting) { int[] savedSettings = new int[]{ PEOPLE_TYPE_UNSET, CONVERSATION_SENDERS_UNSET }; @@ -360,15 +410,18 @@ class ZenModePrioritySendersPreferenceController // Special-case handling for the "priority conversations" checkbox: // If a specific selection exists for priority senders (starred, contacts), we leave // it untouched. Otherwise (when the senders is set to "any"), set it to NONE. - if (key.equals(KEY_IMPORTANT) + if ((key.equals(KEY_IMPORTANT_CONVERSATIONS) || key.equals(KEY_ANY_CONVERSATIONS)) && currSendersSetting == PEOPLE_TYPE_ANYONE) { savedSettings[0] = PEOPLE_TYPE_NONE; } - // Flip-side special case for clicking either "contacts" option: if a specific selection - // exists for priority conversations, leave it untouched; otherwise, set to none. + // The flip-side case for the "contacts" option is slightly different -- we only + // reset conversations if leaving PEOPLE_ANY by selecting a contact option, but not + // if switching contact options. That's because starting from Anyone, checking Contacts, + // and then "important conversations" also shown checked because it was there (albeit + // subsumed into PEOPLE_ANY) would be weird. if ((key.equals(KEY_STARRED) || key.equals(KEY_CONTACTS)) - && currConvosSetting == CONVERSATION_SENDERS_ANYONE) { + && currSendersSetting == PEOPLE_TYPE_ANYONE) { savedSettings[1] = CONVERSATION_SENDERS_NONE; } } @@ -382,8 +435,10 @@ class ZenModePrioritySendersPreferenceController return mZenModeSummaryHelper.getStarredContactsSummary(); case KEY_CONTACTS: return mZenModeSummaryHelper.getContactsNumberSummary(); - case KEY_IMPORTANT: - return getConversationSummary(); + case KEY_ANY_CONVERSATIONS: + return getConversationSummary(mNumAllConversations); + case KEY_IMPORTANT_CONVERSATIONS: + return getConversationSummary(mNumImportantConversations); case KEY_ANY: return mContext.getResources().getString(mIsMessages ? R.string.zen_mode_all_messages_summary @@ -394,9 +449,7 @@ class ZenModePrioritySendersPreferenceController } } - private String getConversationSummary() { - final int numConversations = mNumImportantConversations; - + private String getConversationSummary(int numConversations) { if (numConversations == CONVERSATION_SENDERS_UNSET) { return null; } else { @@ -409,8 +462,7 @@ class ZenModePrioritySendersPreferenceController } } - @VisibleForTesting - SelectorWithWidgetPreference.OnClickListener mSelectorClickListener = + private final SelectorWithWidgetPreference.OnClickListener mSelectorClickListener = new SelectorWithWidgetPreference.OnClickListener() { @Override public void onRadioButtonClicked(SelectorWithWidgetPreference preference) { diff --git a/src/com/android/settings/notification/modes/ZenModeSummaryHelper.java b/src/com/android/settings/notification/modes/ZenModeSummaryHelper.java index 1acef20ac6c..7a16d91d743 100644 --- a/src/com/android/settings/notification/modes/ZenModeSummaryHelper.java +++ b/src/com/android/settings/notification/modes/ZenModeSummaryHelper.java @@ -140,6 +140,14 @@ class ZenModeSummaryHelper { } String getMessagesSettingSummary(ZenPolicy policy) { + if (policy.getPriorityCategoryMessages() == STATE_ALLOW + && policy.getPriorityMessageSenders() == PEOPLE_TYPE_ANYONE) { + // Messages=anyone means anyone. Even if conversation senders is specially configured, + // saying "Anyone and priority conversations" 1) makes no sense and 2) is incorrect + // because conversations WILL get through by virtue of also being messages. + return mContext.getString(R.string.zen_mode_from_anyone); + } + List enabledCategories = getEnabledCategories(policy, category -> PRIORITY_CATEGORY_MESSAGES == category || PRIORITY_CATEGORY_CONVERSATIONS == category, true); @@ -278,10 +286,11 @@ class ZenModeSummaryHelper { continue; } - // For conversations, only the "priority conversations" setting is relevant; any - // other setting is subsumed by the messages-specific messaging. + // For conversations, only the "all/priority conversations" settings are relevant; + // any other setting is subsumed by the messages-specific messaging. if (category == PRIORITY_CATEGORY_CONVERSATIONS && policy.isCategoryAllowed(PRIORITY_CATEGORY_CONVERSATIONS, false) + && policy.getPriorityConversationSenders() != CONVERSATION_SENDERS_ANYONE && policy.getPriorityConversationSenders() != CONVERSATION_SENDERS_IMPORTANT) { continue; @@ -320,13 +329,20 @@ class ZenModeSummaryHelper { } else { return mContext.getString(R.string.zen_mode_from_starred); } - } else if (category == PRIORITY_CATEGORY_CONVERSATIONS - && policy.getPriorityConversationSenders() == CONVERSATION_SENDERS_IMPORTANT) { - if (isFirst) { - return mContext.getString(R.string.zen_mode_from_important_conversations); - } else { - return mContext.getString( - R.string.zen_mode_from_important_conversations_second); + } else if (category == PRIORITY_CATEGORY_CONVERSATIONS) { + if (policy.getPriorityConversationSenders() == CONVERSATION_SENDERS_IMPORTANT) { + if (isFirst) { + return mContext.getString(R.string.zen_mode_from_important_conversations); + } else { + return mContext.getString( + R.string.zen_mode_from_important_conversations_second); + } + } else if (policy.getPriorityConversationSenders() == CONVERSATION_SENDERS_ANYONE) { + if (isFirst) { + return mContext.getString(R.string.zen_mode_from_all_conversations); + } else { + return mContext.getString(R.string.zen_mode_from_all_conversations_second); + } } } else if (category == PRIORITY_CATEGORY_EVENTS) { if (isFirst) { diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModePrioritySendersPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModePrioritySendersPreferenceControllerTest.java index 64de1418ad6..eb570947d88 100644 --- a/tests/robotests/src/com/android/settings/notification/modes/ZenModePrioritySendersPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModePrioritySendersPreferenceControllerTest.java @@ -19,21 +19,23 @@ package com.android.settings.notification.modes; 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; -import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_UNSET; import static android.service.notification.ZenPolicy.PEOPLE_TYPE_ANYONE; import static android.service.notification.ZenPolicy.PEOPLE_TYPE_CONTACTS; import static android.service.notification.ZenPolicy.PEOPLE_TYPE_NONE; import static android.service.notification.ZenPolicy.PEOPLE_TYPE_STARRED; -import static android.service.notification.ZenPolicy.PEOPLE_TYPE_UNSET; -import static android.service.notification.ZenPolicy.STATE_UNSET; +import static android.service.notification.ZenPolicy.conversationTypeToString; +import static android.service.notification.ZenPolicy.peopleTypeToString; import static com.android.settings.notification.modes.ZenModePrioritySendersPreferenceController.KEY_ANY; +import static com.android.settings.notification.modes.ZenModePrioritySendersPreferenceController.KEY_ANY_CONVERSATIONS; import static com.android.settings.notification.modes.ZenModePrioritySendersPreferenceController.KEY_CONTACTS; -import static com.android.settings.notification.modes.ZenModePrioritySendersPreferenceController.KEY_IMPORTANT; +import static com.android.settings.notification.modes.ZenModePrioritySendersPreferenceController.KEY_IMPORTANT_CONVERSATIONS; import static com.android.settings.notification.modes.ZenModePrioritySendersPreferenceController.KEY_NONE; import static com.android.settings.notification.modes.ZenModePrioritySendersPreferenceController.KEY_STARRED; +import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -43,11 +45,14 @@ import android.content.Context; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.service.notification.ZenPolicy; +import android.service.notification.ZenPolicy.ConversationSenders; +import android.service.notification.ZenPolicy.PeopleType; import androidx.preference.Preference; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceManager; import androidx.preference.PreferenceScreen; +import androidx.preference.TwoStatePreference; import com.android.settingslib.notification.modes.TestModeBuilder; import com.android.settingslib.notification.modes.ZenMode; @@ -66,6 +71,9 @@ import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import java.util.function.Consumer; +import java.util.function.Predicate; + @RunWith(RobolectricTestRunner.class) @EnableFlags(Flags.FLAG_MODES_UI) public final class ZenModePrioritySendersPreferenceControllerTest { @@ -109,24 +117,30 @@ public final class ZenModePrioritySendersPreferenceControllerTest { when(mHelperBackend.getAllContacts()).thenReturn( ImmutableList.of(new ZenHelperBackend.Contact(1, "The only contact", null))); when(mHelperBackend.getAllContactsCount()).thenReturn(1); + when(mHelperBackend.getImportantConversations()).thenReturn(ImmutableList.of()); + when(mHelperBackend.getAllConversations()).thenReturn(ImmutableList.of()); } @Test public void testDisplayPreferences_makeMessagesPrefs() { mMessagesController.displayPreference(mPreferenceScreen); - // Starred contacts, Contacts, Priority Conversations, Any, None - assertThat(mMessagesPrefCategory.getPreferenceCount()).isEqualTo(5); + // "Any Conversations" is invisible by default. + assertThat(getAllOptions(mMessagesPrefCategory)).containsExactly(KEY_STARRED, KEY_CONTACTS, + KEY_ANY_CONVERSATIONS, KEY_IMPORTANT_CONVERSATIONS, KEY_ANY, KEY_NONE).inOrder(); + assertThat(getVisibleOptions(mMessagesPrefCategory)).containsExactly(KEY_STARRED, + KEY_CONTACTS, KEY_IMPORTANT_CONVERSATIONS, KEY_ANY, KEY_NONE).inOrder(); } @Test public void testDisplayPreferences_makeCallsPrefs() { mCallsController.displayPreference(mPreferenceScreen); - assertThat(mCallsPrefCategory.getPreferenceCount()).isEqualTo(4); - assertThat((Comparable) mCallsPrefCategory.findPreference(KEY_IMPORTANT)).isNull(); - + assertThat(getAllOptions(mCallsPrefCategory)).containsExactly(KEY_STARRED, KEY_CONTACTS, + KEY_ANY, KEY_NONE).inOrder(); + assertThat(getVisibleOptions(mCallsPrefCategory)).containsExactly(KEY_STARRED, KEY_CONTACTS, + KEY_ANY, KEY_NONE).inOrder(); } @Test @@ -143,287 +157,1198 @@ public final class ZenModePrioritySendersPreferenceControllerTest { } @Test - public void testKeyToSettingEndState_messagesCheck() { - int[] endState; + public void updateState_callsAny() { + ZenMode zenMode = newModeWithPolicy(p -> p.allowCalls(PEOPLE_TYPE_ANYONE)); + mCallsController.displayPreference(mPreferenceScreen); - // For KEY_NONE everything should be none. - endState = mMessagesController.keyToSettingEndState(KEY_NONE, true); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_NONE); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_NONE); + mCallsController.updateZenMode(mCallsPrefCategory, zenMode); - // For KEY_ANY everything should be allowed. - endState = mMessagesController.keyToSettingEndState(KEY_ANY, true); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_ANYONE); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_ANYONE); - - // For [starred] contacts, we should set the priority senders, but not the conversations - endState = mMessagesController.keyToSettingEndState(KEY_STARRED, true); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_STARRED); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); - - endState = mMessagesController.keyToSettingEndState(KEY_CONTACTS, true); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_CONTACTS); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); - - // For priority conversations, we should set the conversations but not priority senders - endState = mMessagesController.keyToSettingEndState(KEY_IMPORTANT, true); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_UNSET); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_IMPORTANT); + assertThat(getCheckedOptions(mCallsPrefCategory)).containsExactly(KEY_ANY); } @Test - public void testKeyToSettingEndState_messagesUncheck() { - int[] endState; + public void updateState_callsContacts() { + ZenMode zenMode = newModeWithPolicy(p -> p.allowCalls(PEOPLE_TYPE_CONTACTS)); + mCallsController.displayPreference(mPreferenceScreen); - // For KEY_NONE, "unchecking" still means "none". - endState = mMessagesController.keyToSettingEndState(KEY_NONE, false); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_NONE); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_NONE); + mCallsController.updateZenMode(mCallsPrefCategory, zenMode); - // For KEY_ANY unchecking resets the state to "none". - endState = mMessagesController.keyToSettingEndState(KEY_ANY, false); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_NONE); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_NONE); - - // For [starred] contacts, we should unset the priority senders, but not the conversations - endState = mMessagesController.keyToSettingEndState(KEY_STARRED, false); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_NONE); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); - - endState = mMessagesController.keyToSettingEndState(KEY_CONTACTS, false); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_NONE); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); - - // For priority conversations, we should set the conversations but not priority senders - endState = mMessagesController.keyToSettingEndState(KEY_IMPORTANT, false); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_UNSET); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_NONE); + assertThat(getCheckedOptions(mCallsPrefCategory)).containsExactly(KEY_CONTACTS); } @Test - public void testKeyToSettingEndState_callsCheck() { - int[] endState; + public void updateState_callsStarredContacts() { + ZenMode zenMode = newModeWithPolicy(p -> p.allowCalls(PEOPLE_TYPE_STARRED)); + mCallsController.displayPreference(mPreferenceScreen); - // For calls: we should never set conversations, as this is unrelated to calls. - // For KEY_NONE senders should be none. - endState = mCallsController.keyToSettingEndState(KEY_NONE, true); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_NONE); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); + mCallsController.updateZenMode(mCallsPrefCategory, zenMode); - // For KEY_ANY senders should be ANY. - endState = mCallsController.keyToSettingEndState(KEY_ANY, true); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_ANYONE); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); - - // For [starred] contacts, we should set the priority senders accordingly - endState = mCallsController.keyToSettingEndState(KEY_STARRED, true); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_STARRED); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); - - endState = mCallsController.keyToSettingEndState(KEY_CONTACTS, true); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_CONTACTS); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); + assertThat(getCheckedOptions(mCallsPrefCategory)).containsExactly(KEY_STARRED); } @Test - public void testKeyToSettingEndState_callsUncheck() { - int[] endState; + public void updateState_callsNone() { + ZenMode zenMode = newModeWithPolicy(p -> p.allowCalls(PEOPLE_TYPE_NONE)); + mCallsController.displayPreference(mPreferenceScreen); - // A calls setup should never set conversations settings. - // For KEY_NONE, "unchecking" still means "none". - endState = mCallsController.keyToSettingEndState(KEY_NONE, false); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_NONE); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); + mCallsController.updateZenMode(mCallsPrefCategory, zenMode); - // For KEY_ANY unchecking resets the state to "none". - endState = mCallsController.keyToSettingEndState(KEY_ANY, false); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_NONE); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); - - // For [starred] contacts, we should unset the priority senders, but not the conversations - endState = mCallsController.keyToSettingEndState(KEY_STARRED, false); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_NONE); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); - - endState = mCallsController.keyToSettingEndState(KEY_CONTACTS, false); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_NONE); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); + assertThat(getCheckedOptions(mCallsPrefCategory)).containsExactly(KEY_NONE); } @Test - public void testSettingsToSaveOnClick_messagesCheck() { - int[] endState; + public void updateState_msgAnyConvAny() { + ZenMode zenMode = newModeWithPolicy(p -> + p.allowMessages(PEOPLE_TYPE_ANYONE) + .allowConversations(CONVERSATION_SENDERS_ANYONE)); - // For KEY_NONE everything should be none. - endState = mMessagesController.settingsToSaveOnClick( - KEY_NONE, true, PEOPLE_TYPE_ANYONE, CONVERSATION_SENDERS_ANYONE); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_NONE); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_NONE); + mMessagesController.displayPreference(mPreferenceScreen); + mMessagesController.updateZenMode(mMessagesPrefCategory, zenMode); - // For KEY_ANY everything should be allowed. - endState = mMessagesController.settingsToSaveOnClick( - KEY_ANY, true, PEOPLE_TYPE_NONE, CONVERSATION_SENDERS_NONE); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_ANYONE); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_ANYONE); - - // For [starred] contacts, we should set the priority senders, but not the conversations - endState = mMessagesController.settingsToSaveOnClick( - KEY_STARRED, true, PEOPLE_TYPE_NONE, CONVERSATION_SENDERS_NONE); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_STARRED); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); - - endState = mMessagesController.settingsToSaveOnClick( - KEY_CONTACTS, true, PEOPLE_TYPE_NONE, CONVERSATION_SENDERS_NONE); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_CONTACTS); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); - - // For priority conversations, we should set the conversations but not priority senders - endState = mMessagesController.settingsToSaveOnClick( - KEY_IMPORTANT, true, PEOPLE_TYPE_NONE, CONVERSATION_SENDERS_NONE); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_UNSET); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_IMPORTANT); + // Messages=ANY shows ANY checked, regardless of conversations value (all conversations are + // messages and will get through). + assertThat(getVisibleOptions(mMessagesPrefCategory)).containsExactly( + KEY_ANY, KEY_STARRED, KEY_CONTACTS, KEY_IMPORTANT_CONVERSATIONS, KEY_NONE); + assertThat(getCheckedOptions(mMessagesPrefCategory)).containsExactly(KEY_ANY); } @Test - public void testSettingsToSaveOnClick_messagesUncheck() { - int[] endState; + public void updateState_msgAnyConvImportant() { + ZenMode zenMode = newModeWithPolicy(p -> + p.allowMessages(PEOPLE_TYPE_ANYONE) + .allowConversations(CONVERSATION_SENDERS_IMPORTANT)); - // For KEY_NONE, "unchecking" still means "none". - endState = mMessagesController.settingsToSaveOnClick( - KEY_NONE, false, PEOPLE_TYPE_NONE, CONVERSATION_SENDERS_NONE); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_UNSET); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); + mMessagesController.displayPreference(mPreferenceScreen); + mMessagesController.updateZenMode(mMessagesPrefCategory, zenMode); - // For KEY_ANY unchecking resets the state to "none". - endState = mMessagesController.settingsToSaveOnClick( - KEY_ANY, false, PEOPLE_TYPE_ANYONE, CONVERSATION_SENDERS_ANYONE); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_NONE); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_NONE); - - // For [starred] contacts, we should unset the priority senders, but not the conversations - endState = mMessagesController.settingsToSaveOnClick( - KEY_STARRED, false, PEOPLE_TYPE_STARRED, CONVERSATION_SENDERS_IMPORTANT); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_NONE); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); - - endState = mMessagesController.settingsToSaveOnClick( - KEY_CONTACTS, false, PEOPLE_TYPE_CONTACTS, CONVERSATION_SENDERS_IMPORTANT); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_NONE); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); - - // For priority conversations, we should set the conversations but not priority senders - endState = mMessagesController.settingsToSaveOnClick( - KEY_IMPORTANT, false, PEOPLE_TYPE_CONTACTS, CONVERSATION_SENDERS_IMPORTANT); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_UNSET); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_NONE); + // Messages=ANY shows ANY checked, regardless of conversations value (all conversations are + // messages and will get through). + assertThat(getVisibleOptions(mMessagesPrefCategory)).containsExactly( + KEY_ANY, KEY_STARRED, KEY_CONTACTS, KEY_IMPORTANT_CONVERSATIONS, KEY_NONE); + assertThat(getCheckedOptions(mMessagesPrefCategory)).containsExactly(KEY_ANY); } @Test - public void testSettingsToSaveOnClick_callsCheck() { - int[] endState; + public void updateState_msgAnyConvNone() { + ZenMode zenMode = newModeWithPolicy(p -> + p.allowMessages(PEOPLE_TYPE_ANYONE) + .allowConversations(CONVERSATION_SENDERS_NONE)); - // For calls: we should never set conversations, as this is unrelated to calls. - // For KEY_NONE senders should be none. - endState = mCallsController.settingsToSaveOnClick( - KEY_NONE, true, PEOPLE_TYPE_CONTACTS, CONVERSATION_SENDERS_IMPORTANT); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_NONE); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); + mMessagesController.displayPreference(mPreferenceScreen); + mMessagesController.updateZenMode(mMessagesPrefCategory, zenMode); - // For KEY_ANY senders should be ANY. - endState = mCallsController.settingsToSaveOnClick( - KEY_ANY, true, PEOPLE_TYPE_CONTACTS, CONVERSATION_SENDERS_IMPORTANT); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_ANYONE); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); - - // For [starred] contacts, we should set the priority senders accordingly - endState = mCallsController.settingsToSaveOnClick( - KEY_STARRED, true, PEOPLE_TYPE_CONTACTS, CONVERSATION_SENDERS_IMPORTANT); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_STARRED); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); - - endState = mCallsController.settingsToSaveOnClick( - KEY_CONTACTS, true, PEOPLE_TYPE_STARRED, CONVERSATION_SENDERS_IMPORTANT); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_CONTACTS); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); + // Messages=ANY shows ANY checked, regardless of conversations value (all conversations are + // messages and will get through). + assertThat(getVisibleOptions(mMessagesPrefCategory)).containsExactly( + KEY_ANY, KEY_STARRED, KEY_CONTACTS, KEY_IMPORTANT_CONVERSATIONS, KEY_NONE); + assertThat(getCheckedOptions(mMessagesPrefCategory)).containsExactly(KEY_ANY); } @Test - public void testSettingsToSaveOnClick_callsUncheck() { - int[] endState; + public void updateState_msgContactsConvAny() { + ZenMode zenMode = newModeWithPolicy(p -> + p.allowMessages(PEOPLE_TYPE_CONTACTS) + .allowConversations(CONVERSATION_SENDERS_ANYONE)); - // A calls setup should never set conversations settings. - // For KEY_NONE, "unchecking" still means "none". - endState = mCallsController.settingsToSaveOnClick( - KEY_NONE, false, PEOPLE_TYPE_NONE, CONVERSATION_SENDERS_NONE); - assertThat(endState[0]).isEqualTo(STATE_UNSET); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); + mMessagesController.displayPreference(mPreferenceScreen); + mMessagesController.updateZenMode(mMessagesPrefCategory, zenMode); - // For KEY_ANY unchecking resets the state to "none". - endState = mCallsController.settingsToSaveOnClick( - KEY_ANY, false, PEOPLE_TYPE_ANYONE, CONVERSATION_SENDERS_ANYONE); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_NONE); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); - - // For [starred] contacts, we should unset the priority senders, but not the conversations - endState = mCallsController.settingsToSaveOnClick( - KEY_STARRED, false, PEOPLE_TYPE_STARRED, CONVERSATION_SENDERS_IMPORTANT); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_NONE); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); - - endState = mCallsController.settingsToSaveOnClick( - KEY_CONTACTS, false, PEOPLE_TYPE_CONTACTS, CONVERSATION_SENDERS_IMPORTANT); - assertThat(endState[0]).isEqualTo(PEOPLE_TYPE_NONE); - assertThat(endState[1]).isEqualTo(CONVERSATION_SENDERS_UNSET); + // Shows a checked option for conversations=ANY which is normally unavailable. + assertThat(getVisibleOptions(mMessagesPrefCategory)).containsExactly(KEY_ANY, + KEY_STARRED, KEY_CONTACTS, KEY_ANY_CONVERSATIONS, KEY_IMPORTANT_CONVERSATIONS, + KEY_NONE); + assertThat(getCheckedOptions(mMessagesPrefCategory)).containsExactly(KEY_CONTACTS, + KEY_ANY_CONVERSATIONS); } @Test - public void testSettingsToSave_messages_noChange() { - int[] savedSettings; + public void updateState_msgContactsConvImportant() { + ZenMode zenMode = newModeWithPolicy(p -> + p.allowMessages(PEOPLE_TYPE_CONTACTS) + .allowConversations(CONVERSATION_SENDERS_IMPORTANT)); - savedSettings = mMessagesController.settingsToSaveOnClick( - KEY_NONE, true, PEOPLE_TYPE_NONE, CONVERSATION_SENDERS_NONE); - assertThat(savedSettings[0]).isEqualTo(STATE_UNSET); - assertThat(savedSettings[1]).isEqualTo(STATE_UNSET); + mMessagesController.displayPreference(mPreferenceScreen); + mMessagesController.updateZenMode(mMessagesPrefCategory, zenMode); - savedSettings = mMessagesController.settingsToSaveOnClick( - KEY_ANY, true, PEOPLE_TYPE_ANYONE, CONVERSATION_SENDERS_ANYONE); - assertThat(savedSettings[0]).isEqualTo(STATE_UNSET); - assertThat(savedSettings[1]).isEqualTo(STATE_UNSET); - - savedSettings = mMessagesController.settingsToSaveOnClick( - KEY_STARRED, true, PEOPLE_TYPE_STARRED, CONVERSATION_SENDERS_ANYONE); - assertThat(savedSettings[0]).isEqualTo(STATE_UNSET); - - savedSettings = mMessagesController.settingsToSaveOnClick( - KEY_CONTACTS, true, PEOPLE_TYPE_CONTACTS, CONVERSATION_SENDERS_ANYONE); - assertThat(savedSettings[0]).isEqualTo(STATE_UNSET); - - savedSettings = mMessagesController.settingsToSaveOnClick( - KEY_IMPORTANT, true, PEOPLE_TYPE_CONTACTS, CONVERSATION_SENDERS_IMPORTANT); - assertThat(savedSettings[1]).isEqualTo(STATE_UNSET); + // Contacts and important conversations. + assertThat(getVisibleOptions(mMessagesPrefCategory)).containsExactly( + KEY_ANY, KEY_STARRED, KEY_CONTACTS, KEY_IMPORTANT_CONVERSATIONS, KEY_NONE); + assertThat(getCheckedOptions(mMessagesPrefCategory)).containsExactly(KEY_CONTACTS, + KEY_IMPORTANT_CONVERSATIONS); } @Test - public void testSettingsToSave_calls_noChange() { - int[] savedSettings; + public void updateState_msgContactsConvNone() { + ZenMode zenMode = newModeWithPolicy(p -> + p.allowMessages(PEOPLE_TYPE_CONTACTS) + .allowConversations(CONVERSATION_SENDERS_NONE)); - savedSettings = mMessagesController.settingsToSaveOnClick( - KEY_NONE, true, PEOPLE_TYPE_NONE, CONVERSATION_SENDERS_NONE); - assertThat(savedSettings[0]).isEqualTo(STATE_UNSET); - assertThat(savedSettings[1]).isEqualTo(STATE_UNSET); + mMessagesController.displayPreference(mPreferenceScreen); + mMessagesController.updateZenMode(mMessagesPrefCategory, zenMode); - savedSettings = mMessagesController.settingsToSaveOnClick( - KEY_ANY, true, PEOPLE_TYPE_ANYONE, CONVERSATION_SENDERS_ANYONE); - assertThat(savedSettings[0]).isEqualTo(STATE_UNSET); - assertThat(savedSettings[1]).isEqualTo(STATE_UNSET); + // Just contacts (will include conversations with those contacts but not explicitly chosen). + assertThat(getVisibleOptions(mMessagesPrefCategory)).containsExactly( + KEY_ANY, KEY_STARRED, KEY_CONTACTS, KEY_IMPORTANT_CONVERSATIONS, KEY_NONE); + assertThat(getCheckedOptions(mMessagesPrefCategory)).containsExactly(KEY_CONTACTS); + } - savedSettings = mMessagesController.settingsToSaveOnClick( - KEY_STARRED, true, PEOPLE_TYPE_STARRED, CONVERSATION_SENDERS_ANYONE); - assertThat(savedSettings[0]).isEqualTo(STATE_UNSET); + @Test + public void updateState_msgStarredConvAny() { + ZenMode zenMode = newModeWithPolicy(p -> + p.allowMessages(PEOPLE_TYPE_STARRED) + .allowConversations(CONVERSATION_SENDERS_ANYONE)); - savedSettings = mMessagesController.settingsToSaveOnClick( - KEY_CONTACTS, true, PEOPLE_TYPE_CONTACTS, CONVERSATION_SENDERS_ANYONE); - assertThat(savedSettings[0]).isEqualTo(STATE_UNSET); + mMessagesController.displayPreference(mPreferenceScreen); + mMessagesController.updateZenMode(mMessagesPrefCategory, zenMode); + + // Shows a checked option for conversations=ANY which is normally unavailable. + assertThat(getVisibleOptions(mMessagesPrefCategory)).containsExactly(KEY_ANY, + KEY_STARRED, KEY_CONTACTS, KEY_ANY_CONVERSATIONS, KEY_IMPORTANT_CONVERSATIONS, + KEY_NONE); + assertThat(getCheckedOptions(mMessagesPrefCategory)).containsExactly(KEY_STARRED, + KEY_ANY_CONVERSATIONS); + } + + @Test + public void updateState_msgStarredConvImportant() { + ZenMode zenMode = newModeWithPolicy(p -> + p.allowMessages(PEOPLE_TYPE_STARRED) + .allowConversations(CONVERSATION_SENDERS_IMPORTANT)); + + mMessagesController.displayPreference(mPreferenceScreen); + mMessagesController.updateZenMode(mMessagesPrefCategory, zenMode); + + // Starred contacts and important conversations. + assertThat(getVisibleOptions(mMessagesPrefCategory)).containsExactly( + KEY_ANY, KEY_STARRED, KEY_CONTACTS, KEY_IMPORTANT_CONVERSATIONS, KEY_NONE); + assertThat(getCheckedOptions(mMessagesPrefCategory)).containsExactly(KEY_STARRED, + KEY_IMPORTANT_CONVERSATIONS); + } + + @Test + public void updateState_msgStarredConvNone() { + ZenMode zenMode = newModeWithPolicy(p -> + p.allowMessages(PEOPLE_TYPE_STARRED) + .allowConversations(CONVERSATION_SENDERS_NONE)); + + mMessagesController.displayPreference(mPreferenceScreen); + mMessagesController.updateZenMode(mMessagesPrefCategory, zenMode); + + // Just starred contacts (will include conversations with those contacts but not + // explicitly chosen). + assertThat(getVisibleOptions(mMessagesPrefCategory)).containsExactly( + KEY_ANY, KEY_STARRED, KEY_CONTACTS, KEY_IMPORTANT_CONVERSATIONS, KEY_NONE); + assertThat(getCheckedOptions(mMessagesPrefCategory)).containsExactly(KEY_STARRED); + } + + @Test + public void updateState_msgNoneConvAny() { + ZenMode zenMode = newModeWithPolicy(p -> + p.allowMessages(PEOPLE_TYPE_NONE) + .allowConversations(CONVERSATION_SENDERS_ANYONE)); + + mMessagesController.displayPreference(mPreferenceScreen); + mMessagesController.updateZenMode(mMessagesPrefCategory, zenMode); + + // Shows a checked option for conversations=ANY which is normally unavailable. + // Only option checked (messages=NONE is reserved for none at all). + assertThat(getVisibleOptions(mMessagesPrefCategory)).containsExactly(KEY_ANY, + KEY_STARRED, KEY_CONTACTS, KEY_ANY_CONVERSATIONS, KEY_IMPORTANT_CONVERSATIONS, + KEY_NONE); + assertThat(getCheckedOptions(mMessagesPrefCategory)).containsExactly( + KEY_ANY_CONVERSATIONS); + } + + @Test + public void updateState_msgNoneConvImportant() { + ZenMode zenMode = newModeWithPolicy(p -> + p.allowMessages(PEOPLE_TYPE_NONE) + .allowConversations(CONVERSATION_SENDERS_IMPORTANT)); + + mMessagesController.displayPreference(mPreferenceScreen); + mMessagesController.updateZenMode(mMessagesPrefCategory, zenMode); + + // Only important conversations (messages=NONE is reserved for none at all). + assertThat(getVisibleOptions(mMessagesPrefCategory)).containsExactly( + KEY_ANY, KEY_STARRED, KEY_CONTACTS, KEY_IMPORTANT_CONVERSATIONS, KEY_NONE); + assertThat(getCheckedOptions(mMessagesPrefCategory)).containsExactly( + KEY_IMPORTANT_CONVERSATIONS); + } + + @Test + public void updateState_msgNoneConvNone() { + ZenMode zenMode = newModeWithPolicy(p -> + p.allowMessages(PEOPLE_TYPE_NONE) + .allowConversations(CONVERSATION_SENDERS_NONE)); + + mMessagesController.displayPreference(mPreferenceScreen); + mMessagesController.updateZenMode(mMessagesPrefCategory, zenMode); + + // Just starred contacts (will include conversations with those contacts but not + // explicitly chosen). + assertThat(getVisibleOptions(mMessagesPrefCategory)).containsExactly( + KEY_ANY, KEY_STARRED, KEY_CONTACTS, KEY_IMPORTANT_CONVERSATIONS, KEY_NONE); + assertThat(getCheckedOptions(mMessagesPrefCategory)).containsExactly(KEY_NONE); + } + + // -------------------------------------------------------------------------- + // Message checkbox tests, starting with Msg=Any, Conv=Any + + @Test + public void checkContacts_fromMsgAnyConvAny_toMsgContactsConvNone() { + checkSomeContacts_fromMsgAnyConvAny_toMsgSomeContactsConvNone(KEY_CONTACTS, + PEOPLE_TYPE_CONTACTS); + } + + @Test + public void checkStarred_fromMsgAnyConvAny_toMsgStarredConvNone() { + checkSomeContacts_fromMsgAnyConvAny_toMsgSomeContactsConvNone(KEY_STARRED, + PEOPLE_TYPE_STARRED); + } + + private void checkSomeContacts_fromMsgAnyConvAny_toMsgSomeContactsConvNone( + String contactsOptionKey, @PeopleType int toMessageSenders) { + setUpMessagesController(p -> + p.allowMessages(PEOPLE_TYPE_ANYONE) + .allowConversations(CONVERSATION_SENDERS_ANYONE)); + + // Choosing CONTACTS/STARRED will also internally switch conversations to NONE (which is + // fine because the user didn't see the old conv=Any, just messages=Anyone). + setMessagesOptionChecked(contactsOptionKey, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(toMessageSenders); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_NONE); + } + + @Test + public void checkImportantConv_fromMsgAnyConvAny_toMsgNoneConvImportant() { + setUpMessagesController(p -> + p.allowMessages(PEOPLE_TYPE_ANYONE) + .allowConversations(CONVERSATION_SENDERS_ANYONE)); + + setMessagesOptionChecked(KEY_IMPORTANT_CONVERSATIONS, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(PEOPLE_TYPE_NONE); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_IMPORTANT); + } + + @Test + public void checkAnyConv_fromMsgAnyConvAny_toMsgNoneConvAny() { + setUpMessagesController(p -> + p.allowMessages(PEOPLE_TYPE_ANYONE) + .allowConversations(CONVERSATION_SENDERS_ANYONE)); + + // Normally this option won't be visible, but it could be if the page was launched with + // conv=Any previously. + setMessagesOptionChecked(KEY_ANY_CONVERSATIONS, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(PEOPLE_TYPE_NONE); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_ANYONE); + } + + @Test + public void uncheckAnyone_fromMsgAnyConvAny_toMsgNoneConvNone() { + uncheckAnyone_fromState_toMsgNoneConvNone(PEOPLE_TYPE_ANYONE, + CONVERSATION_SENDERS_ANYONE); + } + + @Test + public void checkNone_fromMsgAnyConvAny_toMsgNoneConvNone() { + checkNone_fromState_toMsgNoneConvNone(PEOPLE_TYPE_ANYONE, CONVERSATION_SENDERS_ANYONE); + } + + // -------------------------------------------------------------------------- + // Message checkbox tests, starting with Msg=Any, Conv=Important + + @Test + public void checkContacts_fromMsgAnyConvImportant_toMsgContactsConvNone() { + checkSomeContacts_fromMsgAnyConvImportant_toMsgSomeContactsConvNone(KEY_CONTACTS, + PEOPLE_TYPE_CONTACTS); + } + + @Test + public void checkStarred_fromMsgAnyConvImportant_toMsgStarredConvNone() { + checkSomeContacts_fromMsgAnyConvImportant_toMsgSomeContactsConvNone(KEY_STARRED, + PEOPLE_TYPE_STARRED); + } + + private void checkSomeContacts_fromMsgAnyConvImportant_toMsgSomeContactsConvNone( + String contactsOptionKey, @PeopleType int toMessageSenders) { + setUpMessagesController(p -> + p.allowMessages(PEOPLE_TYPE_ANYONE) + .allowConversations(CONVERSATION_SENDERS_IMPORTANT)); + + // Choosing CONTACTS/STARRED will also internally switch conversations to NONE (which is + // fine because the user didn't see the old setting, just messages=Anyone). + setMessagesOptionChecked(contactsOptionKey, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(toMessageSenders); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_NONE); + } + + @Test + public void checkImportantConv_fromMsgAnyConvImportant_toMsgNoneConvImportant() { + setUpMessagesController(p -> + p.allowMessages(PEOPLE_TYPE_ANYONE) + .allowConversations(CONVERSATION_SENDERS_IMPORTANT)); + + // Although conv=IMPORTANT previously, we show it as Anyone, so selecting important + // conversations should switch to important conversations only. + setMessagesOptionChecked(KEY_IMPORTANT_CONVERSATIONS, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(PEOPLE_TYPE_NONE); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_IMPORTANT); + } + + @Test + public void checkAnyConv_fromMsgAnyConvImportant_toMsgNoneConvAny() { + setUpMessagesController(p -> + p.allowMessages(PEOPLE_TYPE_ANYONE) + .allowConversations(CONVERSATION_SENDERS_ANYONE)); + + // Normally this option won't be visible, but it could be if the page was launched with + // conv=Any previously. + setMessagesOptionChecked(KEY_ANY_CONVERSATIONS, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(PEOPLE_TYPE_NONE); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_ANYONE); + } + + @Test + public void uncheckAnyone_fromMsgAnyConvImportant_toMsgNoneConvNone() { + uncheckAnyone_fromState_toMsgNoneConvNone(PEOPLE_TYPE_ANYONE, + CONVERSATION_SENDERS_IMPORTANT); + } + + @Test + public void checkNone_fromMsgAnyConvImportant_toMsgNoneConvNone() { + checkNone_fromState_toMsgNoneConvNone(PEOPLE_TYPE_ANYONE, + CONVERSATION_SENDERS_IMPORTANT); + } + + // -------------------------------------------------------------------------- + // Message checkbox tests, starting with Msg=Any, Conv=None + + @Test + public void checkContacts_fromMsgAnyConvNone_toMsgContactsConvNone() { + checkSomeContacts_fromMsgAnyConvNone_toMsgSomeContactsConvNone(KEY_CONTACTS, + PEOPLE_TYPE_CONTACTS); + } + + @Test + public void checkStarred_fromMsgAnyConvNone_toMsgStarredConvNone() { + checkSomeContacts_fromMsgAnyConvNone_toMsgSomeContactsConvNone(KEY_STARRED, + PEOPLE_TYPE_STARRED); + } + + private void checkSomeContacts_fromMsgAnyConvNone_toMsgSomeContactsConvNone( + String contactsOptionKey, @PeopleType int toMessageSenders) { + setUpMessagesController(p -> + p.allowMessages(PEOPLE_TYPE_ANYONE) + .allowConversations(CONVERSATION_SENDERS_NONE)); + + // Choosing CONTACTS/STARRED will also internally switch conversations to NONE (which is + // fine because the user didn't see the old setting, just messages=Anyone). + setMessagesOptionChecked(contactsOptionKey, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(toMessageSenders); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_NONE); + } + + @Test + public void checkImportantConv_fromMsgAnyConvNone_toMsgNoneConvImportant() { + setUpMessagesController(p -> + p.allowMessages(PEOPLE_TYPE_ANYONE) + .allowConversations(CONVERSATION_SENDERS_NONE)); + + setMessagesOptionChecked(KEY_IMPORTANT_CONVERSATIONS, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(PEOPLE_TYPE_NONE); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_IMPORTANT); + } + + @Test + public void checkAnyConv_fromMsgAnyConvNone_toMsgNoneConvAny() { + setUpMessagesController(p -> + p.allowMessages(PEOPLE_TYPE_ANYONE) + .allowConversations(CONVERSATION_SENDERS_NONE)); + + // Normally this option won't be visible, but it could be if the page was launched with + // conv=Any previously. + setMessagesOptionChecked(KEY_ANY_CONVERSATIONS, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(PEOPLE_TYPE_NONE); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_ANYONE); + } + + @Test + public void uncheckAnyone_fromMsgAnyConvNone_toMsgNoneConvNone() { + uncheckAnyone_fromState_toMsgNoneConvNone(PEOPLE_TYPE_ANYONE, + CONVERSATION_SENDERS_NONE); + } + + @Test + public void checkNone_fromMsgAnyConvNone_toMsgNoneConvNone() { + checkNone_fromState_toMsgNoneConvNone(PEOPLE_TYPE_ANYONE, + CONVERSATION_SENDERS_NONE); + } + + // -------------------------------------------------------------------------- + // Message checkbox tests, starting with Msg=Contacts OR Starred, Conv=Any + + @Test + public void switchContacts_fromMsgStarredConvAny_toMsgContactsConvAny() { + switchContacts_fromMsgSomeContactsConvAny_toMsgOtherContactsConvAny(PEOPLE_TYPE_STARRED, + KEY_CONTACTS, PEOPLE_TYPE_CONTACTS); + } + + @Test + public void switchContacts_fromMsgContactsConvAny_toMsgStarredConvAny() { + switchContacts_fromMsgSomeContactsConvAny_toMsgOtherContactsConvAny(PEOPLE_TYPE_CONTACTS, + KEY_STARRED, PEOPLE_TYPE_STARRED); + } + + private void switchContacts_fromMsgSomeContactsConvAny_toMsgOtherContactsConvAny( + @PeopleType int fromMessageSenders, String checkingContactsOptionKey, + @PeopleType int toMessageSenders) { + setUpMessagesController(p -> + p.allowMessages(fromMessageSenders) + .allowConversations(CONVERSATION_SENDERS_ANYONE)); + + // Switching CONTACTS/STARRED or vice-versa will leave conversations untouched. + setMessagesOptionChecked(checkingContactsOptionKey, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(toMessageSenders); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_ANYONE); + } + + @Test + public void uncheckStarred_fromMsgStarredConvAny_toMsgNoneConvAny() { + uncheckSomeContacts_fromMsgSomeContactsConvAny_toMsgNoneConvAny(PEOPLE_TYPE_STARRED, + KEY_STARRED); + } + + @Test + public void uncheckContacts_fromMsgContactsConvAny_toMsgNoneConvAny() { + uncheckSomeContacts_fromMsgSomeContactsConvAny_toMsgNoneConvAny( + PEOPLE_TYPE_CONTACTS, KEY_CONTACTS); + } + + private void uncheckSomeContacts_fromMsgSomeContactsConvAny_toMsgNoneConvAny( + @PeopleType int fromMessageSenders, String checkingContactsOptionKey) { + setUpMessagesController(p -> + p.allowMessages(fromMessageSenders) + .allowConversations(CONVERSATION_SENDERS_ANYONE)); + + // Unchecking CONTACTS or STARRED will leave conversations untouched. + setMessagesOptionChecked(checkingContactsOptionKey, false); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(PEOPLE_TYPE_NONE); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_ANYONE); + } + + @Test + public void checkImportantConv_fromMsgStarredConvAny_toMsgStarredConvImportant() { + checkImportantConv_fromMsgSomeContactsConvAny_toMsgSomeContactsConvImportant( + PEOPLE_TYPE_STARRED); + } + + @Test + public void checkImportantConv_fromMsgContactsConvAny_toMsgContactsConvImportant() { + checkImportantConv_fromMsgSomeContactsConvAny_toMsgSomeContactsConvImportant( + PEOPLE_TYPE_CONTACTS); + } + + private void checkImportantConv_fromMsgSomeContactsConvAny_toMsgSomeContactsConvImportant( + @PeopleType int fromMessageSenders) { + setUpMessagesController(p -> + p.allowMessages(fromMessageSenders) + .allowConversations(CONVERSATION_SENDERS_ANYONE)); + + // Choosing important conversations leaves contacts untouched. + setMessagesOptionChecked(KEY_IMPORTANT_CONVERSATIONS, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(fromMessageSenders); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_IMPORTANT); + } + + @Test + public void uncheckAnyConv_fromMsgStarredConvAny_toMsgStarredConvNone() { + uncheckAnyConv_fromMsgSomeContactsConvAny_toMsgSomeContactsConvNone( + PEOPLE_TYPE_STARRED); + } + + @Test + public void uncheckAnyConv_fromMsgContactsConvAny_toMsgContactsConvNone() { + uncheckAnyConv_fromMsgSomeContactsConvAny_toMsgSomeContactsConvNone( + PEOPLE_TYPE_CONTACTS); + } + + private void uncheckAnyConv_fromMsgSomeContactsConvAny_toMsgSomeContactsConvNone( + @PeopleType int fromMessageSenders) { + setUpMessagesController(p -> + p.allowMessages(fromMessageSenders) + .allowConversations(CONVERSATION_SENDERS_ANYONE)); + + // Unmarking any conversation leaves contacts untouched. + setMessagesOptionChecked(KEY_ANY_CONVERSATIONS, false); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(fromMessageSenders); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_NONE); + } + + @Test + public void checkAnyone_fromMsgStarredConvAny_toMsgAnyConvNone() { + checkAnyone_fromState_toMsgAnyConvAny(PEOPLE_TYPE_STARRED, + CONVERSATION_SENDERS_ANYONE); + } + + @Test + public void checkAnyone_fromMsgContactsConvAny_toMsgAnyConvNone() { + checkAnyone_fromState_toMsgAnyConvAny(PEOPLE_TYPE_CONTACTS, + CONVERSATION_SENDERS_ANYONE); + } + + @Test + public void checkNone_fromMsgStarredConvAny_toMsgNoneConvNone() { + checkNone_fromState_toMsgNoneConvNone(PEOPLE_TYPE_STARRED, CONVERSATION_SENDERS_ANYONE); + } + + @Test + public void checkNone_fromMsgContactsConvAny_toMsgNoneConvNone() { + checkNone_fromState_toMsgNoneConvNone(PEOPLE_TYPE_CONTACTS, CONVERSATION_SENDERS_ANYONE); + } + + // -------------------------------------------------------------------------- + // Message checkbox tests, starting with Msg=Contacts OR Starred, Conv=Important + + @Test + public void switchContacts_fromMsgStarredConvImportant_toMsgContactsConvImportant() { + switchContacts_fromMsgSomeContactsConvImportant_toMsgOtherContactsConvImportant( + PEOPLE_TYPE_CONTACTS, KEY_STARRED, PEOPLE_TYPE_STARRED); + } + + @Test + public void switchContacts_fromMsgContactsConvImportant_toMsgStarredConvImportant() { + switchContacts_fromMsgSomeContactsConvImportant_toMsgOtherContactsConvImportant( + PEOPLE_TYPE_STARRED, KEY_CONTACTS, PEOPLE_TYPE_CONTACTS); + } + + private void switchContacts_fromMsgSomeContactsConvImportant_toMsgOtherContactsConvImportant( + @PeopleType int fromMessageSenders, String checkingContactsOptionKey, + @PeopleType int toMessageSenders) { + setUpMessagesController(p -> + p.allowMessages(fromMessageSenders) + .allowConversations(CONVERSATION_SENDERS_IMPORTANT)); + + // Switching CONTACTS/STARRED or vice-versa will leave conversations untouched. + setMessagesOptionChecked(checkingContactsOptionKey, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(toMessageSenders); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_IMPORTANT); + } + + @Test + public void uncheckStarred_fromMsgStarredConvImportant_toMsgNoneConvImportant() { + uncheckSomeContacts_fromMsgSomeContactsConvImportant_toMsgNoneConvImportant( + PEOPLE_TYPE_STARRED, KEY_STARRED); + } + + @Test + public void uncheckContacts_fromMsgContactsConvImportant_toMsgNoneConvImportant() { + uncheckSomeContacts_fromMsgSomeContactsConvImportant_toMsgNoneConvImportant( + PEOPLE_TYPE_CONTACTS, KEY_CONTACTS); + } + + private void uncheckSomeContacts_fromMsgSomeContactsConvImportant_toMsgNoneConvImportant( + @PeopleType int fromMessageSenders, String checkingContactsOptionKey) { + setUpMessagesController(p -> + p.allowMessages(fromMessageSenders) + .allowConversations(CONVERSATION_SENDERS_IMPORTANT)); + + // Unchecking CONTACTS or STARRED will leave conversations untouched. + setMessagesOptionChecked(checkingContactsOptionKey, false); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(PEOPLE_TYPE_NONE); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_IMPORTANT); + } + + @Test + public void uncheckImportantConv_fromMsgStarredConvImportant_toMsgStarredConvNone() { + uncheckImportantConv_fromMsgSomeContactsConvImportant_toMsgSomeContactsConvNone( + PEOPLE_TYPE_STARRED); + } + + @Test + public void uncheckImportantConv_fromMsgContactsConvImportant_toMsgContactsConvNone() { + uncheckImportantConv_fromMsgSomeContactsConvImportant_toMsgSomeContactsConvNone( + PEOPLE_TYPE_CONTACTS); + } + + private void uncheckImportantConv_fromMsgSomeContactsConvImportant_toMsgSomeContactsConvNone( + @PeopleType int fromMessageSenders) { + setUpMessagesController(p -> + p.allowMessages(fromMessageSenders) + .allowConversations(CONVERSATION_SENDERS_IMPORTANT)); + + // Deselecting important conversations leaves contacts untouched. + setMessagesOptionChecked(KEY_IMPORTANT_CONVERSATIONS, false); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(fromMessageSenders); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_NONE); + } + + @Test + public void checkAnyConv_fromMsgStarredConvImportant_toMsgStarredConvAny() { + checkAnyConv_fromMsgSomeContactsConvImportant_toMsgSomeContactsConvAny( + PEOPLE_TYPE_STARRED); + } + + @Test + public void checkAnyConv_fromMsgContactsConvImportant_toMsgContactsConvAny() { + checkAnyConv_fromMsgSomeContactsConvImportant_toMsgSomeContactsConvAny( + PEOPLE_TYPE_CONTACTS); + } + + private void checkAnyConv_fromMsgSomeContactsConvImportant_toMsgSomeContactsConvAny( + @PeopleType int fromMessageSenders) { + setUpMessagesController(p -> + p.allowMessages(fromMessageSenders) + .allowConversations(CONVERSATION_SENDERS_IMPORTANT)); + + // Selecting any conversations leaves contacts untouched. + setMessagesOptionChecked(KEY_ANY_CONVERSATIONS, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(fromMessageSenders); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_ANYONE); + } + + @Test + public void checkAnyone_fromMsgStarredConvImportant_toMsgAnyConvNone() { + checkAnyone_fromState_toMsgAnyConvAny(PEOPLE_TYPE_STARRED, + CONVERSATION_SENDERS_IMPORTANT); + } + + @Test + public void checkAnyone_fromMsgContactsConvImportant_toMsgAnyConvNone() { + checkAnyone_fromState_toMsgAnyConvAny(PEOPLE_TYPE_CONTACTS, + CONVERSATION_SENDERS_IMPORTANT); + } + + @Test + public void checkNone_fromMsgStarredConvImportant_toMsgNoneConvNone() { + checkNone_fromState_toMsgNoneConvNone(PEOPLE_TYPE_STARRED, + CONVERSATION_SENDERS_IMPORTANT); + } + + @Test + public void checkNone_fromMsgContactsConvImportant_toMsgNoneConvNone() { + checkNone_fromState_toMsgNoneConvNone(PEOPLE_TYPE_CONTACTS, + CONVERSATION_SENDERS_IMPORTANT); + } + + // -------------------------------------------------------------------------- + // Message checkbox tests, starting with Msg=Contacts OR Starred, Conv=None + + @Test + public void switchContacts_fromMsgStarredConvNone_toMsgContactsConvNone() { + switchContacts_fromMsgSomeContactsConvNone_toMsgSomeContactsConvNone(PEOPLE_TYPE_CONTACTS, + KEY_STARRED, PEOPLE_TYPE_STARRED); + } + + @Test + public void switchContacts_fromMsgContactsConvNone_toMsgStarredConvNone() { + switchContacts_fromMsgSomeContactsConvNone_toMsgSomeContactsConvNone(PEOPLE_TYPE_STARRED, + KEY_CONTACTS, PEOPLE_TYPE_CONTACTS); + } + + private void switchContacts_fromMsgSomeContactsConvNone_toMsgSomeContactsConvNone( + @PeopleType int fromMessageSenders, String checkingContactsOptionKey, + @PeopleType int toMessageSenders) { + setUpMessagesController(p -> + p.allowMessages(fromMessageSenders) + .allowConversations(CONVERSATION_SENDERS_NONE)); + + // Switching CONTACTS/STARRED or vice-versa will leave conversations untouched. + setMessagesOptionChecked(checkingContactsOptionKey, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(toMessageSenders); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_NONE); + } + + @Test + public void uncheckStarred_fromMsgStarredConvNone_toMsgNoneConvNone() { + uncheckSomeContacts_fromMsgSomeContactsConvNone_toMsgNoneConvNone( + PEOPLE_TYPE_STARRED, KEY_STARRED); + } + + @Test + public void uncheckContacts_fromMsgContactsConvNone_toMsgNoneConvNone() { + uncheckSomeContacts_fromMsgSomeContactsConvNone_toMsgNoneConvNone( + PEOPLE_TYPE_CONTACTS, KEY_CONTACTS); + } + + private void uncheckSomeContacts_fromMsgSomeContactsConvNone_toMsgNoneConvNone( + @PeopleType int fromMessageSenders, String checkingContactsOptionKey) { + setUpMessagesController(p -> + p.allowMessages(fromMessageSenders) + .allowConversations(CONVERSATION_SENDERS_NONE)); + + // Unchecking CONTACTS or STARRED will leave conversations untouched. + setMessagesOptionChecked(checkingContactsOptionKey, false); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(PEOPLE_TYPE_NONE); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_NONE); + } + + @Test + public void checkImportantConv_fromMsgStarredConvNone_toMsgSomeContactsConvImportant() { + checkImportantConv_fromMsgSomeContactsConvNone_toMsgSomeContactsConvImportant( + PEOPLE_TYPE_STARRED); + } + + @Test + public void checkImportantConv_fromMsgContactsConvNone_toMsgSomeContactsConvImportant() { + checkImportantConv_fromMsgSomeContactsConvNone_toMsgSomeContactsConvImportant( + PEOPLE_TYPE_CONTACTS); + } + + private void checkImportantConv_fromMsgSomeContactsConvNone_toMsgSomeContactsConvImportant( + @PeopleType int fromMessageSenders) { + setUpMessagesController(p -> + p.allowMessages(fromMessageSenders) + .allowConversations(CONVERSATION_SENDERS_NONE)); + + // Deselecting important conversations leaves contacts untouched. + setMessagesOptionChecked(KEY_IMPORTANT_CONVERSATIONS, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(fromMessageSenders); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_IMPORTANT); + } + + @Test + public void checkAnyConv_fromMsgStarredConvNone_toMsgStarredConvAny() { + checkAnyConv_fromMsgSomeContactsConvNone_toMsgSomeContactsConvAny(PEOPLE_TYPE_STARRED); + } + + @Test + public void checkAnyConv_fromMsgContactsConvNone_toMsgContactsConvAny() { + checkAnyConv_fromMsgSomeContactsConvNone_toMsgSomeContactsConvAny(PEOPLE_TYPE_CONTACTS); + } + + private void checkAnyConv_fromMsgSomeContactsConvNone_toMsgSomeContactsConvAny( + @PeopleType int fromMessageSenders) { + setUpMessagesController(p -> + p.allowMessages(fromMessageSenders) + .allowConversations(CONVERSATION_SENDERS_IMPORTANT)); + + // Selecting any conversations leaves contacts untouched. + setMessagesOptionChecked(KEY_ANY_CONVERSATIONS, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(fromMessageSenders); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_ANYONE); + } + + @Test + public void checkAnyone_fromMsgStarredConvNone_toMsgAnyConvNone() { + checkAnyone_fromState_toMsgAnyConvAny(PEOPLE_TYPE_STARRED, + CONVERSATION_SENDERS_IMPORTANT); + } + + @Test + public void checkAnyone_fromMsgContactsConvNone_toMsgAnyConvNone() { + checkAnyone_fromState_toMsgAnyConvAny(PEOPLE_TYPE_CONTACTS, + CONVERSATION_SENDERS_IMPORTANT); + } + + @Test + public void checkNone_fromMsgStarredConvNone_toMsgNoneConvNone() { + checkNone_fromState_toMsgNoneConvNone(PEOPLE_TYPE_STARRED, + CONVERSATION_SENDERS_NONE); + } + + @Test + public void checkNone_fromMsgContactsConvNone_toMsgNoneConvNone() { + checkNone_fromState_toMsgNoneConvNone(PEOPLE_TYPE_CONTACTS, + CONVERSATION_SENDERS_NONE); + } + + // -------------------------------------------------------------------------- + // Message checkbox tests, starting with Msg=None, Conv=Any + + @Test + public void checkContacts_fromMsgNoneConvAny_toMsgContactsConvAny() { + checkSomeContacts_fromMsgNoneConvAny_toMsgSomeContactsConvAny(KEY_CONTACTS, + PEOPLE_TYPE_CONTACTS); + } + + @Test + public void checkStarred_fromMsgNoneConvAny_toMsgStarredConvAny() { + checkSomeContacts_fromMsgNoneConvAny_toMsgSomeContactsConvAny(KEY_STARRED, + PEOPLE_TYPE_STARRED); + } + + private void checkSomeContacts_fromMsgNoneConvAny_toMsgSomeContactsConvAny( + String contactsOptionKey, @PeopleType int toMessageSenders) { + setUpMessagesController(p -> + p.allowMessages(PEOPLE_TYPE_NONE) + .allowConversations(CONVERSATION_SENDERS_ANYONE)); + + // Adding CONTACTS/STARRED will leave conversations untouched. + setMessagesOptionChecked(contactsOptionKey, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(toMessageSenders); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_ANYONE); + } + + @Test + public void checkImportantConv_fromMsgNoneConvAny_toMsgNoneConvImportant() { + setUpMessagesController(p -> + p.allowMessages(PEOPLE_TYPE_NONE) + .allowConversations(CONVERSATION_SENDERS_ANYONE)); + + setMessagesOptionChecked(KEY_IMPORTANT_CONVERSATIONS, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(PEOPLE_TYPE_NONE); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_IMPORTANT); + } + + @Test + public void uncheckAnyConv_fromMsgNoneConvAny_toMsgNoneConvNone() { + setUpMessagesController(p -> + p.allowMessages(PEOPLE_TYPE_NONE) + .allowConversations(CONVERSATION_SENDERS_ANYONE)); + + setMessagesOptionChecked(KEY_ANY_CONVERSATIONS, false); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(PEOPLE_TYPE_NONE); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_NONE); + } + + @Test + public void checkAnyone_fromMsgNoneConvAny_toMsgAnyConvNone() { + checkAnyone_fromState_toMsgAnyConvAny(PEOPLE_TYPE_NONE, + CONVERSATION_SENDERS_ANYONE); + } + + @Test + public void checkNone_fromMsgNoneConvAny_toMsgNoneConvNone() { + checkNone_fromState_toMsgNoneConvNone(PEOPLE_TYPE_NONE, + CONVERSATION_SENDERS_ANYONE); + } + + // -------------------------------------------------------------------------- + // Message checkbox tests, starting with Msg=None, Conv=Important + + @Test + public void checkContacts_fromMsgNoneConvImportant_toMsgContactsConvImportant() { + checkSomeContacts_fromMsgNoneConvImportant_toMsgSomeContactsConvImportant(KEY_CONTACTS, + PEOPLE_TYPE_CONTACTS); + } + + @Test + public void checkStarred_fromMsgNoneConvImportant_toMsgStarredConvImportant() { + checkSomeContacts_fromMsgNoneConvImportant_toMsgSomeContactsConvImportant(KEY_STARRED, + PEOPLE_TYPE_STARRED); + } + + private void checkSomeContacts_fromMsgNoneConvImportant_toMsgSomeContactsConvImportant( + String contactsOptionKey, @PeopleType int toMessageSenders) { + setUpMessagesController(p -> + p.allowMessages(PEOPLE_TYPE_NONE) + .allowConversations(CONVERSATION_SENDERS_IMPORTANT)); + + // Adding CONTACTS/STARRED will leave conversations untouched. + setMessagesOptionChecked(contactsOptionKey, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(toMessageSenders); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_IMPORTANT); + } + + @Test + public void uncheckImportantConv_fromMsgNoneConvImportant_toMsgNoneConvNone() { + setUpMessagesController(p -> + p.allowMessages(PEOPLE_TYPE_NONE) + .allowConversations(CONVERSATION_SENDERS_IMPORTANT)); + + setMessagesOptionChecked(KEY_IMPORTANT_CONVERSATIONS, false); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(PEOPLE_TYPE_NONE); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_NONE); + } + + @Test + public void checkAnyConv_fromMsgNoneConvImportant_toMsgNoneConvAny() { + setUpMessagesController(p -> + p.allowMessages(PEOPLE_TYPE_NONE) + .allowConversations(CONVERSATION_SENDERS_IMPORTANT)); + + // Normally this option won't be visible, but it could be if the page was launched with + // conv=Any previously. + setMessagesOptionChecked(KEY_ANY_CONVERSATIONS, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(PEOPLE_TYPE_NONE); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_ANYONE); + } + + @Test + public void checkAnyone_fromMsgNoneConvImportant_toMsgAnyConvNone() { + checkAnyone_fromState_toMsgAnyConvAny(PEOPLE_TYPE_NONE, + CONVERSATION_SENDERS_IMPORTANT); + } + + @Test + public void checkNone_fromMsgNoneConvImportant_toMsgNoneConvNone() { + checkNone_fromState_toMsgNoneConvNone(PEOPLE_TYPE_NONE, + CONVERSATION_SENDERS_IMPORTANT); + } + + // -------------------------------------------------------------------------- + // Message checkbox tests, starting with Msg=None, Conv=None + + @Test + public void checkContacts_fromMsgNoneConvNone_toMsgContactsConvNone() { + checkSomeContacts_fromMsgNoneConvNone_toMsgSomeContactsConvNone(KEY_CONTACTS, + PEOPLE_TYPE_CONTACTS); + } + + @Test + public void checkStarred_fromMsgNoneConvNone_toMsgStarredConvNone() { + checkSomeContacts_fromMsgNoneConvNone_toMsgSomeContactsConvNone(KEY_STARRED, + PEOPLE_TYPE_STARRED); + } + + private void checkSomeContacts_fromMsgNoneConvNone_toMsgSomeContactsConvNone( + String contactsOptionKey, @PeopleType int toMessageSenders) { + setUpMessagesController(p -> + p.allowMessages(PEOPLE_TYPE_NONE) + .allowConversations(CONVERSATION_SENDERS_NONE)); + + // Choosing CONTACTS/STARRED will leave conversations untouched. + setMessagesOptionChecked(contactsOptionKey, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(toMessageSenders); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_NONE); + } + + @Test + public void checkImportantConv_fromMsgNoneConvNone_toMsgNoneConvImportant() { + setUpMessagesController(p -> + p.allowMessages(PEOPLE_TYPE_NONE) + .allowConversations(CONVERSATION_SENDERS_NONE)); + + setMessagesOptionChecked(KEY_IMPORTANT_CONVERSATIONS, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(PEOPLE_TYPE_NONE); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_IMPORTANT); + } + + @Test + public void checkAnyConv_fromMsgNoneConvNone_toMsgNoneConvAny() { + setUpMessagesController(p -> + p.allowMessages(PEOPLE_TYPE_NONE) + .allowConversations(CONVERSATION_SENDERS_NONE)); + + // Normally this option won't be visible, but it could be if the page was launched with + // conv=Any previously. + setMessagesOptionChecked(KEY_ANY_CONVERSATIONS, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(PEOPLE_TYPE_NONE); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_ANYONE); + } + + @Test + public void checkAnyone_fromMsgNoneConvNone_toMsgAnyConvNone() { + checkAnyone_fromState_toMsgAnyConvAny(PEOPLE_TYPE_NONE, + CONVERSATION_SENDERS_NONE); + } + + @Test + public void uncheckNone_fromMsgNoneConvNone_noChanges() { + setUpMessagesController(p -> + p.allowMessages(PEOPLE_TYPE_NONE) + .allowConversations(CONVERSATION_SENDERS_NONE)); + + setMessagesOptionChecked(KEY_NONE, false); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertThat(savedPolicy.getPriorityMessageSenders()).isEqualTo(PEOPLE_TYPE_NONE); + assertThat(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_NONE); + } + + // -------------------------------------------------------------------------- + // Message checkbox tests, common cases. + + private void checkAnyone_fromState_toMsgAnyConvAny(@PeopleType int fromMsg, + @ConversationSenders int fromConv) { + setUpMessagesController(p -> + p.allowMessages(fromMsg).allowConversations(fromConv)); + String context = "Trying to check Anyone; starting with Msg=" + peopleTypeToString(fromMsg) + + ", Conv=" + conversationTypeToString(fromConv); + + // Checking ANY will always unselect everything else in the UI, no matter the initial state, + // but will save PEOPLE_ANY and CONVERSATIONS_ANY (which is redundant but equivalent). + setMessagesOptionChecked(KEY_ANY, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertWithMessage(context).that(savedPolicy.getPriorityMessageSenders()).isEqualTo( + PEOPLE_TYPE_ANYONE); + assertWithMessage(context).that(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_ANYONE); + } + + private void uncheckAnyone_fromState_toMsgNoneConvNone(@PeopleType int fromMsg, + @ConversationSenders int fromConv) { + setUpMessagesController(p -> + p.allowMessages(fromMsg).allowConversations(fromConv)); + String context = "Trying to uncheck Anyone; starting with Msg=" + peopleTypeToString( + fromMsg) + ", Conv=" + conversationTypeToString(fromConv); + + // Unchecking ANYONE means NONE to both, even if Anyone was previously Msg=Any&Conv=Any or + // Msg=Any&Conv=Important. + setMessagesOptionChecked(KEY_ANY, false); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertWithMessage(context).that(savedPolicy.getPriorityMessageSenders()).isEqualTo( + PEOPLE_TYPE_NONE); + assertWithMessage(context).that(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_NONE); + } + + private void checkNone_fromState_toMsgNoneConvNone(@PeopleType int fromMsg, + @ConversationSenders int fromConv) { + setUpMessagesController(p -> + p.allowMessages(fromMsg).allowConversations(fromConv)); + String context = "Trying to check None; starting with Msg=" + peopleTypeToString(fromMsg) + + ", Conv=" + conversationTypeToString(fromConv); + + // Checking NONE will always unselect everything else, no matter the initial state. + setMessagesOptionChecked(KEY_NONE, true); + ZenPolicy savedPolicy = getSavedPolicy(); + + assertWithMessage(context).that(savedPolicy.getPriorityMessageSenders()).isEqualTo( + PEOPLE_TYPE_NONE); + assertWithMessage(context).that(savedPolicy.getPriorityConversationSenders()).isEqualTo( + CONVERSATION_SENDERS_NONE); + } + + private void setUpMessagesController(Consumer policyMaker) { + ZenMode zenMode = newModeWithPolicy(policyMaker); + mMessagesController.displayPreference(mPreferenceScreen); + mMessagesController.updateZenMode(mMessagesPrefCategory, zenMode); + } + + private static ZenMode newModeWithPolicy(Consumer policyMaker) { + ZenPolicy.Builder policyBuilder = new ZenPolicy.Builder(); + policyMaker.accept(policyBuilder); + return new TestModeBuilder().setZenPolicy(policyBuilder.build()).build(); + } + + private static ImmutableList getAllOptions(PreferenceCategory category) { + return getOptions(category, o -> true); + } + + private static ImmutableList getVisibleOptions(PreferenceCategory category) { + return getOptions(category, Preference::isVisible); + } + + private static ImmutableList getCheckedOptions(PreferenceCategory category) { + return getOptions(category, TwoStatePreference::isChecked); + } + + private static ImmutableList getOptions(PreferenceCategory category, + Predicate filter) { + ImmutableList.Builder keys = new ImmutableList.Builder<>(); + for (int i = 0; i < category.getPreferenceCount(); i++) { + SelectorWithWidgetPreference option = + (SelectorWithWidgetPreference) category.getPreference(i); + if (filter.test(option)) { + keys.add(category.getPreference(i).getKey()); + } + } + return keys.build(); + } + + + private static void setOptionChecked(PreferenceCategory category, String key, boolean checked) { + SelectorWithWidgetPreference preference = checkNotNull(category.findPreference(key)); + if (preference.isChecked() == checked) { + throw new IllegalArgumentException( + "This test is trying to " + (checked ? "check" : "uncheck") + " " + key + + ", but it's already " + (checked ? "checked" : "unchecked") + "!"); + } + preference.performClick(); + } + + private void setMessagesOptionChecked(String key, boolean checked) { + setOptionChecked(mMessagesPrefCategory, key, checked); + } + + private ZenPolicy getSavedPolicy() { + ArgumentCaptor captor = ArgumentCaptor.forClass(ZenMode.class); + verify(mBackend).updateMode(captor.capture()); + return captor.getValue().getPolicy(); } @Test 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 a7257f53705..948eec0277d 100644 --- a/tests/robotests/src/com/android/settings/notification/modes/ZenModesSummaryHelperTest.java +++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModesSummaryHelperTest.java @@ -21,8 +21,11 @@ import static android.provider.Settings.Global.ZEN_MODE_OFF; import static android.service.notification.Condition.SOURCE_UNKNOWN; import static android.service.notification.Condition.STATE_TRUE; import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_ANYONE; +import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_IMPORTANT; import static android.service.notification.ZenPolicy.PEOPLE_TYPE_ANYONE; import static android.service.notification.ZenPolicy.PEOPLE_TYPE_CONTACTS; +import static android.service.notification.ZenPolicy.PEOPLE_TYPE_NONE; +import static android.service.notification.ZenPolicy.PEOPLE_TYPE_STARRED; import static android.service.notification.ZenPolicy.VISUAL_EFFECT_AMBIENT; import static android.service.notification.ZenPolicy.VISUAL_EFFECT_LIGHTS; @@ -123,6 +126,59 @@ public class ZenModesSummaryHelperTest { assertThat(mSummaryHelper.getPeopleSummary(policy)).isEqualTo("All people can interrupt"); } + @Test + public void getMessagesSettingSummary_allMessages() { + ZenPolicy policy1 = new ZenPolicy.Builder() + .allowMessages(PEOPLE_TYPE_ANYONE) + .build(); + ZenPolicy policy2 = new ZenPolicy.Builder() + .allowMessages(PEOPLE_TYPE_ANYONE) + .allowConversations(CONVERSATION_SENDERS_IMPORTANT) + .build(); + ZenPolicy policy3 = new ZenPolicy.Builder() + .allowMessages(PEOPLE_TYPE_ANYONE) + .allowConversations(CONVERSATION_SENDERS_ANYONE) + .build(); + + assertThat(mSummaryHelper.getMessagesSettingSummary(policy1)).isEqualTo("Anyone"); + assertThat(mSummaryHelper.getMessagesSettingSummary(policy2)).isEqualTo("Anyone"); + assertThat(mSummaryHelper.getMessagesSettingSummary(policy3)).isEqualTo("Anyone"); + } + + @Test + public void getMessagesSettingSummary_noMessagesButSomeConversations() { + ZenPolicy policy1 = new ZenPolicy.Builder() + .allowMessages(PEOPLE_TYPE_NONE) + .allowConversations(CONVERSATION_SENDERS_IMPORTANT) + .build(); + ZenPolicy policy2 = new ZenPolicy.Builder() + .allowMessages(PEOPLE_TYPE_NONE) + .allowConversations(CONVERSATION_SENDERS_ANYONE) + .build(); + + assertThat(mSummaryHelper.getMessagesSettingSummary(policy1)).isEqualTo( + "Priority conversations"); + assertThat(mSummaryHelper.getMessagesSettingSummary(policy2)).isEqualTo( + "All conversations"); + } + + @Test + public void getMessagesSettingSummary_contactsAndConversations() { + ZenPolicy policy1 = new ZenPolicy.Builder() + .allowMessages(PEOPLE_TYPE_STARRED) + .allowConversations(CONVERSATION_SENDERS_IMPORTANT) + .build(); + ZenPolicy policy2 = new ZenPolicy.Builder() + .allowMessages(PEOPLE_TYPE_STARRED) + .allowConversations(CONVERSATION_SENDERS_ANYONE) + .build(); + + assertThat(mSummaryHelper.getMessagesSettingSummary(policy1)).isEqualTo( + "Starred contacts and priority conversations"); + assertThat(mSummaryHelper.getMessagesSettingSummary(policy2)).isEqualTo( + "Starred contacts and all conversations"); + } + @Test public void getOtherSoundCategoriesSummary_single() { ZenMode zenMode = new TestModeBuilder()