Merge "Visual updates for DND screens"

This commit is contained in:
TreeHugger Robot
2020-01-11 20:09:26 +00:00
committed by Android (Google) Code Review
18 changed files with 545 additions and 214 deletions

View File

@@ -19,8 +19,24 @@
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingVertical="@dimen/zen_mode_button_padding_vertical"> android:paddingVertical="@dimen/zen_mode_button_padding_vertical">
<TextView
android:text="@string/zen_mode_settings_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/screen_margin_sides"
android:textAppearance="@android:style/TextAppearance.DeviceDefault.Large"/>
<TextView
android:text="@string/zen_mode_settings_summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/screen_margin_sides"
android:paddingTop="@dimen/zen_mode_button_padding_vertical"
android:paddingBottom="@dimen/zen_mode_button_padding_vertical"/>
<Button <Button
android:id="@+id/zen_mode_settings_turn_on_button" android:id="@+id/zen_mode_settings_turn_on_button"
style="@style/ActionPrimaryButton" style="@style/ActionPrimaryButton"
@@ -29,6 +45,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="left" android:layout_gravity="left"
android:gravity="center"
android:paddingTop="@dimen/zen_mode_button_padding_vertical"
android:text="@string/zen_mode_button_turn_on"/> android:text="@string/zen_mode_button_turn_on"/>
<Button <Button
@@ -39,6 +57,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="left" android:layout_gravity="left"
android:gravity="center"
android:paddingTop="@dimen/zen_mode_button_padding_vertical"
android:text="@string/zen_mode_button_turn_off" /> android:text="@string/zen_mode_button_turn_off" />
</LinearLayout> </LinearLayout>

View File

