Update DND people Settings pages

Settings > Sound > Do Not Disturb > People
- Redesign of messages + calls settings pages
- Redesign of conversations page
- Added strings for Apps page

Test: make RunSettingsRoboTests7
Bug: 151845457
Change-Id: I58d22a31c398418c053e06a4c6bf5ed8c482ee35
This commit is contained in:
Beverly
2020-03-19 16:58:20 -04:00
committed by Beverly Tai
parent 509273cc03
commit e65db314f1
20 changed files with 1081 additions and 827 deletions

View File

@@ -7769,15 +7769,15 @@
<!-- Do not disturb: Zen mode combined summary + condition line [CHAR LIMIT=60] -->
<string name="zen_mode_summary_combination"><xliff:g id="mode" example="Priority only">%1$s</xliff:g>: <xliff:g id="exit condition" example="Until you turn this off">%2$s</xliff:g></string>
<!-- Do not disturb: zen settings screens category title [CHAR LIMIT=100] -->
<string name="zen_mode_settings_category">Allow interruptions that make sound</string>
<!-- Do not disturb: Title for the Visual interruptions option and associated settings page. [CHAR LIMIT=30] -->
<string name="zen_mode_visual_interruptions_settings_title">Block visual disturbances</string>
<!-- Do not disturb: Subtitle for the Visual signals option to toggle on/off visual signals/alerts when the screen is on/when screen is off. [CHAR LIMIT=30] -->
<string name="zen_mode_visual_signals_settings_subtitle">Allow visual signals</string>
<!-- Do not disturb: zen settings screens category title [CHAR LIMIT=100] -->
<string name="zen_mode_settings_category">Allow interruptions that make sound</string>
<!-- Do not disturb: restrict notifications settings title [CHAR LIMIT=80] -->
<string name="zen_mode_restrict_notifications_title">Display options for hidden notifications</string>
<!-- Do not disturb: Mute notifications option [CHAR LIMIT=60] -->
@@ -8777,10 +8777,31 @@
<!-- [CHAR LIMIT=40] General template for a verbal start to end range in a text summary -->
<string name="summary_range_verbal_combination"><xliff:g id="start" example="Sun">%1$s</xliff:g> to <xliff:g id="end" example="Thu">%2$s</xliff:g></string>
<!-- [CHAR LIMIT=20] Zen mode settings: Calls option -->
<string name="zen_mode_calls">Allow calls</string>
<!-- [CHAR LIMIT=120] Zen mode settings: Title for conversations settings page -->
<string name="zen_mode_conversations_title">Conversations</string>
<!-- [CHAR LIMIT=120] Zen mode settings: Header for conversations settings page -->
<string name="zen_mode_conversations_section_title">Conversations that can interrupt</string>
<string name="zen_mode_from_all_conversations">All conversations</string>
<string name="zen_mode_from_important_conversations">Important conversations</string>
<string name="zen_mode_from_no_conversations">None</string>
<plurals name="zen_mode_conversations_count">
<item quantity="one">1 conversation</item>
<item quantity="other"><xliff:g id="conversations" example="3">%d</xliff:g> conversations</item>
</plurals>
<!-- [CHAR LIMIT=40] Zen mode settings: No conversations are allowed to bypass DND -->
<string name="zen_mode_conversations_count_none">None</string>
<!-- [CHAR LIMIT=120] Zen mode settings: Header for calls and messages section of conversations
setting page -->
<string name="zen_mode_people_calls_messages_section_title">Who can interrupt</string>
<!-- [CHAR LIMIT=40] Zen mode settings: Allow calls toggle title -->
<string name="zen_mode_calls_title">Calls</string>
<!-- [CHAR LIMIT=20] Zen mode settings: Calls option -->
<string name="zen_mode_calls">Calls</string>
<!-- [CHAR LIMIT=20] Zen mode settings: Calls option -->
<string name="zen_mode_calls_list">calls</string>
<!-- [CHAR LIMIT=120] Zen mode settings: Calls settings header -->
<string name="zen_mode_calls_header">Calls that can interrupt</string>
<!-- [CHAR LIMIT=NONE] Zen mode settings: Calls screen footer -->
<string name="zen_mode_calls_footer">To be sure allowed calls make sound, check whether your device is set to ring, vibrate, or silent.</string>
<!-- [CHAR LIMIT=NONE] Zen mode custom rule settings: Calls screen footer -->
@@ -8794,26 +8815,32 @@
<item quantity="other"><xliff:g id="num_people" example="3">%d</xliff:g> others</item>
</plurals>
<string name="zen_mode_conversations_title">Conversations</string>
<string name="zen_mode_from_all_conversations">From all conversations</string>
<string name="zen_mode_from_important_conversations">From important conversations</string>
<string name="zen_mode_from_no_conversations">Don\u2019t allow any conversations</string>
<!-- [CHAR LIMIT=40] Zen mode settings: Messages option -->
<string name="zen_mode_messages">Allow messages</string>
<string name="zen_mode_messages">Messages</string>
<!-- [CHAR LIMIT=40] Zen mode settings: Messages option -->
<string name="zen_mode_messages_list">messages</string>
<!-- [CHAR LIMIT=40] Zen mode settings: Allow messages to bypass DND title -->
<string name="zen_mode_messages_title">SMS, MMS, and messaging apps</string>
<!-- [CHAR LIMIT=120] Zen mode settings: Messages settings header -->
<string name="zen_mode_messages_header">Messages that can interrupt</string>
<!-- Do not disturb settings, messages, events and reminders footer [CHAR LIMIT=NONE]-->
<string name="zen_mode_messages_footer">To be sure allowed messages make sound, check whether your device is set to ring, vibrate, or silent.</string>
<!-- [CHAR LIMIT=NONE] Zen mode custom rule settings: Messages screen footer -->
<string name="zen_mode_custom_messages_footer">For \u2018<xliff:g id="schedule_name" example="Schedule 1">%1$s</xliff:g>\u2019 incoming messages are blocked. You can adjust settings to allow your friends, family, or other contacts to reach you.</string>
<!-- [CHAR LIMIT=40] Zen mode settings: Allow messages to bypass DND title -->
<string name="zen_mode_messages_title">SMS, MMS, and messaging apps</string>
<!-- Zen mode settings: All senders can bypass DND summary [CHAR LIMIT=NONE -->
<string name="zen_mode_all_senders_summary">All <xliff:g id="sender_category" example="messages">%s</xliff:g> can reach you</string>
<!-- Zen mode settings: Senders in contacts can bypass DND summary summary [CHAR LIMIT=NONE -->
<string name="zen_mode_contacts_senders_summary"><xliff:g id="num_contacts" example="120">%d</xliff:g> contacts</string>
<!-- [CHAR LIMIT=40] Zen mode settings: Calls or messages option value: From anyone -->
<string name="zen_mode_from_anyone">From anyone</string>
<string name="zen_mode_from_anyone">Anyone</string>
<!-- [CHAR LIMIT=40] Zen mode settings: Calls or messages option value: From contacts only -->
<string name="zen_mode_from_contacts">From contacts only</string>
<string name="zen_mode_from_contacts">Contacts</string>
<!-- [CHAR LIMIT=40] Zen mode settings: Calls or messages option value: From starred contacts only -->
<string name="zen_mode_from_starred">From starred contacts only</string>
<string name="zen_mode_from_starred">Starred contacts</string>
<!-- [CHAR LIMIT=40] Zen mode settings: Calls and/or messages from none-->
<string name="zen_mode_from_none">None</string>
<!-- Do not disturb settings, calls summary [CHAR LIMIT=100]-->
<string name="zen_calls_summary_starred_repeat">From starred contacts and repeat callers</string>
@@ -8822,8 +8849,6 @@
<!-- Do not disturb settings, calls summary [CHAR LIMIT=100]-->
<string name="zen_calls_summary_repeat_only">From repeat callers only</string>
<!-- [CHAR LIMIT=40] Zen mode settings: Calls and/or messages from none-->
<string name="zen_mode_from_none">None</string>
<!-- [CHAR LIMIT=40] Zen mode settings: Calls option value: No calls allowed -->
<string name="zen_mode_from_none_calls">Don\u2019t allow any calls</string>
<!-- [CHAR LIMIT=40] Zen mode settings: Messages option value: No messages allowed -->
@@ -8866,6 +8891,8 @@
<!-- [CHAR LIMIT=100] Zen mode settings: Allow apps to bypass DND -->
<string name="zen_mode_bypassing_apps">Allow apps to override</string>
<!-- [CHAR LIMIT=100] Zen mode settings: Allow apps to bypass DND header -->
<string name="zen_mode_bypassing_apps_header">Apps that can interrupt</string>
<!-- [CHAR LIMIT=120] Zen mode settings: No apps are bypassing DND -->
<string name="zen_mode_bypassing_apps_subtext_none">No apps can interrupt</string>
<!-- [CHAR LIMIT=120] Zen mode settings: Allow apps to bypass DND -->
@@ -8878,6 +8905,10 @@
<string name="zen_mode_apps_bypassing_list_count"><xliff:g id="number" example="2">%d</xliff:g> more</string>
<!-- [CHAR LIMIT=100] Zen mode settings: Allow apps to bypass DND title-->
<string name="zen_mode_bypassing_apps_title">App exceptions</string>
<!-- [CHAR LIMIT=100] Zen mode settings: App that can bypass DND's secondary text describing which notification channels from the app can bypass DND-->
<string name="zen_mode_bypassing_apps_all_summary">All notifications</string>
<!-- [CHAR LIMIT=100] Zen mode settings: App that can bypass DND's secondary text describing which notification channels from the app can bypass DND-->
<string name="zen_mode_bypassing_apps_some_summary">Some notifications</string>
<!-- [CHAR LIMIT=120] Zen mode settings: Summary for sound interruption settings -->
<plurals name="zen_mode_other_sounds_summary">

View File

@@ -16,11 +16,12 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="conversation_list">
android:key="conversation_list"
android:title="zen_mode_conversations_title">
<PreferenceCategory
android:title="@string/important_conversations"
android:key="important_conversations"
android:title="@string/important_conversations"
android:visibility="gone"
settings:allowDividerAbove="false"
settings:allowDividerBelow="true" >

View File

@@ -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">
<PreferenceCategory
android:title="@string/zen_mode_settings_category"
android:key="zen_mode_settings_category_calls">
<!-- Calls -->
<ListPreference
android:key="zen_mode_calls"
android:title="@string/zen_mode_calls"
android:entries="@array/zen_mode_contacts_calls_entries"
android:entryValues="@array/zen_mode_contacts_values"/>
<Preference
android:key="zen_mode_starred_contacts_callers"
android:title="@string/zen_mode_starred_contacts_title"/>
<!-- Repeat callers -->
<SwitchPreference
android:key="zen_mode_repeat_callers"
android:title="@string/zen_mode_repeat_callers_title" />
android:key="zen_mode_settings_category_calls"
android:title="@string/zen_mode_calls_header"
settings:allowDividerBelow="true">
</PreferenceCategory>
<!-- Repeat callers -->
<SwitchPreference
android:key="zen_mode_repeat_callers"
android:title="@string/zen_mode_repeat_callers_title"
settings:allowDividerAbove="true"/>
<com.android.settingslib.widget.FooterPreference/>
</PreferenceScreen>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:key="zen_mode_conversations_settings"
android:title="@string/zen_mode_conversations_title">
<!-- Conversations -->
<PreferenceCategory
android:key="zen_mode_conversations_radio_buttons"
android:title="@string/zen_mode_conversations_section_title">
<!-- TODO: add preference with chat images here (b/151845457) -->
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -21,18 +21,8 @@
android:title="@string/zen_mode_messages_title" >
<PreferenceCategory
android:title="@string/zen_mode_settings_category"
android:key="zen_mode_settings_category_messages">
<!-- Messages -->
<ListPreference
android:key="zen_mode_messages"
android:title="@string/zen_mode_messages"
android:entries="@array/zen_mode_contacts_messages_entries"
android:entryValues="@array/zen_mode_contacts_values"/>
<Preference
android:key="zen_mode_starred_contacts_messages"
android:title="@string/zen_mode_starred_contacts_title"/>
android:key="zen_mode_settings_category_messages"
android:title="@string/zen_mode_messages_header">
</PreferenceCategory>
<com.android.settingslib.widget.FooterPreference/>

View File

@@ -20,51 +20,31 @@
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/zen_category_people" >
<!-- Conversations -->
<PreferenceCategory
android:title="@string/zen_mode_calls_title"
android:key="zen_mode_settings_category_calls">
<!-- Calls -->
<ListPreference
android:key="zen_mode_calls"
android:title="@string/zen_mode_calls"
android:entries="@array/zen_mode_contacts_calls_entries"
android:entryValues="@array/zen_mode_contacts_values"/>
android:key="zen_mode_settings_category_conversations"
android:title="@string/zen_mode_conversations_section_title">
<Preference
android:key="zen_mode_starred_contacts_callers"
android:title="@string/zen_mode_starred_contacts_title"/>
<!-- Repeat callers -->
<SwitchPreference
android:key="zen_mode_repeat_callers"
android:title="@string/zen_mode_repeat_callers_title" />
</PreferenceCategory>
<PreferenceCategory
android:title="@string/zen_mode_messages_title"
android:key="zen_mode_settings_category_messages">
<!-- Messages -->
<ListPreference
android:key="zen_mode_messages"
android:title="@string/zen_mode_messages"
android:entries="@array/zen_mode_contacts_messages_entries"
android:entryValues="@array/zen_mode_contacts_values"/>
<Preference
android:key="zen_mode_starred_contacts_messages"
android:title="@string/zen_mode_starred_contacts_title"/>
</PreferenceCategory>
<PreferenceCategory
android:title="@string/zen_mode_conversations_title"
android:key="zen_mode_settings_category_conversations">
<!-- Conversations -->
<ListPreference
android:key="zen_mode_conversations"
android:title="@string/zen_mode_conversations_title"
android:entries="@array/zen_mode_conversations_entries"
android:entryValues="@array/zen_mode_conversations_values"/>
android:fragment="com.android.settings.notification.zen.ZenModeConversationsSettings"/>
</PreferenceCategory>
<!-- Calls & Messages -->
<PreferenceCategory
android:key="zen_mode_people_calls_messages_section"
android:title="@string/zen_mode_people_calls_messages_section_title">
<Preference
android:key="zen_mode_people_calls"
android:title="@string/zen_mode_calls_title"
android:fragment="com.android.settings.notification.zen.ZenModeCallsSettings"/>
<Preference
android:key="zen_mode_people_messages"
android:title="@string/zen_mode_messages_title"
android:fragment="com.android.settings.notification.zen.ZenModeMessagesSettings"/>
</PreferenceCategory>
<!-- Footer that shows if user is put into alarms only or total silence mode by an app -->

View File

@@ -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<String> 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<String> 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<Map.Entry<String, AutomaticZenRule>> RULE_COMPARATOR =
new Comparator<Map.Entry<String, AutomaticZenRule>>() {

View File

@@ -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<AbstractPreferenceController> createPreferenceControllers(Context context) {
return buildPreferenceControllers(context, getSettingsLifecycle());
}
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
Lifecycle lifecycle) {
List<AbstractPreferenceController> 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<SearchIndexableResource> getXmlResourcesToIndex(Context context,
boolean enabled) {
final ArrayList<SearchIndexableResource> 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<AbstractPreferenceController> createPreferenceControllers(
Context context) {
return buildPreferenceControllers(context, null);
}
};
}

View File

@@ -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());
}
}
}

