From 7c5ac8fdaca18b6ce90c6d5f54309dcc1af72c89 Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Thu, 30 Jan 2020 08:29:39 -0500 Subject: [PATCH] Support new conversation DND options Test: atest Bug: 137397357 Change-Id: I52420ffdc4b6618e66354a9c1bb99b0296bc4ea4 --- res/values/arrays.xml | 13 ++ res/values/strings.xml | 3 + res/xml/zen_mode_people_settings.xml | 7 + ...singConversationsPreferenceController.java | 210 ------------------ .../notification/zen/ZenModeBackend.java | 74 ++++-- .../zen/ZenModeCallsPreferenceController.java | 2 +- .../ZenModeMessagesPreferenceController.java | 2 +- .../ZenModePeoplePreferenceController.java | 2 +- .../zen/ZenModePeopleSettings.java | 3 +- ...ModePriorityCallsPreferenceController.java | 2 +- ...rityConversationsPreferenceController.java | 104 +++++++++ ...ePriorityMessagesPreferenceController.java | 2 +- .../notification/zen/ZenModeBackendTest.java | 201 ++++++++++++----- ...PriorityCallsPreferenceControllerTest.java | 4 +- ...ConversationsPreferenceControllerTest.java | 191 ++++++++++++++++ ...orityMessagesPreferenceControllerTest.java | 4 +- 16 files changed, 530 insertions(+), 294 deletions(-) delete mode 100644 src/com/android/settings/notification/zen/ZenModeAllBypassingConversationsPreferenceController.java create mode 100644 src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceControllerTest.java diff --git a/res/values/arrays.xml b/res/values/arrays.xml index 9c3a622df00..bfffce093ec 100644 --- a/res/values/arrays.xml +++ b/res/values/arrays.xml @@ -1175,6 +1175,19 @@ zen_mode_from_none + + @string/zen_mode_from_all_conversations + @string/zen_mode_from_important_conversations + @string/zen_mode_from_no_conversations + + + + + 1 + 2 + 3 + + @string/swipe_direction_rtl diff --git a/res/values/strings.xml b/res/values/strings.xml index e5e55c6c4f5..b3b9d42149c 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -8637,6 +8637,9 @@ Conversations + From all conversations + From important conversations + Don\u2019t allow any conversations Allow messages diff --git a/res/xml/zen_mode_people_settings.xml b/res/xml/zen_mode_people_settings.xml index 5456f6f45b4..140d1cde8d7 100644 --- a/res/xml/zen_mode_people_settings.xml +++ b/res/xml/zen_mode_people_settings.xml @@ -59,6 +59,13 @@ + + + diff --git a/src/com/android/settings/notification/zen/ZenModeAllBypassingConversationsPreferenceController.java b/src/com/android/settings/notification/zen/ZenModeAllBypassingConversationsPreferenceController.java deleted file mode 100644 index 309cd428a2f..00000000000 --- a/src/com/android/settings/notification/zen/ZenModeAllBypassingConversationsPreferenceController.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * 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.Application; -import android.app.NotificationChannel; -import android.app.settings.SettingsEnums; -import android.content.Context; -import android.os.Bundle; -import android.provider.Settings; -import android.text.TextUtils; - -import androidx.annotation.VisibleForTesting; -import androidx.core.text.BidiFormatter; -import androidx.fragment.app.Fragment; -import androidx.preference.Preference; -import androidx.preference.PreferenceCategory; -import androidx.preference.PreferenceScreen; - -import com.android.settings.R; -import com.android.settings.applications.AppInfoBase; -import com.android.settings.core.PreferenceControllerMixin; -import com.android.settings.core.SubSettingLauncher; -import com.android.settings.notification.NotificationBackend; -import com.android.settings.notification.app.ChannelNotificationSettings; -import com.android.settingslib.applications.ApplicationsState; -import com.android.settingslib.core.AbstractPreferenceController; -import com.android.settingslib.widget.apppreference.AppPreference; - -import java.util.ArrayList; -import java.util.List; - -/** - * Adds a preference to the PreferenceScreen for each conversation notification channel that can - * bypass DND. - */ -public class ZenModeAllBypassingConversationsPreferenceController extends - AbstractPreferenceController implements PreferenceControllerMixin { - - private final String KEY = "zen_mode_settings_category_conversations"; - - @VisibleForTesting ApplicationsState mApplicationsState; - @VisibleForTesting PreferenceCategory mCategory; - @VisibleForTesting Context mPrefContext; - - private ApplicationsState.Session mAppSession; - private NotificationBackend mNotificationBackend = new NotificationBackend(); - private Fragment mHostFragment; - - public ZenModeAllBypassingConversationsPreferenceController(Context context, Application app, - Fragment host) { - - this(context, app == null ? null : ApplicationsState.getInstance(app), host); - } - - private ZenModeAllBypassingConversationsPreferenceController(Context context, - ApplicationsState appState, Fragment host) { - super(context); - mApplicationsState = appState; - mHostFragment = host; - - if (mApplicationsState != null && host != null) { - mAppSession = mApplicationsState.newSession(mAppSessionCallbacks, host.getLifecycle()); - } - } - - @Override - public void displayPreference(PreferenceScreen screen) { - mCategory = screen.findPreference(KEY); - mPrefContext = screen.getContext(); - updateNotificationChannelList(); - super.displayPreference(screen); - } - - @Override - public boolean isAvailable() { - return true; - } - - @Override - public String getPreferenceKey() { - return KEY; - } - - /** - * Call this method to trigger the notification channels list to refresh. - */ - public void updateNotificationChannelList() { - if (mAppSession == null) { - return; - } - - ApplicationsState.AppFilter filter = ApplicationsState.FILTER_ALL_ENABLED; - List apps = mAppSession.rebuild(filter, - ApplicationsState.ALPHA_COMPARATOR); - if (apps != null) { - updateNotificationChannelList(apps); - } - } - - @VisibleForTesting - void updateNotificationChannelList(List apps) { - if (mCategory == null || apps == null) { - return; - } - - List channelsBypassingDnd = new ArrayList<>(); - for (ApplicationsState.AppEntry entry : apps) { - String pkg = entry.info.packageName; - mApplicationsState.ensureIcon(entry); - for (NotificationChannel channel : mNotificationBackend - .getNotificationChannelsBypassingDnd(pkg, entry.info.uid).getList()) { - if (TextUtils.isEmpty(channel.getConversationId())) { - // only conversation channels - continue; - } - Preference pref = new AppPreference(mPrefContext); - pref.setKey(pkg + "|" + channel.getId()); - pref.setTitle(BidiFormatter.getInstance().unicodeWrap(entry.label)); - // TODO: use badged shortcut icon instead of app icon - pref.setIcon(entry.icon); - pref.setSummary(BidiFormatter.getInstance().unicodeWrap(channel.getName())); - - pref.setOnPreferenceClickListener(preference -> { - Bundle args = new Bundle(); - args.putString(AppInfoBase.ARG_PACKAGE_NAME, entry.info.packageName); - args.putInt(AppInfoBase.ARG_PACKAGE_UID, entry.info.uid); - args.putString(Settings.EXTRA_CHANNEL_ID, channel.getId()); - new SubSettingLauncher(mContext) - .setDestination(ChannelNotificationSettings.class.getName()) - .setArguments(args) - .setTitleRes(R.string.notification_channel_title) - .setResultListener(mHostFragment, 0) - .setSourceMetricsCategory( - SettingsEnums.NOTIFICATION_ZEN_MODE_OVERRIDING_APP) - .launch(); - return true; - }); - channelsBypassingDnd.add(pref); - } - - mCategory.removeAll(); - if (channelsBypassingDnd.size() > 0) { - mCategory.setVisible(true); - for (Preference prefToAdd : channelsBypassingDnd) { - mCategory.addPreference(prefToAdd); - } - } else { - mCategory.setVisible(false); - } - } - } - - private final ApplicationsState.Callbacks mAppSessionCallbacks = - new ApplicationsState.Callbacks() { - - @Override - public void onRunningStateChanged(boolean running) { - updateNotificationChannelList(); - } - - @Override - public void onPackageListChanged() { - updateNotificationChannelList(); - } - - @Override - public void onRebuildComplete(ArrayList apps) { - updateNotificationChannelList(apps); - } - - @Override - public void onPackageIconChanged() { - updateNotificationChannelList(); - } - - @Override - public void onPackageSizeChanged(String packageName) { - updateNotificationChannelList(); - } - - @Override - public void onAllSizesComputed() { } - - @Override - public void onLauncherInfoChanged() { - updateNotificationChannelList(); - } - - @Override - public void onLoadEntriesCompleted() { - // Add shortcut info - updateNotificationChannelList(); - } - }; -} diff --git a/src/com/android/settings/notification/zen/ZenModeBackend.java b/src/com/android/settings/notification/zen/ZenModeBackend.java index ac494668095..836f4358e84 100644 --- a/src/com/android/settings/notification/zen/ZenModeBackend.java +++ b/src/com/android/settings/notification/zen/ZenModeBackend.java @@ -16,8 +16,12 @@ 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; +import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_NONE; import android.app.ActivityManager; import android.app.AutomaticZenRule; @@ -147,25 +151,35 @@ public class ZenModeBackend { return SOURCE_NONE; } + protected int getPriorityConversationSenders() { + if (isPriorityCategoryEnabled(PRIORITY_CATEGORY_CONVERSATIONS)) { + return mPolicy.priorityConversationSenders; + } + return CONVERSATION_SENDERS_NONE; + } + protected void saveVisualEffectsPolicy(int category, boolean suppress) { Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.ZEN_SETTINGS_UPDATED, 1); int suppressedEffects = getNewSuppressedEffects(suppress, category); savePolicy(mPolicy.priorityCategories, mPolicy.priorityCallSenders, - mPolicy.priorityMessageSenders, suppressedEffects); + mPolicy.priorityMessageSenders, suppressedEffects, + mPolicy.priorityConversationSenders); } protected void saveSoundPolicy(int category, boolean allow) { int priorityCategories = getNewDefaultPriorityCategories(allow, category); savePolicy(priorityCategories, mPolicy.priorityCallSenders, - mPolicy.priorityMessageSenders, mPolicy.suppressedVisualEffects); + mPolicy.priorityMessageSenders, mPolicy.suppressedVisualEffects, + mPolicy.priorityConversationSenders); } protected void savePolicy(int priorityCategories, int priorityCallSenders, - int priorityMessageSenders, int suppressedVisualEffects) { + int priorityMessageSenders, int suppressedVisualEffects, + int priorityConversationSenders) { mPolicy = new NotificationManager.Policy(priorityCategories, priorityCallSenders, - priorityMessageSenders, suppressedVisualEffects); + priorityMessageSenders, suppressedVisualEffects, priorityConversationSenders); mNotificationManager.setNotificationPolicy(mPolicy); } @@ -210,23 +224,21 @@ public class ZenModeBackend { } savePolicy(getNewDefaultPriorityCategories(allowSenders, category), - priorityCallSenders, priorityMessagesSenders, mPolicy.suppressedVisualEffects); + priorityCallSenders, priorityMessagesSenders, mPolicy.suppressedVisualEffects, + mPolicy.priorityConversationSenders); if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allow" + stringCategory + "=" + allowSenders + " allow" + stringCategory + "From=" + ZenModeConfig.sourceToString(allowSendersFrom)); } - protected String getSendersKey(int category) { - switch (getZenMode()) { - case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS: - case Settings.Global.ZEN_MODE_ALARMS: - return getKeyFromSetting(SOURCE_NONE); - default: - int prioritySenders = getPrioritySenders(category); - return getKeyFromSetting(isPriorityCategoryEnabled(category) - ? prioritySenders : SOURCE_NONE); - } + protected void saveConversationSenders(int val) { + final boolean allowSenders = val != CONVERSATION_SENDERS_NONE; + + savePolicy(getNewDefaultPriorityCategories(allowSenders, PRIORITY_CATEGORY_CONVERSATIONS), + mPolicy.priorityCallSenders, mPolicy.priorityMessageSenders, + mPolicy.suppressedVisualEffects, val); + } private int getPrioritySenders(int category) { @@ -240,6 +252,10 @@ public class ZenModeBackend { return getPriorityMessageSenders(); } + if (category == NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS) { + return getPriorityConversationSenders(); + } + return categorySenders; } @@ -271,11 +287,13 @@ public class ZenModeBackend { } } - protected int getAlarmsTotalSilenceCallsMessagesSummary(int category) { + protected int getAlarmsTotalSilencePeopleSummary(int category) { if (category == NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES) { return R.string.zen_mode_from_none_messages; } else if (category == NotificationManager.Policy.PRIORITY_CATEGORY_CALLS){ return R.string.zen_mode_from_none_calls; + } else if (category == NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS) { + return R.string.zen_mode_from_no_conversations; } return R.string.zen_mode_from_none; } @@ -309,6 +327,21 @@ public class ZenModeBackend { } } + protected int getConversationSummary() { + int conversationType = getPriorityConversationSenders(); + + switch (conversationType) { + case NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE: + return R.string.zen_mode_from_all_conversations; + case NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT: + return R.string.zen_mode_from_important_conversations; + case NotificationManager.Policy.CONVERSATION_SENDERS_NONE: + return R.string.zen_mode_from_no_conversations; + default: + return R.string.zen_mode_from_no_conversations; + } + } + protected int getContactsCallsSummary(ZenPolicy policy) { int peopleType = policy.getPriorityCallSenders(); switch (peopleType) { @@ -398,12 +431,21 @@ public class ZenModeBackend { messages = ZenPolicy.PEOPLE_TYPE_NONE; } + int conversations; + if (mPolicy.allowConversations()) { + // unlike the above, no mapping is needed because the values are the same + conversations = mPolicy.allowConversationsFrom(); + } else { + conversations = CONVERSATION_SENDERS_NONE; + } + return new ZenPolicy.Builder(zenPolicy) .allowAlarms(mPolicy.allowAlarms()) .allowCalls(calls) .allowEvents(mPolicy.allowEvents()) .allowMedia(mPolicy.allowMedia()) .allowMessages(messages) + .allowConversations(conversations) .allowReminders(mPolicy.allowReminders()) .allowRepeatCallers(mPolicy.allowRepeatCallers()) .allowSystem(mPolicy.allowSystem()) diff --git a/src/com/android/settings/notification/zen/ZenModeCallsPreferenceController.java b/src/com/android/settings/notification/zen/ZenModeCallsPreferenceController.java index 7b97fb1d600..0930db241aa 100644 --- a/src/com/android/settings/notification/zen/ZenModeCallsPreferenceController.java +++ b/src/com/android/settings/notification/zen/ZenModeCallsPreferenceController.java @@ -56,7 +56,7 @@ public class ZenModeCallsPreferenceController extends case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS: case Settings.Global.ZEN_MODE_ALARMS: preference.setEnabled(false); - preference.setSummary(mBackend.getAlarmsTotalSilenceCallsMessagesSummary( + preference.setSummary(mBackend.getAlarmsTotalSilencePeopleSummary( NotificationManager.Policy.PRIORITY_CATEGORY_CALLS)); break; default: diff --git a/src/com/android/settings/notification/zen/ZenModeMessagesPreferenceController.java b/src/com/android/settings/notification/zen/ZenModeMessagesPreferenceController.java index ba91f560dcc..de169ed895b 100644 --- a/src/com/android/settings/notification/zen/ZenModeMessagesPreferenceController.java +++ b/src/com/android/settings/notification/zen/ZenModeMessagesPreferenceController.java @@ -55,7 +55,7 @@ public class ZenModeMessagesPreferenceController extends case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS: case Settings.Global.ZEN_MODE_ALARMS: preference.setEnabled(false); - preference.setSummary(mBackend.getAlarmsTotalSilenceCallsMessagesSummary( + preference.setSummary(mBackend.getAlarmsTotalSilencePeopleSummary( NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)); break; default: diff --git a/src/com/android/settings/notification/zen/ZenModePeoplePreferenceController.java b/src/com/android/settings/notification/zen/ZenModePeoplePreferenceController.java index a06f023deb6..a48c93d5d6b 100644 --- a/src/com/android/settings/notification/zen/ZenModePeoplePreferenceController.java +++ b/src/com/android/settings/notification/zen/ZenModePeoplePreferenceController.java @@ -55,7 +55,7 @@ public class ZenModePeoplePreferenceController extends case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS: case Settings.Global.ZEN_MODE_ALARMS: preference.setEnabled(false); - preference.setSummary(mBackend.getAlarmsTotalSilenceCallsMessagesSummary( + preference.setSummary(mBackend.getAlarmsTotalSilencePeopleSummary( NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)); break; default: diff --git a/src/com/android/settings/notification/zen/ZenModePeopleSettings.java b/src/com/android/settings/notification/zen/ZenModePeopleSettings.java index af3c26bf6f8..ff768dbd4ed 100644 --- a/src/com/android/settings/notification/zen/ZenModePeopleSettings.java +++ b/src/com/android/settings/notification/zen/ZenModePeopleSettings.java @@ -65,8 +65,7 @@ public class ZenModePeopleSettings extends ZenModeSettingsBase implements Indexa controllers.add(new ZenModeRepeatCallersPreferenceController(context, lifecycle, context.getResources().getInteger(com.android.internal.R.integer .config_zen_repeat_callers_threshold))); - controllers.add( - new ZenModeAllBypassingConversationsPreferenceController(context, app, host)); + controllers.add(new ZenModePriorityConversationsPreferenceController(context, lifecycle)); controllers.add(new ZenModeSettingsFooterPreferenceController(context, lifecycle, fragmentManager)); return controllers; diff --git a/src/com/android/settings/notification/zen/ZenModePriorityCallsPreferenceController.java b/src/com/android/settings/notification/zen/ZenModePriorityCallsPreferenceController.java index 780cf840b1b..6b538dc2c93 100644 --- a/src/com/android/settings/notification/zen/ZenModePriorityCallsPreferenceController.java +++ b/src/com/android/settings/notification/zen/ZenModePriorityCallsPreferenceController.java @@ -80,7 +80,7 @@ public class ZenModePriorityCallsPreferenceController extends AbstractZenModePre case Settings.Global.ZEN_MODE_ALARMS: mPreference.setEnabled(false); mPreference.setValue(ZenModeBackend.ZEN_MODE_FROM_NONE); - mPreference.setSummary(mBackend.getAlarmsTotalSilenceCallsMessagesSummary( + mPreference.setSummary(mBackend.getAlarmsTotalSilencePeopleSummary( NotificationManager.Policy.PRIORITY_CATEGORY_CALLS)); break; default: diff --git a/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java b/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java new file mode 100644 index 00000000000..afd17ad71ff --- /dev/null +++ b/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java @@ -0,0 +1,104 @@ +/* + * 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.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 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 ZenModePriorityConversationsPreferenceController + extends AbstractZenModePreferenceController + implements Preference.OnPreferenceChangeListener { + + protected static final String KEY = "zen_mode_conversations"; + private final ZenModeBackend mBackend; + private ListPreference mPreference; + + public ZenModePriorityConversationsPreferenceController(Context context, 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); + updateValue(preference); + } + + @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; + } + } + } +} diff --git a/src/com/android/settings/notification/zen/ZenModePriorityMessagesPreferenceController.java b/src/com/android/settings/notification/zen/ZenModePriorityMessagesPreferenceController.java index f54179e7575..6476c634b84 100644 --- a/src/com/android/settings/notification/zen/ZenModePriorityMessagesPreferenceController.java +++ b/src/com/android/settings/notification/zen/ZenModePriorityMessagesPreferenceController.java @@ -80,7 +80,7 @@ public class ZenModePriorityMessagesPreferenceController extends AbstractZenMode case Settings.Global.ZEN_MODE_ALARMS: mPreference.setEnabled(false); mPreference.setValue(ZenModeBackend.ZEN_MODE_FROM_NONE); - mPreference.setSummary(mBackend.getAlarmsTotalSilenceCallsMessagesSummary( + mPreference.setSummary(mBackend.getAlarmsTotalSilencePeopleSummary( NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)); break; default: diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModeBackendTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModeBackendTest.java index c4ece5ad0c7..247d68e4bfe 100644 --- a/tests/robotests/src/com/android/settings/notification/zen/ZenModeBackendTest.java +++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModeBackendTest.java @@ -1,25 +1,41 @@ 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_ALARMS; +import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS; +import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS; +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 android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT; + import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertEquals; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.AutomaticZenRule; import android.app.NotificationManager; +import android.app.NotificationManager.Policy; import android.content.Context; import android.database.Cursor; import android.provider.Settings; import android.service.notification.ZenModeConfig; -import com.android.settings.notification.zen.ZenModeBackend; +import com.android.settings.R; 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.mockito.invocation.InvocationOnMock; @@ -55,60 +71,6 @@ public class ZenModeBackendTest { mBackend = new ZenModeBackend(mContext); } - @Test - public void updateState_checkRuleOrderingDescending() { - final int NUM_RULES = 4; - Map.Entry[] rules = populateAutoZenRulesDescendingCreationTime( - NUM_RULES, false); - Arrays.sort(rules, ZenModeBackend.RULE_COMPARATOR); - - // check ordering, most recent should be at the end - for (int i = 0; i < NUM_RULES; i++) { - assertEquals(GENERIC_RULE_NAME + (NUM_RULES - 1 - i), rules[i].getKey()); - } - } - - @Test - public void updateState_checkRuleOrderingAscending() { - final int NUM_RULES = 4; - Map.Entry[] rules = populateAutoZenRulesAscendingCreationTime( - NUM_RULES, false); - Arrays.sort(rules, ZenModeBackend.RULE_COMPARATOR); - - // check ordering, most recent should be at the end - for (int i = 0; i < NUM_RULES; i++) { - assertEquals(GENERIC_RULE_NAME + i, rules[i].getKey()); - } - } - - @Test - public void updateState_checkRuleOrderingDescending_withDefaultRules() { - final int NUM_RULES = 4; - - Map.Entry[] rules = populateAutoZenRulesDescendingCreationTime(NUM_RULES, - true); - Arrays.sort(rules, ZenModeBackend.RULE_COMPARATOR); - - assertEquals(rules[0].getKey(), DEFAULT_ID_1); - assertEquals(rules[1].getKey(), DEFAULT_ID_2); - // NON-DEFAULT RULES check ordering, most recent at the bottom/end - for (int i = 0; i < NUM_RULES; i++) { - assertEquals(GENERIC_RULE_NAME + (NUM_RULES - 1 - i), rules[i + 2].getKey()); - } - } - - @Test - public void updateSummary_nullCursorValues() { - Cursor testCursorWithNullValues = createMockCursor(3); - when(testCursorWithNullValues.getString(0)).thenReturn(null); - - // expected - no null values - List contacts = mBackend.getStarredContacts(testCursorWithNullValues); - for (String contact : contacts) { - assertThat(contact).isNotNull(); - } - } - private Cursor createMockCursor(int size) { Cursor mockCursor = mock(Cursor.class); when(mockCursor.moveToFirst()).thenReturn(true); @@ -173,4 +135,133 @@ public class ZenModeBackendTest { ruleMap.entrySet().toArray(toReturn); return toReturn; } + + @Test + public void updateState_checkRuleOrderingDescending() { + final int NUM_RULES = 4; + Map.Entry[] rules = populateAutoZenRulesDescendingCreationTime( + NUM_RULES, false); + Arrays.sort(rules, ZenModeBackend.RULE_COMPARATOR); + + // check ordering, most recent should be at the end + for (int i = 0; i < NUM_RULES; i++) { + assertEquals(GENERIC_RULE_NAME + (NUM_RULES - 1 - i), rules[i].getKey()); + } + } + + @Test + public void updateState_checkRuleOrderingAscending() { + final int NUM_RULES = 4; + Map.Entry[] rules = populateAutoZenRulesAscendingCreationTime( + NUM_RULES, false); + Arrays.sort(rules, ZenModeBackend.RULE_COMPARATOR); + + // check ordering, most recent should be at the end + for (int i = 0; i < NUM_RULES; i++) { + assertEquals(GENERIC_RULE_NAME + i, rules[i].getKey()); + } + } + + @Test + public void updateState_checkRuleOrderingDescending_withDefaultRules() { + final int NUM_RULES = 4; + + Map.Entry[] rules = populateAutoZenRulesDescendingCreationTime(NUM_RULES, + true); + Arrays.sort(rules, ZenModeBackend.RULE_COMPARATOR); + + assertEquals(rules[0].getKey(), DEFAULT_ID_1); + assertEquals(rules[1].getKey(), DEFAULT_ID_2); + // NON-DEFAULT RULES check ordering, most recent at the bottom/end + for (int i = 0; i < NUM_RULES; i++) { + assertEquals(GENERIC_RULE_NAME + (NUM_RULES - 1 - i), rules[i + 2].getKey()); + } + } + + @Test + public void updateSummary_nullCursorValues() { + Cursor testCursorWithNullValues = createMockCursor(3); + when(testCursorWithNullValues.getString(0)).thenReturn(null); + + // expected - no null values + List contacts = mBackend.getStarredContacts(testCursorWithNullValues); + for (String contact : contacts) { + assertThat(contact).isNotNull(); + } + } + + @Test + public void saveConversationSenders_importantToNone() { + when(mNotificationManager.getNotificationPolicy()).thenReturn( + new Policy(PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_CONVERSATIONS + | PRIORITY_CATEGORY_MESSAGES | PRIORITY_CATEGORY_ALARMS, + PRIORITY_SENDERS_CONTACTS, + PRIORITY_SENDERS_STARRED, + SUPPRESSED_EFFECT_AMBIENT, + CONVERSATION_SENDERS_IMPORTANT)); + mBackend = new ZenModeBackend(mContext); + + mBackend.saveConversationSenders(CONVERSATION_SENDERS_NONE); + + ArgumentCaptor captor = ArgumentCaptor.forClass(Policy.class); + verify(mNotificationManager, times(1)).setNotificationPolicy(captor.capture()); + + Policy expected = new Policy( + PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_MESSAGES | PRIORITY_CATEGORY_ALARMS, + PRIORITY_SENDERS_CONTACTS, + PRIORITY_SENDERS_STARRED, + SUPPRESSED_EFFECT_AMBIENT, + CONVERSATION_SENDERS_NONE); + assertEquals(expected, captor.getValue()); + } + + @Test + public void saveConversationSenders_noneToAll() { + when(mNotificationManager.getNotificationPolicy()).thenReturn(new Policy( + PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_MESSAGES | PRIORITY_CATEGORY_ALARMS, + PRIORITY_SENDERS_CONTACTS, + PRIORITY_SENDERS_STARRED, + SUPPRESSED_EFFECT_AMBIENT, + CONVERSATION_SENDERS_NONE)); + mBackend = new ZenModeBackend(mContext); + + mBackend.saveConversationSenders(CONVERSATION_SENDERS_ANYONE); + + ArgumentCaptor captor = ArgumentCaptor.forClass(Policy.class); + verify(mNotificationManager, times(1)).setNotificationPolicy(captor.capture()); + + Policy expected = new Policy(PRIORITY_CATEGORY_CONVERSATIONS + | PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_MESSAGES | PRIORITY_CATEGORY_ALARMS, + PRIORITY_SENDERS_CONTACTS, + PRIORITY_SENDERS_STARRED, + SUPPRESSED_EFFECT_AMBIENT, + CONVERSATION_SENDERS_ANYONE); + assertEquals(expected, captor.getValue()); + } + + @Test + public void saveSenders_doesNotChangeConversations() { + when(mNotificationManager.getNotificationPolicy()).thenReturn( + new Policy(PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_CONVERSATIONS + | PRIORITY_CATEGORY_MESSAGES | PRIORITY_CATEGORY_ALARMS, + PRIORITY_SENDERS_CONTACTS, + PRIORITY_SENDERS_STARRED, + SUPPRESSED_EFFECT_AMBIENT, + CONVERSATION_SENDERS_ANYONE)); + mBackend = new ZenModeBackend(mContext); + + mBackend.saveSenders(PRIORITY_CATEGORY_CALLS, PRIORITY_SENDERS_ANY); + + ArgumentCaptor captor = ArgumentCaptor.forClass(Policy.class); + verify(mNotificationManager, times(1)).setNotificationPolicy(captor.capture()); + + Policy expected = new Policy(PRIORITY_CATEGORY_CONVERSATIONS + | PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_MESSAGES | PRIORITY_CATEGORY_ALARMS, + PRIORITY_SENDERS_ANY, + PRIORITY_SENDERS_STARRED, + SUPPRESSED_EFFECT_AMBIENT, + CONVERSATION_SENDERS_ANYONE); + assertEquals(expected, captor.getValue()); + } + } diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityCallsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityCallsPreferenceControllerTest.java index e4490d53a99..d1f80b8fc3d 100644 --- a/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityCallsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityCallsPreferenceControllerTest.java @@ -34,8 +34,6 @@ import androidx.preference.ListPreference; import androidx.preference.PreferenceScreen; import com.android.settings.R; -import com.android.settings.notification.zen.ZenModeBackend; -import com.android.settings.notification.zen.ZenModePriorityCallsPreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; import org.junit.Before; @@ -88,7 +86,7 @@ public class ZenModePriorityCallsPreferenceControllerTest { when(mBackend.getPriorityCallSenders()) .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_STARRED); - when(mBackend.getAlarmsTotalSilenceCallsMessagesSummary( + when(mBackend.getAlarmsTotalSilencePeopleSummary( NotificationManager.Policy.PRIORITY_CATEGORY_CALLS)).thenCallRealMethod(); when(mBackend.getContactsSummary(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS)) .thenCallRealMethod(); diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceControllerTest.java new file mode 100644 index 00000000000..1583b9106ca --- /dev/null +++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceControllerTest.java @@ -0,0 +1,191 @@ +/* + * 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.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 org.mockito.Mockito.mock; +import static org.mockito.Mockito.reset; +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 ZenModePriorityConversationsPreferenceControllerTest { + + private ZenModePriorityConversationsPreferenceController 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; + + @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); + + 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(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); + } + + @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_no_conversations); + } + + @Test + public void updateState_Priority_important() { + Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS); + when(mBackend.isPriorityCategoryEnabled(PRIORITY_CATEGORY_CONVERSATIONS)).thenReturn(true); + + 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)); + } + + @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); + + + 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)); + } + + @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(); + } +} \ 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 index 3ecd22acef3..7af2211b05e 100644 --- a/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityMessagesPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityMessagesPreferenceControllerTest.java @@ -34,8 +34,6 @@ import androidx.preference.ListPreference; import androidx.preference.PreferenceScreen; import com.android.settings.R; -import com.android.settings.notification.zen.ZenModeBackend; -import com.android.settings.notification.zen.ZenModePriorityMessagesPreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; import org.junit.Before; @@ -88,7 +86,7 @@ public class ZenModePriorityMessagesPreferenceControllerTest { when(mBackend.getPriorityMessageSenders()) .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_STARRED); - when(mBackend.getAlarmsTotalSilenceCallsMessagesSummary( + when(mBackend.getAlarmsTotalSilencePeopleSummary( NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)).thenCallRealMethod(); when(mBackend.getContactsSummary(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)) .thenCallRealMethod();