@@ -7605,6 +7605,9 @@
<!-- Sound: Title for the Do not Disturb option and associated settings page. [CHAR LIMIT=50]--> <!-- Sound: Title for the Do not Disturb option and associated settings page. [CHAR LIMIT=50]-->
<string name="zen_mode_settings_title">Do Not Disturb</string> <string name="zen_mode_settings_title">Do Not Disturb</string>
<!-- Sound: Summary for the Do not Disturb option and associated settings page. [CHAR LIMIT=240]-->
<string name="zen_mode_settings_summary">Only get notified by important people and apps</string>
<!-- Subtitle for the Do not Disturb slice. [CHAR LIMIT=50]--> <!-- Subtitle for the Do not Disturb slice. [CHAR LIMIT=50]-->
<string name="zen_mode_slice_subtitle">Limit interruptions</string> <string name="zen_mode_slice_subtitle">Limit interruptions</string>
@@ -7684,7 +7687,7 @@
<string name="zen_mode_visual_signals_settings_subtitle">Allow visual signals</string> <string name="zen_mode_visual_signals_settings_subtitle">Allow visual signals</string>
<!-- Do not disturb: zen settings screens category title [CHAR LIMIT=100] --> <!-- Do not disturb: zen settings screens category title [CHAR LIMIT=100] -->
<string name="zen_mode_settings_category">When Do Not Disturb is on</string> <string name="zen_mode_settings_category">Allow interruptions that make sound</string>
<!-- Do not disturb: restrict notifications title [CHAR LIMIT=80] --> <!-- Do not disturb: restrict notifications title [CHAR LIMIT=80] -->
<string name="zen_mode_restrict_notifications_title">Restrict notifications</string> <string name="zen_mode_restrict_notifications_title">Restrict notifications</string>
@@ -7825,15 +7828,19 @@
<item quantity="other"><xliff:g id="on_count" example="3">%d</xliff:g> schedules can turn on automatically</item> <item quantity="other"><xliff:g id="on_count" example="3">%d</xliff:g> schedules can turn on automatically</item>
</plurals> </plurals>
<!-- Do not disturb settings, category header [CHAR LIMIT=120]--> <!-- Do not disturb settings, main screen, category header [CHAR LIMIT=120]-->
<string name="zen_category_behavior">Mute device but allow exceptions</string> <string name="zen_category_behavior">Exceptions when Do Not Disturb is on</string>
<!-- Do not disturb settings, exceptions to dnd title [CHAR LIMIT=100]--> <!-- Do not disturb settings, main screen, field, dnd breakthrough [CHAR LIMIT=100]-->
<string name="zen_category_exceptions">Exceptions</string> <string name="zen_category_people">People</string>
<!-- Do not disturb settings, category header [CHAR LIMIT=100]--> <!-- Do not disturb settings, main screen, field, dnd breakthrough [CHAR LIMIT=100]-->
<string name="zen_category_schedule">Schedule</string> <string name="zen_category_apps">Apps</string>
<!-- Do not disturb settings, main screen, field, dnd breakthrough [CHAR LIMIT=100]-->
<string name="zen_category_exceptions">Alarms &amp; other interruptions</string>
<!-- Do not disturb settings, main screen, field, schedules [CHAR LIMIT=100]-->
<string name="zen_category_schedule">Schedules</string>
<!-- Do not disturb settings, main screen, field, dnd visuals [CHAR LIMIT=100]-->
<string name="zen_category_visuals">Silenced notifications</string>
<!-- Do not disturb settings, sound and vibrations exceptions title [CHAR LIMIT=100]-->
<string name="zen_sound_title">See all exceptions</string>
<!-- Do not disturb settings, sound and vibrations screen footer [CHAR LIMIT=NONE]--> <!-- Do not disturb settings, sound and vibrations screen footer [CHAR LIMIT=NONE]-->
<string name="zen_sound_footer">When Do Not Disturb is on, sound and vibration will be muted, except for the items you allow above.</string> <string name="zen_sound_footer">When Do Not Disturb is on, sound and vibration will be muted, except for the items you allow above.</string>
<!-- Do not disturb settings, sound and vibrations screen category [CHAR LIMIT=100]--> <!-- Do not disturb settings, sound and vibrations screen category [CHAR LIMIT=100]-->
@@ -8596,6 +8603,8 @@
<item quantity="other"><xliff:g id="num_people" example="3">%d</xliff:g> others</item> <item quantity="other"><xliff:g id="num_people" example="3">%d</xliff:g> others</item>
</plurals> </plurals>
<string name="zen_mode_conversations_title">Conversations</string>
<!-- [CHAR LIMIT=40] Zen mode settings: Messages option --> <!-- [CHAR LIMIT=40] Zen mode settings: Messages option -->
<string name="zen_mode_messages">Allow messages</string> <string name="zen_mode_messages">Allow messages</string>
@@ -8636,31 +8645,46 @@
<string name="zen_mode_from_none_messages">Don\u2019t allow any messages</string> <string name="zen_mode_from_none_messages">Don\u2019t allow any messages</string>
<!-- [CHAR LIMIT=80] Zen mode settings: Allow alarms option --> <!-- [CHAR LIMIT=80] Zen mode settings: Allow alarms option -->
<string name="zen_mode_alarms">Allow alarms</string> <string name="zen_mode_alarms">Alarms</string>
<!-- [CHAR LIMIT=NONE] Zen mode settings: Allow alarms summary -->
<string name="zen_mode_alarms_summary">From timers, alarms, security systems, and other apps</string>
<!-- [CHAR LIMIT=50] Zen mode settings: Alarms option (ie: sound from alarm clock) --> <!-- [CHAR LIMIT=50] Zen mode settings: Alarms option (ie: sound from alarm clock) -->
<string name="zen_mode_alarms_list">alarms</string> <string name="zen_mode_alarms_list">alarms</string>
<!-- [CHAR LIMIT=80] Zen mode settings: Allow media (sound from video) to bypass dnd --> <!-- [CHAR LIMIT=80] Zen mode settings: Allow media (sound from video) to bypass dnd -->
<string name="zen_mode_media">Play media sounds</string> <string name="zen_mode_media">Media sounds</string>
<!-- [CHAR LIMIT=NONE] Zen mode settings: Allow media (sound from video) to bypass dnd summary-->
<string name="zen_mode_media_summary">From videos, games, and other media</string>
<!-- [CHAR LIMIT=50] Zen mode settings: Media (ie: sound from video) --> <!-- [CHAR LIMIT=50] Zen mode settings: Media (ie: sound from video) -->
<string name="zen_mode_media_list">media</string> <string name="zen_mode_media_list">media</string>
<!-- [CHAR LIMIT=80] Zen mode settings: allow touch sounds to bypass DND --> <!-- [CHAR LIMIT=80] Zen mode settings: allow touch sounds to bypass DND -->
<string name="zen_mode_system">Allow touch sounds</string> <string name="zen_mode_system">Touch sounds</string>
<!-- [CHAR LIMIT=NONE] Zen mode settings: allow touch sounds to bypass DND summary -->
<string name="zen_mode_system_summary">From your keyboard and other buttons</string>
<!-- [CHAR LIMIT=50] Zen mode settings: System sounds (ie: touch sounds) --> <!-- [CHAR LIMIT=50] Zen mode settings: System sounds (ie: touch sounds) -->
<string name="zen_mode_system_list">touch sounds</string> <string name="zen_mode_system_list">touch sounds</string>
<!-- [CHAR LIMIT=80] Zen mode settings: Allow reminder notifications/sounds to bypass DND --> <!-- [CHAR LIMIT=80] Zen mode settings: Allow reminder notifications/sounds to bypass DND -->
<string name="zen_mode_reminders">Allow reminders</string> <string name="zen_mode_reminders">Reminders</string>
<!-- [CHAR LIMIT=NONE] Zen mode settings: Allow reminder notifications/sounds to bypass DND summary -->
<string name="zen_mode_reminders_summary">From tasks and reminders</string>
<!-- [CHAR LIMIT=50] Zen mode settings: Reminders (ie: calendar reminders are allowed to bypass dnd) --> <!-- [CHAR LIMIT=50] Zen mode settings: Reminders (ie: calendar reminders are allowed to bypass dnd) -->
<string name="zen_mode_reminders_list">reminders</string> <string name="zen_mode_reminders_list">reminders</string>
<!-- [CHAR LIMIT=80] Zen mode settings: Allow event notifications/sounds to bypass DND --> <!-- [CHAR LIMIT=80] Zen mode settings: Allow event notifications/sounds to bypass DND -->
<string name="zen_mode_events">Allow events</string> <string name="zen_mode_events">Events</string>
<!-- [CHAR LIMIT=NONE] Zen mode settings: Allow event notifications/sounds to bypass DND summary -->
<string name="zen_mode_events_summary">From upcoming calendar events</string>
<!-- [CHAR LIMIT=100] Zen mode settings: Allow apps to bypass DND --> <!-- [CHAR LIMIT=100] Zen mode settings: Allow apps to bypass DND -->
<string name="zen_mode_bypassing_apps">Allow apps to override</string> <string name="zen_mode_bypassing_apps">Allow apps to override</string>

