diff --git a/res/values/strings.xml b/res/values/strings.xml index a296fab84de..e5a1a8a31a3 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -7769,15 +7769,15 @@ %1$s: %2$s + + Allow interruptions that make sound + Block visual disturbances Allow visual signals - - Allow interruptions that make sound - Display options for hidden notifications @@ -8777,10 +8777,31 @@ %1$s to %2$s - - Allow calls + + Conversations + + Conversations that can interrupt + All conversations + Important conversations + None + + 1 conversation + %d conversations + + + None + + Who can interrupt + Calls + + Calls + + calls + + Calls that can interrupt To be sure allowed calls make sound, check whether your device is set to ring, vibrate, or silent. @@ -8794,26 +8815,32 @@ %d others - Conversations - From all conversations - From important conversations - Don\u2019t allow any conversations - - Allow messages + Messages + + messages + + SMS, MMS, and messaging apps + + Messages that can interrupt To be sure allowed messages make sound, check whether your device is set to ring, vibrate, or silent. For \u2018%1$s\u2019 incoming messages are blocked. You can adjust settings to allow your friends, family, or other contacts to reach you. - - SMS, MMS, and messaging apps + + + All %s can reach you + + %d contacts - From anyone + Anyone - From contacts only + Contacts - From starred contacts only + Starred contacts + + None From starred contacts and repeat callers @@ -8822,8 +8849,6 @@ From repeat callers only - - None Don\u2019t allow any calls @@ -8866,6 +8891,8 @@ Allow apps to override + + Apps that can interrupt No apps can interrupt @@ -8878,6 +8905,10 @@ %d more App exceptions + + All notifications + + Some notifications diff --git a/res/xml/conversation_list_settings.xml b/res/xml/conversation_list_settings.xml index 5b9f0c4a09f..238e92b0bee 100644 --- a/res/xml/conversation_list_settings.xml +++ b/res/xml/conversation_list_settings.xml @@ -16,11 +16,12 @@ + android:key="conversation_list" + android:title="zen_mode_conversations_title"> diff --git a/res/xml/zen_mode_calls_settings.xml b/res/xml/zen_mode_calls_settings.xml index 8366b09e01f..cbadc7d7ce4 100644 --- a/res/xml/zen_mode_calls_settings.xml +++ b/res/xml/zen_mode_calls_settings.xml @@ -19,28 +19,20 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:settings="http://schemas.android.com/apk/res-auto" android:key="zen_mode_calls_settings_page" - android:title="@string/zen_mode_calls_title" > + android:title="@string/zen_mode_calls_title"> - - - - - - - + android:key="zen_mode_settings_category_calls" + android:title="@string/zen_mode_calls_header" + settings:allowDividerBelow="true"> + + + diff --git a/res/xml/zen_mode_conversations_settings.xml b/res/xml/zen_mode_conversations_settings.xml new file mode 100644 index 00000000000..773a8b28819 --- /dev/null +++ b/res/xml/zen_mode_conversations_settings.xml @@ -0,0 +1,26 @@ + + + + + + + + \ No newline at end of file diff --git a/res/xml/zen_mode_messages_settings.xml b/res/xml/zen_mode_messages_settings.xml index 2d0129e56ba..c302b02b72e 100644 --- a/res/xml/zen_mode_messages_settings.xml +++ b/res/xml/zen_mode_messages_settings.xml @@ -21,18 +21,8 @@ android:title="@string/zen_mode_messages_title" > - - - - + android:key="zen_mode_settings_category_messages" + android:title="@string/zen_mode_messages_header"> diff --git a/res/xml/zen_mode_people_settings.xml b/res/xml/zen_mode_people_settings.xml index 7755bb75647..140c2414aa4 100644 --- a/res/xml/zen_mode_people_settings.xml +++ b/res/xml/zen_mode_people_settings.xml @@ -20,51 +20,31 @@ xmlns:settings="http://schemas.android.com/apk/res-auto" android:title="@string/zen_category_people" > + - - + android:key="zen_mode_settings_category_conversations" + android:title="@string/zen_mode_conversations_section_title"> - - - - - - - - - - - - - - - - + android:fragment="com.android.settings.notification.zen.ZenModeConversationsSettings"/> + + + + + + + + diff --git a/src/com/android/settings/notification/zen/ZenModeBackend.java b/src/com/android/settings/notification/zen/ZenModeBackend.java index 836f4358e84..bb406c1b827 100644 --- a/src/com/android/settings/notification/zen/ZenModeBackend.java +++ b/src/com/android/settings/notification/zen/ZenModeBackend.java @@ -16,8 +16,6 @@ package com.android.settings.notification.zen; -import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE; -import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT; import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON; @@ -501,7 +499,7 @@ public class ZenModeBackend { private List getStarredContacts() { Cursor cursor = null; try { - cursor = queryData(); + cursor = queryStarredContactsData(); return getStarredContacts(cursor); } finally { if (cursor != null) { @@ -510,7 +508,7 @@ public class ZenModeBackend { } } - public String getStarredContactsSummary(Context context) { + String getStarredContactsSummary(Context context) { List starredContacts = getStarredContacts(); int numStarredContacts = starredContacts.size(); @@ -536,13 +534,24 @@ public class ZenModeBackend { return ListFormatter.getInstance().format(displayContacts); } - private Cursor queryData() { + String getContactsNumberSummary(Context context) { + return context.getResources().getString(R.string.zen_mode_contacts_senders_summary, + queryAllContactsData().getCount()); + } + + private Cursor queryStarredContactsData() { return mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, new String[]{ContactsContract.Contacts.DISPLAY_NAME_PRIMARY}, ContactsContract.Data.STARRED + "=1", null, ContactsContract.Data.TIMES_CONTACTED); } + private Cursor queryAllContactsData() { + return mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, + new String[]{ContactsContract.Contacts.DISPLAY_NAME_PRIMARY}, + null, null, null); + } + @VisibleForTesting public static final Comparator> RULE_COMPARATOR = new Comparator>() { diff --git a/src/com/android/settings/notification/zen/ZenModeCallsSettings.java b/src/com/android/settings/notification/zen/ZenModeCallsSettings.java new file mode 100644 index 00000000000..1b5412e0ec8 --- /dev/null +++ b/src/com/android/settings/notification/zen/ZenModeCallsSettings.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2020 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.zen; + +import android.app.settings.SettingsEnums; +import android.content.Context; +import android.provider.SearchIndexableResource; + +import com.android.settings.R; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.lifecycle.Lifecycle; +import com.android.settingslib.search.SearchIndexable; + +import java.util.ArrayList; +import java.util.List; + +/** + * DND Calls Settings page to determine which priority senders can bypass DND. + */ +@SearchIndexable +public class ZenModeCallsSettings extends ZenModeSettingsBase { + + @Override + protected List createPreferenceControllers(Context context) { + return buildPreferenceControllers(context, getSettingsLifecycle()); + } + + private static List buildPreferenceControllers(Context context, + Lifecycle lifecycle) { + List controllers = new ArrayList<>(); + controllers.add(new ZenModePrioritySendersPreferenceController(context, + "zen_mode_settings_category_calls", lifecycle, false)); + controllers.add(new ZenModeRepeatCallersPreferenceController(context, lifecycle, + context.getResources().getInteger(com.android.internal.R.integer + .config_zen_repeat_callers_threshold))); + controllers.add(new ZenModeBehaviorFooterPreferenceController( + context, lifecycle, R.string.zen_mode_calls_footer)); + return controllers; + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.zen_mode_calls_settings; + } + + @Override + public int getMetricsCategory() { + return SettingsEnums.DND_CALLS; + } + + /** + * For Search. + */ + public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider() { + @Override + public List getXmlResourcesToIndex(Context context, + boolean enabled) { + final ArrayList result = new ArrayList<>(); + + final SearchIndexableResource sir = new SearchIndexableResource(context); + sir.xmlResId = R.xml.zen_mode_calls_settings; + result.add(sir); + return result; + } + + @Override + public List createPreferenceControllers( + Context context) { + return buildPreferenceControllers(context, null); + } + }; +} diff --git a/src/com/android/settings/notification/zen/ZenModeConversationsPreferenceController.java b/src/com/android/settings/notification/zen/ZenModeConversationsPreferenceController.java new file mode 100644 index 00000000000..f23bf614ac5 --- /dev/null +++ b/src/com/android/settings/notification/zen/ZenModeConversationsPreferenceController.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2020 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.zen; + +import android.app.NotificationManager; +import android.content.Context; +import android.provider.Settings; + +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +import com.android.settingslib.core.lifecycle.Lifecycle; + +/** + * Controls the summary for preference found at: + * Settings > Sound > Do Not Disturb > People > Conversations + */ +public class ZenModeConversationsPreferenceController extends AbstractZenModePreferenceController { + private final ZenModeBackend mBackend; + private Preference mPreference; + + public ZenModeConversationsPreferenceController(Context context, + String key, Lifecycle lifecycle) { + super(context, key, lifecycle); + mBackend = ZenModeBackend.getInstance(context); + } + + @Override + public String getPreferenceKey() { + return KEY; + } + + @Override + public boolean isAvailable() { + return true; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = screen.findPreference(KEY); + } + + @Override + public void updateState(Preference preference) { + super.updateState(preference); + switch (getZenMode()) { + case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS: + case Settings.Global.ZEN_MODE_ALARMS: + mPreference.setEnabled(false); + mPreference.setSummary(mBackend.getAlarmsTotalSilencePeopleSummary( + NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS)); + break; + default: + preference.setEnabled(true); + preference.setSummary(mBackend.getConversationSummary()); + } + } +} diff --git a/src/com/android/settings/notification/zen/ZenModeConversationsSettings.java b/src/com/android/settings/notification/zen/ZenModeConversationsSettings.java new file mode 100644 index 00000000000..4307538c0f5 --- /dev/null +++ b/src/com/android/settings/notification/zen/ZenModeConversationsSettings.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2020 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.zen; + +import android.app.settings.SettingsEnums; +import android.content.Context; + +import com.android.settings.R; +import com.android.settings.notification.NotificationBackend; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.lifecycle.Lifecycle; +import com.android.settingslib.search.SearchIndexable; + +import java.util.ArrayList; +import java.util.List; + +/** + * Settings > Sound > Do Not Disturb > Conversationss + */ +@SearchIndexable +public class ZenModeConversationsSettings extends ZenModeSettingsBase { + private final NotificationBackend mNotificationBackend = new NotificationBackend(); + + @Override + protected List createPreferenceControllers(Context context) { + return buildPreferenceControllers(context, getSettingsLifecycle(), mNotificationBackend); + } + + private static List buildPreferenceControllers(Context context, + Lifecycle lifecycle, NotificationBackend notificationBackend) { + List controllers = new ArrayList<>(); + controllers.add(new ZenModePriorityConversationsPreferenceController(context, + "zen_mode_conversations_radio_buttons", lifecycle, notificationBackend)); + return controllers; + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.zen_mode_conversations_settings; + } + + @Override + public int getMetricsCategory() { + return SettingsEnums.DND_CONVERSATIONS; + } + + /** + * For Search. + */ + public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider(R.xml.zen_mode_conversations_settings) { + + @Override + public List createPreferenceControllers( + Context context) { + return buildPreferenceControllers(context, null, null); + } + }; +} diff --git a/src/com/android/settings/notification/zen/ZenModeMessagesSettings.java b/src/com/android/settings/notification/zen/ZenModeMessagesSettings.java new file mode 100644 index 00000000000..d15a4aa428b --- /dev/null +++ b/src/com/android/settings/notification/zen/ZenModeMessagesSettings.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2020 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.zen; + +import android.app.settings.SettingsEnums; +import android.content.Context; +import android.provider.SearchIndexableResource; + +import com.android.settings.R; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.lifecycle.Lifecycle; +import com.android.settingslib.search.SearchIndexable; + +import java.util.ArrayList; +import java.util.List; + +/** + * DND Messages Settings page to determine which priority senders can bypass DND. + * "Messages" include SMS, MMS, and messaging apps. + */ +@SearchIndexable +public class ZenModeMessagesSettings extends ZenModeSettingsBase { + + @Override + protected List createPreferenceControllers(Context context) { + return buildPreferenceControllers(context, getSettingsLifecycle()); + } + + private static List buildPreferenceControllers(Context context, + Lifecycle lifecycle) { + List controllers = new ArrayList<>(); + controllers.add(new ZenModePrioritySendersPreferenceController(context, + "zen_mode_settings_category_messages", lifecycle, true)); + controllers.add(new ZenModeBehaviorFooterPreferenceController( + context, lifecycle, R.string.zen_mode_messages_footer)); + return controllers; + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.zen_mode_messages_settings; + } + + @Override + public int getMetricsCategory() { + return SettingsEnums.DND_MESSAGES; + } + + /** + * For Search. + */ + public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider() { + @Override + public List getXmlResourcesToIndex(Context context, + boolean enabled) { + final ArrayList result = new ArrayList<>(); + + final SearchIndexableResource sir = new SearchIndexableResource(context); + sir.xmlResId = R.xml.zen_mode_messages_settings; + result.add(sir); + return result; + } + + @Override + public List createPreferenceControllers( + Context context) { + return buildPreferenceControllers(context, null); + } + }; +} diff --git a/src/com/android/settings/notification/zen/ZenModePeopleSettings.java b/src/com/android/settings/notification/zen/ZenModePeopleSettings.java index ff768dbd4ed..4971e544b26 100644 --- a/src/com/android/settings/notification/zen/ZenModePeopleSettings.java +++ b/src/com/android/settings/notification/zen/ZenModePeopleSettings.java @@ -16,9 +16,6 @@ package com.android.settings.notification.zen; -import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS; -import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES; - import android.app.Activity; import android.app.Application; import android.app.settings.SettingsEnums; @@ -56,16 +53,12 @@ public class ZenModePeopleSettings extends ZenModeSettingsBase implements Indexa private static List buildPreferenceControllers(Context context, Lifecycle lifecycle, Application app, Fragment host, FragmentManager fragmentManager) { List controllers = new ArrayList<>(); - controllers.add(new ZenModePriorityMessagesPreferenceController(context, lifecycle)); - controllers.add(new ZenModeStarredContactsPreferenceController(context, lifecycle, - PRIORITY_CATEGORY_MESSAGES, "zen_mode_starred_contacts_messages")); - controllers.add(new ZenModePriorityCallsPreferenceController(context, lifecycle)); - controllers.add(new ZenModeStarredContactsPreferenceController(context, lifecycle, - PRIORITY_CATEGORY_CALLS, "zen_mode_starred_contacts_callers")); - controllers.add(new ZenModeRepeatCallersPreferenceController(context, lifecycle, - context.getResources().getInteger(com.android.internal.R.integer - .config_zen_repeat_callers_threshold))); - controllers.add(new ZenModePriorityConversationsPreferenceController(context, lifecycle)); + controllers.add(new ZenModeConversationsPreferenceController(context, + "zen_mode_conversations", lifecycle)); + controllers.add(new ZenModeCallsPreferenceController(context, lifecycle, + "zen_mode_people_calls")); + controllers.add(new ZenModeMessagesPreferenceController(context, lifecycle, + "zen_mode_people_messages")); controllers.add(new ZenModeSettingsFooterPreferenceController(context, lifecycle, fragmentManager)); return controllers; diff --git a/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java b/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java index afd17ad71ff..b6824a90f18 100644 --- a/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java +++ b/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java @@ -16,37 +16,65 @@ package com.android.settings.notification.zen; -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 android.app.NotificationManager; import android.content.Context; -import android.provider.Settings; +import android.content.pm.ParceledListSlice; +import android.os.AsyncTask; +import android.service.notification.ConversationChannelWrapper; -import androidx.preference.ListPreference; +import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; +import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceScreen; import com.android.settings.R; +import com.android.settings.notification.NotificationBackend; import com.android.settingslib.core.lifecycle.Lifecycle; +import com.android.settingslib.widget.RadioButtonPreference; +import java.util.ArrayList; +import java.util.List; + +/** + * Options to choose the priority conversations that are allowed to bypass DND. + */ public class ZenModePriorityConversationsPreferenceController - extends AbstractZenModePreferenceController - implements Preference.OnPreferenceChangeListener { + extends AbstractZenModePreferenceController { + private static final int UNSET = -1; + @VisibleForTesting static final String KEY_ALL = "conversations_all"; + @VisibleForTesting static final String KEY_IMPORTANT = "conversations_important"; + @VisibleForTesting static final String KEY_NONE = "conversations_none"; - protected static final String KEY = "zen_mode_conversations"; - private final ZenModeBackend mBackend; - private ListPreference mPreference; + private final NotificationBackend mNotificationBackend; - public ZenModePriorityConversationsPreferenceController(Context context, Lifecycle lifecycle) { - super(context, KEY, lifecycle); - mBackend = ZenModeBackend.getInstance(context); + private int mNumImportantConversations = UNSET; + private int mNumConversations = UNSET; + private PreferenceCategory mPreferenceCategory; + private List mRadioButtonPreferences = new ArrayList<>(); + + public ZenModePriorityConversationsPreferenceController(Context context, String key, + Lifecycle lifecycle, NotificationBackend notificationBackend) { + super(context, key, lifecycle); + mNotificationBackend = notificationBackend; } @Override - public String getPreferenceKey() { - return KEY; + public void displayPreference(PreferenceScreen screen) { + mPreferenceCategory = screen.findPreference(getPreferenceKey()); + if (mPreferenceCategory.findPreference(KEY_ALL) == null) { + makeRadioPreference(KEY_ALL, R.string.zen_mode_from_all_conversations); + makeRadioPreference(KEY_IMPORTANT, R.string.zen_mode_from_important_conversations); + makeRadioPreference(KEY_NONE, R.string.zen_mode_from_no_conversations); + updateChannelCounts(); + } + + super.displayPreference(screen); + } + + @Override + public void onResume() { + super.onResume(); + updateChannelCounts(); } @Override @@ -55,50 +83,98 @@ public class ZenModePriorityConversationsPreferenceController } @Override - public void displayPreference(PreferenceScreen screen) { - super.displayPreference(screen); - mPreference = screen.findPreference(KEY); + public String getPreferenceKey() { + return KEY; } @Override public void updateState(Preference preference) { - super.updateState(preference); - updateValue(preference); - } + final int currSetting = mBackend.getPriorityConversationSenders(); - @Override - public boolean onPreferenceChange(Preference preference, Object selectedContactsFrom) { - mBackend.saveConversationSenders(Integer.parseInt(selectedContactsFrom.toString())); - updateValue(preference); - return true; - } - - private void updateValue(Preference preference) { - mPreference = (ListPreference) preference; - switch (getZenMode()) { - case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS: - case Settings.Global.ZEN_MODE_ALARMS: - mPreference.setEnabled(false); - mPreference.setValue(String.valueOf(CONVERSATION_SENDERS_NONE)); - mPreference.setSummary(mBackend.getAlarmsTotalSilencePeopleSummary( - NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS)); - break; - default: - preference.setEnabled(true); - preference.setSummary(mBackend.getConversationSummary()); - int senders = mBackend.getPriorityConversationSenders(); - - switch (senders) { - case CONVERSATION_SENDERS_NONE: - mPreference.setValue(String.valueOf(CONVERSATION_SENDERS_NONE)); - break; - case CONVERSATION_SENDERS_IMPORTANT: - mPreference.setValue(String.valueOf(CONVERSATION_SENDERS_IMPORTANT)); - break; - default: - mPreference.setValue(String.valueOf(CONVERSATION_SENDERS_ANYONE)); - break; - } + for (RadioButtonPreference pref : mRadioButtonPreferences) { + pref.setChecked(keyToSetting(pref.getKey()) == currSetting); + pref.setSummary(getSummary(pref.getKey())); } } + + private static int keyToSetting(String key) { + switch (key) { + case KEY_ALL: + return NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE; + case KEY_IMPORTANT: + return NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT; + default: + return NotificationManager.Policy.CONVERSATION_SENDERS_NONE; + } + } + + private String getSummary(String key) { + int numConversations; + if (KEY_ALL.equals(key)) { + numConversations = mNumConversations; + } else if (KEY_IMPORTANT.equals(key)) { + numConversations = mNumImportantConversations; + } else { + return null; + } + + if (numConversations == UNSET) { + return null; + } else if (numConversations == 0) { + return mContext.getResources().getString( + R.string.zen_mode_conversations_count_none); + } else { + return mContext.getResources().getQuantityString( + R.plurals.zen_mode_conversations_count, numConversations); + } + } + + private void updateChannelCounts() { + // Load conversations + new AsyncTask() { + @Override + protected Void doInBackground(Void... unused) { + ParceledListSlice allConversations = + mNotificationBackend.getConversations(false); + if (allConversations != null) { + mNumConversations = allConversations.getList().size(); + } + ParceledListSlice importantConversations = + mNotificationBackend.getConversations(true); + if (importantConversations != null) { + mNumImportantConversations = importantConversations.getList().size(); + } + return null; + } + + @Override + protected void onPostExecute(Void unused) { + if (mContext == null) { + return; + } + updateState(mPreferenceCategory); + } + }.execute(); + } + + private RadioButtonPreference makeRadioPreference(String key, int titleId) { + RadioButtonPreference pref = new RadioButtonPreference(mPreferenceCategory.getContext()); + pref.setKey(key); + pref.setTitle(titleId); + pref.setOnClickListener(mRadioButtonClickListener); + mPreferenceCategory.addPreference(pref); + mRadioButtonPreferences.add(pref); + return pref; + } + + private RadioButtonPreference.OnClickListener mRadioButtonClickListener = + new RadioButtonPreference.OnClickListener() { + @Override + public void onRadioButtonClicked(RadioButtonPreference preference) { + int selectedConversationSetting = keyToSetting(preference.getKey()); + if (selectedConversationSetting != mBackend.getPriorityConversationSenders()) { + mBackend.saveConversationSenders(selectedConversationSetting); + } + } + }; } diff --git a/src/com/android/settings/notification/zen/ZenModePriorityMessagesPreferenceController.java b/src/com/android/settings/notification/zen/ZenModePriorityMessagesPreferenceController.java deleted file mode 100644 index 6476c634b84..00000000000 --- a/src/com/android/settings/notification/zen/ZenModePriorityMessagesPreferenceController.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2018 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.zen; - -import android.app.NotificationManager; -import android.content.Context; -import android.provider.Settings; -import android.text.TextUtils; - -import androidx.annotation.VisibleForTesting; -import androidx.preference.ListPreference; -import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; - -import com.android.settings.R; -import com.android.settingslib.core.lifecycle.Lifecycle; - -public class ZenModePriorityMessagesPreferenceController extends AbstractZenModePreferenceController - implements Preference.OnPreferenceChangeListener { - - protected static final String KEY = "zen_mode_messages"; - private final ZenModeBackend mBackend; - private ListPreference mPreference; - private final String[] mListValues; - - public ZenModePriorityMessagesPreferenceController(Context context, Lifecycle lifecycle) { - super(context, KEY, lifecycle); - mBackend = ZenModeBackend.getInstance(context); - mListValues = context.getResources().getStringArray(R.array.zen_mode_contacts_values); - } - - @Override - public String getPreferenceKey() { - return KEY; - } - - @Override - public boolean isAvailable() { - return true; - } - - @Override - public void displayPreference(PreferenceScreen screen) { - super.displayPreference(screen); - mPreference = screen.findPreference(KEY); - } - - @Override - public void updateState(Preference preference) { - super.updateState(preference); - updateFromContactsValue(preference); - } - - @Override - public boolean onPreferenceChange(Preference preference, Object selectedContactsFrom) { - mBackend.saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES, - ZenModeBackend.getSettingFromPrefKey(selectedContactsFrom.toString())); - updateFromContactsValue(preference); - return true; - } - - private void updateFromContactsValue(Preference preference) { - mPreference = (ListPreference) preference; - switch (getZenMode()) { - case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS: - case Settings.Global.ZEN_MODE_ALARMS: - mPreference.setEnabled(false); - mPreference.setValue(ZenModeBackend.ZEN_MODE_FROM_NONE); - mPreference.setSummary(mBackend.getAlarmsTotalSilencePeopleSummary( - NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)); - break; - default: - preference.setEnabled(true); - preference.setSummary(mBackend.getContactsSummary( - NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)); - - final String currentVal = ZenModeBackend.getKeyFromSetting( - mBackend.getPriorityMessageSenders()); - mPreference.setValue(mListValues[getIndexOfSendersValue(currentVal)]); - } - } - - @VisibleForTesting - protected int getIndexOfSendersValue(String currentVal) { - int index = 3; // defaults to "none" based on R.array.zen_mode_contacts_values - for (int i = 0; i < mListValues.length; i++) { - if (TextUtils.equals(currentVal, mListValues[i])) { - return i; - } - } - - return index; - } -} diff --git a/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceController.java b/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceController.java new file mode 100644 index 00000000000..da7b24d7d33 --- /dev/null +++ b/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceController.java @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2020 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.zen; + +import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS; +import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES; + +import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_GONE; +import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_SETTING; + +import android.app.NotificationManager; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.provider.Contacts; +import android.view.View; + +import androidx.annotation.VisibleForTesting; +import androidx.preference.Preference; +import androidx.preference.PreferenceCategory; +import androidx.preference.PreferenceScreen; + +import com.android.settings.R; +import com.android.settings.widget.RadioButtonPreferenceWithExtraWidget; +import com.android.settingslib.core.lifecycle.Lifecycle; +import com.android.settingslib.widget.RadioButtonPreference; + +import java.util.ArrayList; +import java.util.List; + +/** + * Common preference controller functionality shared by + * ZenModePriorityMessagesPreferenceController and ZenModePriorityCallsPreferenceController. + * + * This includes the options to choose the priority senders that are allowed to bypass DND for + * calls or messages. This can be one of four values: starred contacts, all contacts, anyone, or + * no one. + */ +public class ZenModePrioritySendersPreferenceController + extends AbstractZenModePreferenceController { + @VisibleForTesting static final String KEY_ANY = "senders_anyone"; + @VisibleForTesting static final String KEY_CONTACTS = "senders_contacts"; + @VisibleForTesting static final String KEY_STARRED = "senders_starred_contacts"; + @VisibleForTesting static final String KEY_NONE = "senders_none"; + + private static final Intent ALL_CONTACTS_INTENT = + new Intent(Contacts.Intents.UI.LIST_ALL_CONTACTS_ACTION); + private static final Intent STARRED_CONTACTS_INTENT = + new Intent(Contacts.Intents.UI.LIST_STARRED_ACTION); + private static final Intent FALLBACK_INTENT = new Intent(Intent.ACTION_MAIN); + + private final PackageManager mPackageManager; + private final boolean mIsMessages; // if this is false, then this preference is for calls + + private PreferenceCategory mPreferenceCategory; + private List mRadioButtonPreferences = new ArrayList<>(); + + public ZenModePrioritySendersPreferenceController(Context context, String key, + Lifecycle lifecycle, boolean isMessages) { + super(context, key, lifecycle); + mIsMessages = isMessages; + + mPackageManager = mContext.getPackageManager(); + if (!FALLBACK_INTENT.hasCategory(Intent.CATEGORY_APP_CONTACTS)) { + FALLBACK_INTENT.addCategory(Intent.CATEGORY_APP_CONTACTS); + } + } + + @Override + public void displayPreference(PreferenceScreen screen) { + mPreferenceCategory = screen.findPreference(getPreferenceKey()); + if (mPreferenceCategory.findPreference(KEY_ANY) == null) { + makeRadioPreference(KEY_STARRED, + com.android.settings.R.string.zen_mode_from_starred); + makeRadioPreference(KEY_CONTACTS, + com.android.settings.R.string.zen_mode_from_contacts); + makeRadioPreference(KEY_ANY, + com.android.settings.R.string.zen_mode_from_anyone); + makeRadioPreference(KEY_NONE, + com.android.settings.R.string.zen_mode_from_none); + updateSummaries(); + } + + super.displayPreference(screen); + } + + @Override + public boolean isAvailable() { + return true; + } + + @Override + public String getPreferenceKey() { + return KEY; + } + + @Override + public void updateState(Preference preference) { + final int currSetting = getPrioritySenders(); + + for (RadioButtonPreferenceWithExtraWidget pref : mRadioButtonPreferences) { + pref.setChecked(keyToSetting(pref.getKey()) == currSetting); + } + } + + @Override + public void onResume() { + super.onResume(); + updateSummaries(); + } + + private void updateSummaries() { + for (RadioButtonPreferenceWithExtraWidget pref : mRadioButtonPreferences) { + pref.setSummary(getSummary(pref.getKey())); + } + } + + private static int keyToSetting(String key) { + switch (key) { + case KEY_STARRED: + return NotificationManager.Policy.PRIORITY_SENDERS_STARRED; + case KEY_CONTACTS: + return NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS; + case KEY_ANY: + return NotificationManager.Policy.PRIORITY_SENDERS_ANY; + case KEY_NONE: + default: + return ZenModeBackend.SOURCE_NONE; + } + } + + private String getSummary(String key) { + switch (key) { + case KEY_STARRED: + return mBackend.getStarredContactsSummary(mContext); + case KEY_CONTACTS: + return mBackend.getContactsNumberSummary(mContext); + case KEY_ANY: + return mContext.getResources().getString(R.string.zen_mode_all_senders_summary, + mContext.getResources().getString(mIsMessages + ? R.string.zen_mode_messages_list + : R.string.zen_mode_calls_list)); + case KEY_NONE: + default: + return null; + } + } + + private int getPrioritySenders() { + if (mIsMessages) { + return mBackend.getPriorityMessageSenders(); + } else { + return mBackend.getPriorityCallSenders(); + } + } + + private RadioButtonPreferenceWithExtraWidget makeRadioPreference(String key, int titleId) { + RadioButtonPreferenceWithExtraWidget pref = + new RadioButtonPreferenceWithExtraWidget(mPreferenceCategory.getContext()); + View.OnClickListener widgetClickListener = getWidgetClickListener(key); + if (widgetClickListener != null) { + pref.setExtraWidgetOnClickListener(widgetClickListener); + pref.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_SETTING); + } else { + pref.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_GONE); + } + + pref.setKey(key); + pref.setTitle(titleId); + pref.setOnClickListener(mRadioButtonClickListener); + mPreferenceCategory.addPreference(pref); + mRadioButtonPreferences.add(pref); + return pref; + } + + private RadioButtonPreference.OnClickListener mRadioButtonClickListener = + new RadioButtonPreference.OnClickListener() { + @Override + public void onRadioButtonClicked(RadioButtonPreference preference) { + int selectedSetting = keyToSetting(preference.getKey()); + if (selectedSetting != getPrioritySenders()) { + mBackend.saveSenders( + mIsMessages ? PRIORITY_CATEGORY_MESSAGES : PRIORITY_CATEGORY_CALLS, + selectedSetting); + } + } + }; + + private View.OnClickListener getWidgetClickListener(String key) { + if (!KEY_CONTACTS.equals(key) && !KEY_STARRED.equals(key)) { + return null; + } + + if (KEY_STARRED.equals(key) && !isStarredIntentValid()) { + return null; + } + + if (KEY_CONTACTS.equals(key) && !isContactsIntentValid()) { + return null; + } + + return new View.OnClickListener() { + @Override + public void onClick(View v) { + if (KEY_STARRED.equals(key) + && STARRED_CONTACTS_INTENT.resolveActivity(mPackageManager) != null) { + mContext.startActivity(STARRED_CONTACTS_INTENT); + } else if (KEY_CONTACTS.equals(key) + && ALL_CONTACTS_INTENT.resolveActivity(mPackageManager) != null) { + mContext.startActivity(ALL_CONTACTS_INTENT); + } else { + mContext.startActivity(FALLBACK_INTENT); + } + } + }; + } + + private boolean isStarredIntentValid() { + return STARRED_CONTACTS_INTENT.resolveActivity(mPackageManager) != null + || FALLBACK_INTENT.resolveActivity(mPackageManager) != null; + } + + private boolean isContactsIntentValid() { + return ALL_CONTACTS_INTENT.resolveActivity(mPackageManager) != null + || FALLBACK_INTENT.resolveActivity(mPackageManager) != null; + } +} diff --git a/src/com/android/settings/notification/zen/ZenModeStarredContactsPreferenceController.java b/src/com/android/settings/notification/zen/ZenModeStarredContactsPreferenceController.java deleted file mode 100644 index 64f20103ea1..00000000000 --- a/src/com/android/settings/notification/zen/ZenModeStarredContactsPreferenceController.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2018 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.zen; - -import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS; -import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES; -import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_STARRED; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.provider.Contacts; - -import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; - -import com.android.settings.dashboard.DashboardFragment; -import com.android.settingslib.core.lifecycle.Lifecycle; - -public class ZenModeStarredContactsPreferenceController extends - AbstractZenModePreferenceController implements Preference.OnPreferenceClickListener { - private Preference mPreference; - private final int mPriorityCategory; - private final PackageManager mPackageManager; - - private Intent mStarredContactsIntent; - private Intent mFallbackIntent; - - public ZenModeStarredContactsPreferenceController(Context context, Lifecycle lifecycle, int - priorityCategory, String key) { - super(context, key, lifecycle); - mPriorityCategory = priorityCategory; - mPackageManager = mContext.getPackageManager(); - - mStarredContactsIntent = new Intent(Contacts.Intents.UI.LIST_STARRED_ACTION); - - mFallbackIntent = new Intent(Intent.ACTION_MAIN); - mFallbackIntent.addCategory(Intent.CATEGORY_APP_CONTACTS); - } - - @Override - public void displayPreference(PreferenceScreen screen) { - super.displayPreference(screen); - mPreference = screen.findPreference(KEY); - - if (mPreference != null) { - mPreference.setOnPreferenceClickListener(this); - } - } - - @Override - public String getPreferenceKey() { - return KEY; - } - - @Override - public boolean isAvailable() { - if (mPriorityCategory == PRIORITY_CATEGORY_CALLS) { - return mBackend.isPriorityCategoryEnabled(PRIORITY_CATEGORY_CALLS) - && mBackend.getPriorityCallSenders() == PRIORITY_SENDERS_STARRED - && isIntentValid(); - } else if (mPriorityCategory == PRIORITY_CATEGORY_MESSAGES) { - return mBackend.isPriorityCategoryEnabled(PRIORITY_CATEGORY_MESSAGES) - && mBackend.getPriorityMessageSenders() == PRIORITY_SENDERS_STARRED - && isIntentValid(); - } else { - // invalid category - return false; - } - } - - @Override - public CharSequence getSummary() { - return mBackend.getStarredContactsSummary(mContext); - } - - @Override - public boolean onPreferenceClick(Preference preference) { - mMetricsFeatureProvider.logClickedPreference(preference, - preference.getExtras().getInt(DashboardFragment.CATEGORY)); - if (mStarredContactsIntent.resolveActivity(mPackageManager) != null) { - mContext.startActivity(mStarredContactsIntent); - } else { - mContext.startActivity(mFallbackIntent); - } - return true; - } - - private boolean isIntentValid() { - return mStarredContactsIntent.resolveActivity(mPackageManager) != null - || mFallbackIntent.resolveActivity(mPackageManager) != null; - } -} diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceControllerTest.java index 1583b9106ca..a8a8a7a3ed3 100644 --- a/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceControllerTest.java @@ -19,173 +19,131 @@ package com.android.settings.notification.zen; import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE; import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT; import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_NONE; -import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS; -import static android.provider.Settings.Global.ZEN_MODE; -import static android.provider.Settings.Global.ZEN_MODE_ALARMS; -import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; -import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS; +import static com.android.settings.notification.zen.ZenModePriorityConversationsPreferenceController.KEY_ALL; +import static com.android.settings.notification.zen.ZenModePriorityConversationsPreferenceController.KEY_IMPORTANT; +import static com.android.settings.notification.zen.ZenModePriorityConversationsPreferenceController.KEY_NONE; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.NotificationManager; import android.content.ContentResolver; import android.content.Context; -import android.provider.Settings; -import androidx.preference.ListPreference; +import androidx.preference.Preference; +import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceScreen; -import com.android.settings.R; +import com.android.settings.notification.NotificationBackend; import com.android.settingslib.core.lifecycle.Lifecycle; +import com.android.settingslib.widget.RadioButtonPreference; import org.junit.Before; 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; -import org.robolectric.shadows.ShadowApplication; import org.robolectric.util.ReflectionHelpers; +import java.util.List; + @RunWith(RobolectricTestRunner.class) public class ZenModePriorityConversationsPreferenceControllerTest { private ZenModePriorityConversationsPreferenceController mController; @Mock - private ZenModeBackend mBackend; + private ZenModeBackend mZenBackend; @Mock - private NotificationManager mNotificationManager; - @Mock - private ListPreference mockPref; + private PreferenceCategory mMockPrefCategory; @Mock private NotificationManager.Policy mPolicy; @Mock private PreferenceScreen mPreferenceScreen; + @Mock + private NotificationBackend mNotifBackend; + + private List mRadioButtonPreferences; private ContentResolver mContentResolver; private Context mContext; - @Before public void setup() { MockitoAnnotations.initMocks(this); - ShadowApplication shadowApplication = ShadowApplication.getInstance(); - shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager); - mContext = RuntimeEnvironment.application; - mContentResolver = RuntimeEnvironment.application.getContentResolver(); - when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy); - - when(mBackend.getPriorityConversationSenders()) - .thenReturn(CONVERSATION_SENDERS_IMPORTANT); - when(mBackend.getAlarmsTotalSilencePeopleSummary(PRIORITY_CATEGORY_CONVERSATIONS)) - .thenCallRealMethod(); - when(mBackend.getConversationSummary()).thenCallRealMethod(); - mController = new ZenModePriorityConversationsPreferenceController( - mContext, mock(Lifecycle.class)); - ReflectionHelpers.setField(mController, "mBackend", mBackend); + mContext, "test_key", mock(Lifecycle.class), mNotifBackend); + ReflectionHelpers.setField(mController, "mBackend", mZenBackend); - when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref); + when(mMockPrefCategory.getContext()).thenReturn(mContext); + when(mPreferenceScreen.findPreference(mController.getPreferenceKey())) + .thenReturn(mMockPrefCategory); + captureRadioButtons(); + } + + @Test + public void displayPreference_radioButtonsCreatedOnlyOnce() { + when(mMockPrefCategory.findPreference(any())).thenReturn(mock(Preference.class)); + + // radio buttons were already created, so don't re-create them mController.displayPreference(mPreferenceScreen); + verify(mMockPrefCategory, never()).addPreference(any()); } @Test - public void updateState_TotalSilence() { - Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_NO_INTERRUPTIONS); + public void clickAllConversations() { + RadioButtonPreference allConversationsRb = getButton(KEY_ALL); + allConversationsRb.onClick(); - when(mBackend.isPriorityCategoryEnabled(PRIORITY_CATEGORY_CONVERSATIONS)).thenReturn(true); - final ListPreference mockPref = mock(ListPreference.class); - mController.updateState(mockPref); - - verify(mockPref).setEnabled(false); - verify(mockPref).setSummary(R.string.zen_mode_from_no_conversations); + verify(mZenBackend).saveConversationSenders(CONVERSATION_SENDERS_ANYONE); } @Test - public void updateState_AlarmsOnly() { - Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_ALARMS); + public void clickImportantConversations() { + RadioButtonPreference importantConversationsRb = getButton(KEY_IMPORTANT); + importantConversationsRb.onClick(); - final ListPreference mockPref = mock(ListPreference.class); - mController.updateState(mockPref); - - verify(mockPref).setEnabled(false); - verify(mockPref).setSummary(R.string.zen_mode_from_no_conversations); + verify(mZenBackend).saveConversationSenders(CONVERSATION_SENDERS_IMPORTANT); } @Test - public void updateState_Priority_important() { - Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS); - when(mBackend.isPriorityCategoryEnabled(PRIORITY_CATEGORY_CONVERSATIONS)).thenReturn(true); + public void clickNoConversations() { + RadioButtonPreference noConversationsRb = getButton(KEY_NONE); + noConversationsRb.onClick(); - mController.updateState(mockPref); - - verify(mockPref).setEnabled(true); - verify(mockPref).setSummary(R.string.zen_mode_from_important_conversations); - verify(mockPref).setValue(String.valueOf(CONVERSATION_SENDERS_IMPORTANT)); + verify(mZenBackend) + .saveConversationSenders(CONVERSATION_SENDERS_NONE); } - @Test - public void updateState_Priority_all() { - Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS); - when(mBackend.getPriorityConversationSenders()).thenReturn(CONVERSATION_SENDERS_ANYONE); - when(mBackend.isPriorityCategoryEnabled(PRIORITY_CATEGORY_CONVERSATIONS)).thenReturn(true); + private void captureRadioButtons() { + ArgumentCaptor rbCaptor = + ArgumentCaptor.forClass(RadioButtonPreference.class); + mController.displayPreference(mPreferenceScreen); + // verifies 3 buttons were added + verify(mMockPrefCategory, times(3)).addPreference(rbCaptor.capture()); + mRadioButtonPreferences = rbCaptor.getAllValues(); + assertThat(mRadioButtonPreferences.size()).isEqualTo(3); - mController.updateState(mockPref); - - verify(mockPref).setEnabled(true); - verify(mockPref).setSummary(R.string.zen_mode_from_all_conversations); - verify(mockPref).setValue(String.valueOf(CONVERSATION_SENDERS_ANYONE)); + reset(mMockPrefCategory); } - @Test - public void updateState_Priority_none() { - Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS); - when(mBackend.getPriorityConversationSenders()).thenReturn(CONVERSATION_SENDERS_NONE); - when(mBackend.isPriorityCategoryEnabled(PRIORITY_CATEGORY_CONVERSATIONS)).thenReturn(false); - - mController.updateState(mockPref); - - verify(mockPref).setEnabled(true); - verify(mockPref).setSummary(R.string.zen_mode_from_no_conversations); - verify(mockPref).setValue(String.valueOf(CONVERSATION_SENDERS_NONE)); - } - - @Test - public void onPreferenceChange_noneToImportant() { - // start with none - - Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS); - when(mBackend.getPriorityConversationSenders()).thenReturn(CONVERSATION_SENDERS_NONE); - when(mBackend.isPriorityCategoryEnabled(PRIORITY_CATEGORY_CONVERSATIONS)).thenReturn(false); - - mController.updateState(mockPref); - reset(mBackend); - - mController.onPreferenceChange(mockPref, String.valueOf(CONVERSATION_SENDERS_IMPORTANT)); - - verify(mBackend).saveConversationSenders(CONVERSATION_SENDERS_IMPORTANT); - verify(mBackend).getPriorityConversationSenders(); - } - - @Test - public void onPreferenceChange_allToNone() { - // start with none - - Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS); - when(mBackend.getPriorityConversationSenders()).thenReturn(CONVERSATION_SENDERS_ANYONE); - when(mBackend.isPriorityCategoryEnabled(PRIORITY_CATEGORY_CONVERSATIONS)).thenReturn(true); - - mController.updateState(mockPref); - reset(mBackend); - - mController.onPreferenceChange(mockPref, String.valueOf(CONVERSATION_SENDERS_NONE)); - - verify(mBackend).saveConversationSenders(CONVERSATION_SENDERS_NONE); - verify(mBackend).getPriorityConversationSenders(); + private RadioButtonPreference getButton(String key) { + for (RadioButtonPreference pref : mRadioButtonPreferences) { + if (key.equals(pref.getKey())) { + return pref; + } + } + return null; } } \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityMessagesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityMessagesPreferenceControllerTest.java deleted file mode 100644 index 7af2211b05e..00000000000 --- a/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityMessagesPreferenceControllerTest.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2017 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.zen; - -import static android.provider.Settings.Global.ZEN_MODE; -import static android.provider.Settings.Global.ZEN_MODE_ALARMS; -import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; -import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.NotificationManager; -import android.content.ContentResolver; -import android.content.Context; -import android.provider.Settings; - -import androidx.preference.ListPreference; -import androidx.preference.PreferenceScreen; - -import com.android.settings.R; -import com.android.settingslib.core.lifecycle.Lifecycle; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.shadows.ShadowApplication; -import org.robolectric.util.ReflectionHelpers; - -@RunWith(RobolectricTestRunner.class) -public class ZenModePriorityMessagesPreferenceControllerTest { - - private ZenModePriorityMessagesPreferenceController mController; - - @Mock - private ZenModeBackend mBackend; - @Mock - private NotificationManager mNotificationManager; - @Mock - private ListPreference mockPref; - @Mock - private NotificationManager.Policy mPolicy; - @Mock - private PreferenceScreen mPreferenceScreen; - private ContentResolver mContentResolver; - private Context mContext; - - /** - * Array Values Key - * 0: anyone - * 1: contacts - * 2: starred - * 3: none - */ - private String[] mValues; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - ShadowApplication shadowApplication = ShadowApplication.getInstance(); - shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager); - - mContext = RuntimeEnvironment.application; - mValues = mContext.getResources().getStringArray(R.array.zen_mode_contacts_values); - mContentResolver = RuntimeEnvironment.application.getContentResolver(); - when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy); - - when(mBackend.getPriorityMessageSenders()) - .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_STARRED); - when(mBackend.getAlarmsTotalSilencePeopleSummary( - NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)).thenCallRealMethod(); - when(mBackend.getContactsSummary(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)) - .thenCallRealMethod(); - - mController = new ZenModePriorityMessagesPreferenceController(mContext, mock(Lifecycle.class)); - ReflectionHelpers.setField(mController, "mBackend", mBackend); - - when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref); - mController.displayPreference(mPreferenceScreen); - } - - @Test - public void updateState_TotalSilence() { - Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_NO_INTERRUPTIONS); - - when(mBackend.isPriorityCategoryEnabled( - NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)) - .thenReturn(false); - final ListPreference mockPref = mock(ListPreference.class); - mController.updateState(mockPref); - - verify(mockPref).setEnabled(false); - verify(mockPref).setSummary(R.string.zen_mode_from_none_messages); - } - - @Test - public void updateState_AlarmsOnly() { - Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_ALARMS); - - final ListPreference mockPref = mock(ListPreference.class); - mController.updateState(mockPref); - - verify(mockPref).setEnabled(false); - verify(mockPref).setSummary(R.string.zen_mode_from_none_messages); - } - - @Test - public void updateState_Priority() { - Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS); - - when(mBackend.isPriorityCategoryEnabled( - NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)) - .thenReturn(true); - - mController.updateState(mockPref); - - verify(mockPref).setEnabled(true); - verify(mockPref).setSummary(R.string.zen_mode_from_starred); - } - - @Test - public void onPreferenceChange_setSelectedContacts_any() { - Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS); - when(mBackend.getPriorityMessageSenders()).thenReturn( - NotificationManager.Policy.PRIORITY_SENDERS_ANY); - mController.updateState(mockPref); - verify(mockPref).setValue(mValues[mController.getIndexOfSendersValue( - ZenModeBackend.ZEN_MODE_FROM_ANYONE)]); - } - - @Test - public void onPreferenceChange_setSelectedContacts_none() { - Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS); - when(mBackend.getPriorityMessageSenders()).thenReturn(ZenModeBackend.SOURCE_NONE); - mController.updateState(mockPref); - verify(mockPref).setValue(mValues[mController.getIndexOfSendersValue( - ZenModeBackend.ZEN_MODE_FROM_NONE)]); - } - - @Test - public void onPreferenceChange_setSelectedContacts_starred() { - Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS); - when(mBackend.getPriorityMessageSenders()).thenReturn( - NotificationManager.Policy.PRIORITY_SENDERS_STARRED); - mController.updateState(mockPref); - verify(mockPref).setValue(mValues[mController.getIndexOfSendersValue( - ZenModeBackend.ZEN_MODE_FROM_STARRED)]); - } - - @Test - public void onPreferenceChange_setSelectedContacts_contacts() { - Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS); - when(mBackend.getPriorityMessageSenders()).thenReturn( - NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS); - mController.updateState(mockPref); - verify(mockPref).setValue(mValues[mController.getIndexOfSendersValue( - ZenModeBackend.ZEN_MODE_FROM_CONTACTS)]); - } -} \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceControllerTest.java new file mode 100644 index 00000000000..7dde1cd042e --- /dev/null +++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceControllerTest.java @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2020 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.zen; + +import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES; +import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_ANY; +import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS; +import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_STARRED; + +import static com.android.settings.notification.zen.ZenModePrioritySendersPreferenceController.KEY_ANY; +import static com.android.settings.notification.zen.ZenModePrioritySendersPreferenceController.KEY_CONTACTS; +import static com.android.settings.notification.zen.ZenModePrioritySendersPreferenceController.KEY_NONE; +import static com.android.settings.notification.zen.ZenModePrioritySendersPreferenceController.KEY_STARRED; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.app.NotificationManager; +import android.content.ContentResolver; +import android.content.Context; + +import androidx.preference.Preference; +import androidx.preference.PreferenceCategory; +import androidx.preference.PreferenceScreen; + +import com.android.settings.notification.NotificationBackend; +import com.android.settingslib.core.lifecycle.Lifecycle; +import com.android.settingslib.widget.RadioButtonPreference; + +import org.junit.Before; +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; +import org.robolectric.util.ReflectionHelpers; + +import java.util.List; + +@RunWith(RobolectricTestRunner.class) +public class ZenModePrioritySendersPreferenceControllerTest { + + private ZenModePrioritySendersPreferenceController mMessagesController; + + @Mock + private ZenModeBackend mZenBackend; + @Mock + private PreferenceCategory mMockPrefCategory; + @Mock + private NotificationManager.Policy mPolicy; + @Mock + private PreferenceScreen mPreferenceScreen; + @Mock + private NotificationBackend mNotifBackend; + + private List mRadioButtonPreferences; + private ContentResolver mContentResolver; + private Context mContext; + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + mMessagesController = new ZenModePrioritySendersPreferenceController( + mContext, "test_key_messages", mock(Lifecycle.class), true); + ReflectionHelpers.setField(mMessagesController, "mBackend", mZenBackend); + + when(mMockPrefCategory.getContext()).thenReturn(mContext); + when(mPreferenceScreen.findPreference(mMessagesController.getPreferenceKey())) + .thenReturn(mMockPrefCategory); + captureRadioButtons(); + } + + @Test + public void displayPreference_radioButtonsCreatedOnlyOnce() { + when(mMockPrefCategory.findPreference(any())).thenReturn(mock(Preference.class)); + + // radio buttons were already created, so don't re-create them + mMessagesController.displayPreference(mPreferenceScreen); + verify(mMockPrefCategory, never()).addPreference(any()); + } + + @Test + public void clickAnySenders() { + // GIVEN current priority message senders are STARRED + when(mZenBackend.getPriorityMessageSenders()).thenReturn(PRIORITY_SENDERS_STARRED); + + // WHEN user clicks the any senders option + RadioButtonPreference allSendersRb = getButton(KEY_ANY); + allSendersRb.onClick(); + + // THEN any senders gets saved as priority senders for messages + verify(mZenBackend).saveSenders(PRIORITY_CATEGORY_MESSAGES, PRIORITY_SENDERS_ANY); + } + + @Test + public void clickStarredSenders() { + // GIVEN current priority message senders are ANY + when(mZenBackend.getPriorityMessageSenders()).thenReturn(PRIORITY_SENDERS_ANY); + + // WHEN user clicks the starred contacts option + RadioButtonPreference starredRb = getButton(KEY_STARRED); + starredRb.onClick(); + + // THEN starred contacts gets saved as priority senders for messages + verify(mZenBackend).saveSenders(PRIORITY_CATEGORY_MESSAGES, PRIORITY_SENDERS_STARRED); + } + + @Test + public void clickContactsSenders() { + // GIVEN current priority message senders are ANY + when(mZenBackend.getPriorityMessageSenders()).thenReturn(PRIORITY_SENDERS_ANY); + + // WHEN user clicks the contacts only option + RadioButtonPreference contactsRb = getButton(KEY_CONTACTS); + contactsRb.onClick(); + + // THEN contacts gets saved as priority senders for messages + verify(mZenBackend).saveSenders(PRIORITY_CATEGORY_MESSAGES, PRIORITY_SENDERS_CONTACTS); + } + + @Test + public void clickNoSenders() { + // GIVEN current priority message senders are ANY + when(mZenBackend.getPriorityMessageSenders()).thenReturn(PRIORITY_SENDERS_ANY); + + // WHEN user clicks the no senders option + RadioButtonPreference noSenders = getButton(KEY_NONE); + noSenders.onClick(); + + // THEN no senders gets saved as priority senders for messages + verify(mZenBackend).saveSenders(PRIORITY_CATEGORY_MESSAGES, ZenModeBackend.SOURCE_NONE); + } + + @Test + public void clickSameOptionMultipleTimes() { + // GIVEN current priority message senders are ANY + when(mZenBackend.getPriorityMessageSenders()).thenReturn(PRIORITY_SENDERS_ANY); + + // WHEN user clicks the any senders option multiple times again + RadioButtonPreference anySenders = getButton(KEY_ANY); + anySenders.onClick(); + anySenders.onClick(); + anySenders.onClick(); + + // THEN no senders are saved because this setting is already in effect + verify(mZenBackend, never()).saveSenders(PRIORITY_CATEGORY_MESSAGES, PRIORITY_SENDERS_ANY); + } + + private void captureRadioButtons() { + ArgumentCaptor rbCaptor = + ArgumentCaptor.forClass(RadioButtonPreference.class); + mMessagesController.displayPreference(mPreferenceScreen); + + // verifies 4 buttons were added + verify(mMockPrefCategory, times(4)).addPreference(rbCaptor.capture()); + mRadioButtonPreferences = rbCaptor.getAllValues(); + assertThat(mRadioButtonPreferences.size()).isEqualTo(4); + + reset(mMockPrefCategory); + } + + private RadioButtonPreference getButton(String key) { + for (RadioButtonPreference pref : mRadioButtonPreferences) { + if (key.equals(pref.getKey())) { + return pref; + } + } + return null; + } +} diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModeStarredContactsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModeStarredContactsPreferenceControllerTest.java deleted file mode 100644 index f27367a985d..00000000000 --- a/tests/robotests/src/com/android/settings/notification/zen/ZenModeStarredContactsPreferenceControllerTest.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2018 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.zen; - -import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS; -import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES; - -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.when; - -import android.app.NotificationManager; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; - -import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; - -import com.android.settings.notification.zen.ZenModeBackend; -import com.android.settings.notification.zen.ZenModeStarredContactsPreferenceController; -import com.android.settingslib.core.lifecycle.Lifecycle; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.shadows.ShadowApplication; -import org.robolectric.util.ReflectionHelpers; - - -@RunWith(RobolectricTestRunner.class) -public class ZenModeStarredContactsPreferenceControllerTest { - - private ZenModeStarredContactsPreferenceController mCallsController; - private ZenModeStarredContactsPreferenceController mMessagesController; - - @Mock - private ZenModeBackend mBackend; - @Mock - private NotificationManager mNotificationManager; - @Mock - private Preference mockPref; - @Mock - private NotificationManager.Policy mPolicy; - @Mock - private PreferenceScreen mPreferenceScreen; - @Mock - private Intent testIntent; - @Mock - private ComponentName mComponentName; - private Context mContext; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - ShadowApplication shadowApplication = ShadowApplication.getInstance(); - shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager); - - mContext = RuntimeEnvironment.application; - when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy); - when(testIntent.resolveActivity(any())).thenReturn(mComponentName); - - mCallsController = new ZenModeStarredContactsPreferenceController( - mContext, mock(Lifecycle.class), PRIORITY_CATEGORY_CALLS, - "zen_mode_starred_contacts_callers"); - ReflectionHelpers.setField(mCallsController, "mBackend", mBackend); - ReflectionHelpers.setField(mCallsController, "mStarredContactsIntent", testIntent); - when(mPreferenceScreen.findPreference(mCallsController.getPreferenceKey())) - .thenReturn(mockPref); - mCallsController.displayPreference(mPreferenceScreen); - - mMessagesController = new ZenModeStarredContactsPreferenceController( - mContext, mock(Lifecycle.class), PRIORITY_CATEGORY_MESSAGES, - "zen_mode_starred_contacts_messages"); - ReflectionHelpers.setField(mMessagesController, "mBackend", mBackend); - ReflectionHelpers.setField(mMessagesController, "mStarredContactsIntent", testIntent); - when(mPreferenceScreen.findPreference(mMessagesController.getPreferenceKey())) - .thenReturn(mockPref); - mMessagesController.displayPreference(mPreferenceScreen); - } - - @Test - public void isAvailable_noCallers() { - when(mBackend.isPriorityCategoryEnabled(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS)) - .thenReturn(false); - assertThat(mCallsController.isAvailable()).isFalse(); - } - - @Test - public void isAvailable_anyCallers() { - when(mBackend.isPriorityCategoryEnabled(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS)) - .thenReturn(true); - when(mBackend.getPriorityCallSenders()) - .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_ANY); - - assertThat(mCallsController.isAvailable()).isFalse(); - } - - @Test - public void isAvailable_starredCallers() { - when(mBackend.isPriorityCategoryEnabled(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS)) - .thenReturn(true); - when(mBackend.getPriorityCallSenders()) - .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_STARRED); - - assertThat(mCallsController.isAvailable()).isTrue(); - } - - @Test - public void isAvailable_noMessages() { - when(mBackend.isPriorityCategoryEnabled( - NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)).thenReturn(false); - assertThat(mMessagesController.isAvailable()).isFalse(); - } - - @Test - public void isAvailable_anyMessages() { - when(mBackend.isPriorityCategoryEnabled( - NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)).thenReturn(true); - when(mBackend.getPriorityMessageSenders()) - .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_ANY); - - assertThat(mMessagesController.isAvailable()).isFalse(); - } - - @Test - public void isAvailable_starredMessageContacts() { - when(mBackend.isPriorityCategoryEnabled( - NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)).thenReturn(true); - when(mBackend.getPriorityMessageSenders()) - .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_STARRED); - - assertThat(mMessagesController.isAvailable()).isTrue(); - } - - @Test - public void nullPreference_displayPreference() { - when(mPreferenceScreen.findPreference(mMessagesController.getPreferenceKey())) - .thenReturn(null); - - // should not throw a null pointer - mMessagesController.displayPreference(mPreferenceScreen); - } -}