View File

@@ -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<AbstractPreferenceController> createPreferenceControllers(Context context) {
return buildPreferenceControllers(context, getSettingsLifecycle(), mNotificationBackend);
}
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
Lifecycle lifecycle, NotificationBackend notificationBackend) {
List<AbstractPreferenceController> 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<AbstractPreferenceController> createPreferenceControllers(
Context context) {
return buildPreferenceControllers(context, null, null);
}
};
}

View File

@@ -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<AbstractPreferenceController> createPreferenceControllers(Context context) {
return buildPreferenceControllers(context, getSettingsLifecycle());
}
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
Lifecycle lifecycle) {
List<AbstractPreferenceController> 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<SearchIndexableResource> getXmlResourcesToIndex(Context context,
boolean enabled) {
final ArrayList<SearchIndexableResource> 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<AbstractPreferenceController> createPreferenceControllers(
Context context) {
return buildPreferenceControllers(context, null);
}
};
}

View File

@@ -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<AbstractPreferenceController> buildPreferenceControllers(Context context,
Lifecycle lifecycle, Application app, Fragment host, FragmentManager fragmentManager) {
List<AbstractPreferenceController> 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;

View File

@@ -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<RadioButtonPreference> 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<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... unused) {
ParceledListSlice<ConversationChannelWrapper> allConversations =
mNotificationBackend.getConversations(false);
if (allConversations != null) {
mNumConversations = allConversations.getList().size();
}
ParceledListSlice<ConversationChannelWrapper> 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);
}
}
};
}

View File

@@ -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;
}
}

View File

@@ -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<RadioButtonPreferenceWithExtraWidget> 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;
}
}

View File

@@ -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;
}
}

View File

@@ -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<RadioButtonPreference> 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<RadioButtonPreference> 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;
}
}

View File

@@ -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)]);
}
}

View File

@@ -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<RadioButtonPreference> 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<RadioButtonPreference> 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;
}
}

View File

@@ -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);
}
}