View File

@@ -21,26 +21,26 @@
android:key="zen_mode_calls_settings_page" android:key="zen_mode_calls_settings_page"
android:title="@string/zen_mode_calls_title" > android:title="@string/zen_mode_calls_title" >
<PreferenceCategory <PreferenceCategory
android:title="@string/zen_mode_settings_category" android:title="@string/zen_mode_settings_category"
android:key="zen_mode_settings_category_calls"> android:key="zen_mode_settings_category_calls">
<!-- Calls --> <!-- Calls -->
<ListPreference <ListPreference
android:key="zen_mode_calls" android:key="zen_mode_calls"
android:title="@string/zen_mode_calls" android:title="@string/zen_mode_calls"
android:entries="@array/zen_mode_contacts_calls_entries" android:entries="@array/zen_mode_contacts_calls_entries"
android:entryValues="@array/zen_mode_contacts_values"/> android:entryValues="@array/zen_mode_contacts_values"/>
<Preference <Preference
android:key="zen_mode_starred_contacts_callers" android:key="zen_mode_starred_contacts_callers"
android:title="@string/zen_mode_starred_contacts_title"/> android:title="@string/zen_mode_starred_contacts_title"/>
<!-- Repeat callers --> <!-- Repeat callers -->
<SwitchPreference <SwitchPreference
android:key="zen_mode_repeat_callers" android:key="zen_mode_repeat_callers"
android:title="@string/zen_mode_repeat_callers_title" /> android:title="@string/zen_mode_repeat_callers_title" />
</PreferenceCategory> </PreferenceCategory>
<com.android.settingslib.widget.FooterPreference/> <com.android.settingslib.widget.FooterPreference/>
</PreferenceScreen> </PreferenceScreen>

View File

@@ -36,27 +36,32 @@
<!-- Alarms --> <!-- Alarms -->
<SwitchPreference <SwitchPreference
android:key="zen_rule_alarms" android:key="zen_rule_alarms"
android:title="@string/zen_mode_alarms"/> android:title="@string/zen_mode_alarms"
android:summary="@string/zen_mode_alarms_summary"/>
<!-- Media --> <!-- Media -->
<SwitchPreference <SwitchPreference
android:key="zen_rule_media" android:key="zen_rule_media"
android:title="@string/zen_mode_media"/> android:title="@string/zen_mode_media"
android:summary="@string/zen_mode_media_summary"/>
<!-- System --> <!-- System -->
<SwitchPreference <SwitchPreference
android:key="zen_rule_system" android:key="zen_rule_system"
android:title="@string/zen_mode_system"/> android:title="@string/zen_mode_system"
android:summary="@string/zen_mode_system_summary"/>
<!-- Reminders --> <!-- Reminders -->
<SwitchPreference <SwitchPreference
android:key="zen_rule_reminders" android:key="zen_rule_reminders"
android:title="@string/zen_mode_reminders"/> android:title="@string/zen_mode_reminders"
android:summary="@string/zen_mode_reminders_summary"/>
<!-- Events --> <!-- Events -->
<SwitchPreference <SwitchPreference
android:key="zen_rule_events" android:key="zen_rule_events"
android:title="@string/zen_mode_events"/> android:title="@string/zen_mode_events"
android:summary="@string/zen_mode_events_summary"/>
</PreferenceCategory> </PreferenceCategory>
<Preference <Preference

View File

@@ -0,0 +1,67 @@
<?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"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="zen_mode_people_settings_page"
android:title="@string/zen_category_people" >
<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"/>
<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">
</PreferenceCategory>
<!-- Footer that shows if user is put into alarms only or total silence mode by an app -->
<com.android.settingslib.widget.FooterPreference/>
</PreferenceScreen>

View File

@@ -19,49 +19,7 @@
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto" xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="zen_mode_settings" android:key="zen_mode_settings"
android:title="@string/zen_mode_settings_title"> android:title=" ">
<PreferenceCategory
android:key="zen_mode_settings_category_behavior"
android:title="@string/zen_category_behavior">
<!-- Calls -->
<Preference
android:key="zen_mode_behavior_calls"
android:title="@string/zen_mode_calls_title"
android:fragment="com.android.settings.notification.zen.ZenModeCallsSettings" />
<!-- Messages -->
<Preference
android:key="zen_mode_behavior_messages"
android:title="@string/zen_mode_messages_title"
android:fragment="com.android.settings.notification.zen.ZenModeMessagesSettings" />
<!-- All sounds -->
<Preference
android:key="zen_sound_vibration_settings"
android:title="@string/zen_sound_title"
android:fragment="com.android.settings.notification.zen.ZenModeSoundVibrationSettings"
android:icon="@drawable/ic_chevron_right_24dp"/>
</PreferenceCategory>
<!-- What to block (effects) -->
<Preference
android:key="zen_mode_block_effects_settings"
android:title="@string/zen_mode_restrict_notifications_title"
android:fragment="com.android.settings.notification.zen.ZenModeRestrictNotificationsSettings"
settings:allowDividerAbove="true"/>
<!-- DND duration settings -->
<com.android.settings.notification.zen.ZenDurationDialogPreference
android:key="zen_mode_duration_settings"
android:title="@string/zen_mode_duration_settings_title"
android:widgetLayout="@null"/>
<!-- Automatic rules -->
<Preference
android:key="zen_mode_automation_settings"
android:title="@string/zen_mode_automation_settings_title"
android:fragment="com.android.settings.notification.zen.ZenModeAutomationSettings"/>
<!-- Turn on DND button --> <!-- Turn on DND button -->
<com.android.settingslib.widget.LayoutPreference <com.android.settingslib.widget.LayoutPreference
@@ -73,6 +31,53 @@
settings:allowDividerBelow="true" settings:allowDividerBelow="true"
settings:keywords="@string/keywords_zen_mode_settings"/> settings:keywords="@string/keywords_zen_mode_settings"/>
<PreferenceCategory
android:key="zen_mode_settings_category_behavior"
android:title="@string/zen_category_behavior">
<!-- People -->
<Preference
android:key="zen_mode_behavior_people"
android:title="@string/zen_category_people"
android:fragment="com.android.settings.notification.zen.ZenModePeopleSettings" />
<!-- Apps -->
<Preference
android:key="zen_mode_behavior_apps"
android:title="@string/zen_category_apps"
android:fragment="com.android.settings.notification.zen.ZenModeBypassingAppsSettings" />
<!-- All sounds -->
<Preference
android:key="zen_sound_vibration_settings"
android:title="@string/zen_category_exceptions"
android:fragment="com.android.settings.notification.zen.ZenModeSoundVibrationSettings" />
</PreferenceCategory>
<!-- Automatic rules -->
<Preference
android:key="zen_mode_automation_settings"
android:title="@string/zen_mode_automation_settings_title"
settings:allowDividerAbove="true"
settings:allowDividerBelow="true"
android:fragment="com.android.settings.notification.zen.ZenModeAutomationSettings"/>
<PreferenceCategory
android:key="zen_mode_settings_advanced"
settings:initialExpandedChildrenCount="1">
<!-- What to block (effects) -->
<Preference
android:key="zen_mode_block_effects_settings"
android:title="@string/zen_mode_restrict_notifications_title"
android:fragment="com.android.settings.notification.zen.ZenModeRestrictNotificationsSettings" />
<!-- DND duration settings -->
<com.android.settings.notification.zen.ZenDurationDialogPreference
android:key="zen_mode_duration_settings"
android:title="@string/zen_mode_duration_settings_title"
android:widgetLayout="@null"/>
</PreferenceCategory>
<!-- Footer that shows if user is put into alarms only or total silence mode by an app --> <!-- Footer that shows if user is put into alarms only or total silence mode by an app -->
<com.android.settingslib.widget.FooterPreference/> <com.android.settingslib.widget.FooterPreference/>

View File

@@ -24,48 +24,35 @@
android:title="@string/zen_mode_settings_category" android:title="@string/zen_mode_settings_category"
android:key="zen_mode_settings_category_sound_vibration"> android:key="zen_mode_settings_category_sound_vibration">
<!-- Calls -->
<Preference
android:key="zen_mode_calls_settings"
android:title="@string/zen_mode_calls"
android:fragment="com.android.settings.notification.zen.ZenModeCallsSettings" />
<!-- Messages -->
<Preference
android:key="zen_mode_messages_settings"
android:title="@string/zen_mode_messages"
android:fragment="com.android.settings.notification.zen.ZenModeMessagesSettings" />
<!-- Alarms --> <!-- Alarms -->
<SwitchPreference <SwitchPreference
android:key="zen_mode_alarms" android:key="zen_mode_alarms"
android:title="@string/zen_mode_alarms"/> android:title="@string/zen_mode_alarms"
android:summary="@string/zen_mode_alarms_summary"/>
<!-- Media --> <!-- Media -->
<SwitchPreference <SwitchPreference
android:key="zen_mode_media" android:key="zen_mode_media"
android:title="@string/zen_mode_media"/> android:title="@string/zen_mode_media"
android:summary="@string/zen_mode_media_summary"/>
<!-- System --> <!-- System -->
<SwitchPreference <SwitchPreference
android:key="zen_mode_system" android:key="zen_mode_system"
android:title="@string/zen_mode_system"/> android:title="@string/zen_mode_system"
android:summary="@string/zen_mode_system_summary"/>
<!-- Reminders --> <!-- Reminders -->
<SwitchPreference <SwitchPreference
android:key="zen_mode_reminders" android:key="zen_mode_reminders"
android:title="@string/zen_mode_reminders"/> android:title="@string/zen_mode_reminders"
android:summary="@string/zen_mode_reminders_summary"/>
<!-- Events --> <!-- Events -->
<SwitchPreference <SwitchPreference
android:key="zen_mode_events" android:key="zen_mode_events"
android:title="@string/zen_mode_events"/> android:title="@string/zen_mode_events"
android:summary="@string/zen_mode_events_summary"/>
<!-- Apps overriding DND -->
<Preference
android:key="zen_mode_bypassing_apps"
android:title="@string/zen_mode_bypassing_apps"
android:fragment="com.android.settings.notification.zen.ZenModeBypassingAppsSettings"/>
</PreferenceCategory> </PreferenceCategory>

View File

@@ -19,6 +19,7 @@ package com.android.settings.notification.zen;
import android.app.AutomaticZenRule; import android.app.AutomaticZenRule;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.util.Slog;
import androidx.preference.Preference; import androidx.preference.Preference;

View File

@@ -22,6 +22,7 @@ import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.provider.Settings; import android.provider.Settings;
import android.text.TextUtils;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.core.text.BidiFormatter; import androidx.core.text.BidiFormatter;
@@ -121,29 +122,30 @@ public class ZenModeAllBypassingAppsPreferenceController extends AbstractPrefere
mApplicationsState.ensureIcon(entry); mApplicationsState.ensureIcon(entry);
for (NotificationChannel channel : mNotificationBackend for (NotificationChannel channel : mNotificationBackend
.getNotificationChannelsBypassingDnd(pkg, entry.info.uid).getList()) { .getNotificationChannelsBypassingDnd(pkg, entry.info.uid).getList()) {
if (!TextUtils.isEmpty(channel.getConversationId())) {
// conversation channels that bypass dnd will be shown on the People page
continue;
}
Preference pref = new AppPreference(mPrefContext); Preference pref = new AppPreference(mPrefContext);
pref.setKey(pkg + "|" + channel.getId()); pref.setKey(pkg + "|" + channel.getId());
pref.setTitle(BidiFormatter.getInstance().unicodeWrap(entry.label)); pref.setTitle(BidiFormatter.getInstance().unicodeWrap(entry.label));
pref.setIcon(entry.icon); pref.setIcon(entry.icon);
pref.setSummary(BidiFormatter.getInstance().unicodeWrap(channel.getName())); pref.setSummary(BidiFormatter.getInstance().unicodeWrap(channel.getName()));
pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { pref.setOnPreferenceClickListener(preference -> {
@Override Bundle args = new Bundle();
public boolean onPreferenceClick(Preference preference) { args.putString(AppInfoBase.ARG_PACKAGE_NAME, entry.info.packageName);
Bundle args = new Bundle(); args.putInt(AppInfoBase.ARG_PACKAGE_UID, entry.info.uid);
args.putString(AppInfoBase.ARG_PACKAGE_NAME, entry.info.packageName); args.putString(Settings.EXTRA_CHANNEL_ID, channel.getId());
args.putInt(AppInfoBase.ARG_PACKAGE_UID, entry.info.uid); new SubSettingLauncher(mContext)
args.putString(Settings.EXTRA_CHANNEL_ID, channel.getId()); .setDestination(ChannelNotificationSettings.class.getName())
new SubSettingLauncher(mContext) .setArguments(args)
.setDestination(ChannelNotificationSettings.class.getName()) .setTitleRes(R.string.notification_channel_title)
.setArguments(args) .setResultListener(mHostFragment, 0)
.setTitleRes(R.string.notification_channel_title) .setSourceMetricsCategory(
.setResultListener(mHostFragment, 0) SettingsEnums.NOTIFICATION_ZEN_MODE_OVERRIDING_APP)
.setSourceMetricsCategory( .launch();
SettingsEnums.NOTIFICATION_ZEN_MODE_OVERRIDING_APP) return true;
.launch();
return true;
}
}); });
channelsBypassingDnd.add(pref); channelsBypassingDnd.add(pref);
} }

View File

@@ -0,0 +1,210 @@
/*
* 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<ApplicationsState.AppEntry> apps = mAppSession.rebuild(filter,
ApplicationsState.ALPHA_COMPARATOR);
if (apps != null) {
updateNotificationChannelList(apps);
}
}
@VisibleForTesting
void updateNotificationChannelList(List<ApplicationsState.AppEntry> apps) {
if (mCategory == null || apps == null) {
return;
}
List<Preference> 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<ApplicationsState.AppEntry> 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();
}
};
}

View File

@@ -277,7 +277,7 @@ public class ZenModeBackend {
} else if (category == NotificationManager.Policy.PRIORITY_CATEGORY_CALLS){ } else if (category == NotificationManager.Policy.PRIORITY_CATEGORY_CALLS){
return R.string.zen_mode_from_none_calls; return R.string.zen_mode_from_none_calls;
} }
return 0; return R.string.zen_mode_from_none;
} }
protected int getContactsSummary(int category) { protected int getContactsSummary(int category) {

View File

@@ -64,4 +64,4 @@ public class ZenModeCallsPreferenceController extends
preference.setSummary(mSummaryBuilder.getCallsSettingSummary(getPolicy())); preference.setSummary(mSummaryBuilder.getCallsSettingSummary(getPolicy()));
} }
} }
} }

View File

@@ -1,75 +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_MESSAGES;
import android.app.settings.SettingsEnums;
import android.content.Context;
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.Indexable;
import com.android.settingslib.search.SearchIndexable;
import java.util.ArrayList;
import java.util.List;
@SearchIndexable
public class ZenModeMessagesSettings extends ZenModeSettingsBase implements Indexable {
@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 ZenModePriorityMessagesPreferenceController(context, lifecycle));
controllers.add(new ZenModeStarredContactsPreferenceController(context, lifecycle,
PRIORITY_CATEGORY_MESSAGES, "zen_mode_starred_contacts_messages"));
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.NOTIFICATION_ZEN_MODE_PRIORITY;
}
/**
* For Search.
*/
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.zen_mode_messages_settings) {
@Override
public List<AbstractPreferenceController> createPreferenceControllers(
Context context) {
return buildPreferenceControllers(context, null);
}
};
}

View File

@@ -0,0 +1,67 @@
/*
* 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 com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.lifecycle.Lifecycle;
public class ZenModePeoplePreferenceController extends
AbstractZenModePreferenceController implements PreferenceControllerMixin {
private final String KEY;
private final ZenModeSettings.SummaryBuilder mSummaryBuilder;
public ZenModePeoplePreferenceController(Context context, Lifecycle lifecycle, String key) {
super(context, key, lifecycle);
KEY = key;
mSummaryBuilder = new ZenModeSettings.SummaryBuilder(context);
}
@Override
public String getPreferenceKey() {
return KEY;
}
@Override
public boolean isAvailable() {
return true;
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
switch (getZenMode()) {
case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
case Settings.Global.ZEN_MODE_ALARMS:
preference.setEnabled(false);
preference.setSummary(mBackend.getAlarmsTotalSilenceCallsMessagesSummary(
NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES));
break;
default:
preference.setEnabled(true);
// TODO: How do all of the people options roll up into the summary?
//preference.setSummary(mSummaryBuilder.getMessagesSettingSummary(getPolicy()));
}
}
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2018 The Android Open Source Project * Copyright (C) 2020 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -17,10 +17,16 @@
package com.android.settings.notification.zen; package com.android.settings.notification.zen;
import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS; 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; import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.AbstractPreferenceController;
@@ -32,47 +38,60 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
@SearchIndexable @SearchIndexable
public class ZenModeCallsSettings extends ZenModeSettingsBase implements Indexable { public class ZenModePeopleSettings extends ZenModeSettingsBase implements Indexable {
@Override @Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) { protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
return buildPreferenceControllers(context, getSettingsLifecycle()); final Activity activity = getActivity();
final Application app;
if (activity != null) {
app = activity.getApplication();
} else {
app = null;
}
return buildPreferenceControllers(
context, getSettingsLifecycle(), app, this, getFragmentManager());
} }
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context, private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
Lifecycle lifecycle) { Lifecycle lifecycle, Application app, Fragment host, FragmentManager fragmentManager) {
List<AbstractPreferenceController> controllers = new ArrayList<>(); 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 ZenModePriorityCallsPreferenceController(context, lifecycle));
controllers.add(new ZenModeStarredContactsPreferenceController(context, lifecycle, controllers.add(new ZenModeStarredContactsPreferenceController(context, lifecycle,
PRIORITY_CATEGORY_CALLS, "zen_mode_starred_contacts_callers")); PRIORITY_CATEGORY_CALLS, "zen_mode_starred_contacts_callers"));
controllers.add(new ZenModeRepeatCallersPreferenceController(context, lifecycle, controllers.add(new ZenModeRepeatCallersPreferenceController(context, lifecycle,
context.getResources().getInteger(com.android.internal.R.integer context.getResources().getInteger(com.android.internal.R.integer
.config_zen_repeat_callers_threshold))); .config_zen_repeat_callers_threshold)));
controllers.add(new ZenModeBehaviorFooterPreferenceController( controllers.add(
context, lifecycle, R.string.zen_mode_calls_footer)); new ZenModeAllBypassingConversationsPreferenceController(context, app, host));
controllers.add(new ZenModeSettingsFooterPreferenceController(context, lifecycle,
fragmentManager));
return controllers; return controllers;
} }
@Override @Override
protected int getPreferenceScreenResId() { protected int getPreferenceScreenResId() {
return R.xml.zen_mode_calls_settings; return R.xml.zen_mode_people_settings;
} }
@Override @Override
public int getMetricsCategory() { public int getMetricsCategory() {
return SettingsEnums.NOTIFICATION_ZEN_MODE_PRIORITY; return SettingsEnums.DND_PEOPLE;
} }
/** /**
* For Search. * For Search.
*/ */
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.zen_mode_calls_settings) { new BaseSearchIndexProvider(R.xml.zen_mode_people_settings) {
@Override @Override
public List<AbstractPreferenceController> createPreferenceControllers( public List<AbstractPreferenceController> createPreferenceControllers(
Context context) { Context context) {
return buildPreferenceControllers(context, null); return buildPreferenceControllers(context, null, null, null, null);
} }
}; };
} }

View File

@@ -78,10 +78,9 @@ public class ZenModeSettings extends ZenModeSettingsBase {
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context, private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
Lifecycle lifecycle, FragmentManager fragmentManager) { Lifecycle lifecycle, FragmentManager fragmentManager) {
List<AbstractPreferenceController> controllers = new ArrayList<>(); List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new ZenModeCallsPreferenceController(context, lifecycle, controllers.add(new ZenModePeoplePreferenceController(context, lifecycle,
"zen_mode_behavior_calls")); "zen_mode_behavior_people"));
controllers.add(new ZenModeMessagesPreferenceController(context, lifecycle, controllers.add(new ZenModeBypassingAppsPreferenceController(context, lifecycle));
"zen_mode_behavior_messages"));
controllers.add(new ZenModeBlockedEffectsPreferenceController(context, lifecycle)); controllers.add(new ZenModeBlockedEffectsPreferenceController(context, lifecycle));
controllers.add(new ZenModeDurationPreferenceController(context, lifecycle)); controllers.add(new ZenModeDurationPreferenceController(context, lifecycle));
controllers.add(new ZenModeAutomationPreferenceController(context)); controllers.add(new ZenModeAutomationPreferenceController(context));

View File

@@ -77,7 +77,7 @@ public class ZenModeBehaviorFooterPreferenceControllerTest {
private Context mContext; private Context mContext;
private ContentResolver mContentResolver; private ContentResolver mContentResolver;
private int mTitleResId = R.string.zen_sound_title; private int mTitleResId = R.string.zen_mode_settings_title;
@Before @Before
public void setup() { public void setup() {

View File

@@ -79,4 +79,4 @@ public final class ZenModeCallsPreferenceControllerTest {
mController.updateState(pref); mController.updateState(pref);
verify(pref).setSummary(any()); verify(pref).setSummary(any());
} }
} }