Snap for 6326486 from 4db41f15c7 to mainline-release

Change-Id: I374bd470bb455c40690df733a138fca938cd500e
This commit is contained in:
android-build-team Robot
2020-03-24 07:08:54 +00:00
35 changed files with 1411 additions and 795 deletions

View File

@@ -0,0 +1,158 @@
<?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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/app_entities_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="@dimen/notification_importance_toggle_marginTop"
android:orientation="vertical">
<com.android.settings.notification.NotificationButtonRelativeLayout
android:id="@+id/priority_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/notification_importance_button_padding"
android:clickable="true"
android:focusable="true">
<ImageView
android:id="@+id/priority_icon"
android:src="@drawable/ic_important_outline"
android:background="@android:color/transparent"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false"/>
<TextView
android:id="@+id/priority_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:clickable="false"
android:focusable="false"
android:layout_toEndOf="@id/priority_icon"
android:layout_marginStart="@dimen/notification_importance_drawable_padding"
android:textAppearance="@style/TextAppearance.NotificationImportanceButton.Unselected"
android:text="@string/notification_priority_title"/>
<TextView
android:id="@+id/priority_summary"
android:paddingTop="@dimen/notification_importance_button_padding"
android:text="@string/notification_channel_summary_priority"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false"
android:ellipsize="end"
android:maxLines="2"
android:layout_below="@id/priority_icon"
android:textAppearance="@style/TextAppearance.NotificationImportanceDetail"
android:visibility="gone" />
</com.android.settings.notification.NotificationButtonRelativeLayout>
<com.android.settings.notification.NotificationButtonRelativeLayout
android:id="@+id/alert"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/notification_importance_button_padding"
android:layout_marginTop="@dimen/notification_importance_button_separation"
android:clickable="true"
android:focusable="true">
<ImageView
android:id="@+id/alert_icon"
android:src="@drawable/ic_notifications_alert"
android:background="@android:color/transparent"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false"/>
<TextView
android:id="@+id/alert_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:clickable="false"
android:focusable="false"
android:layout_toEndOf="@id/alert_icon"
android:layout_marginStart="@dimen/notification_importance_drawable_padding"
android:textAppearance="@style/TextAppearance.NotificationImportanceButton.Unselected"
android:text="@string/notification_alert_title"/>
<TextView
android:id="@+id/alert_summary"
android:paddingTop="@dimen/notification_importance_button_padding"
android:text="@string/notification_channel_summary_default"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false"
android:ellipsize="end"
android:maxLines="2"
android:layout_below="@id/alert_icon"
android:textAppearance="@style/TextAppearance.NotificationImportanceDetail"
android:visibility="gone" />
</com.android.settings.notification.NotificationButtonRelativeLayout>
<com.android.settings.notification.NotificationButtonRelativeLayout
android:id="@+id/silence"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/notification_importance_button_padding"
android:layout_marginTop="@dimen/notification_importance_button_separation"
android:clickable="true"
android:focusable="true">
<ImageView
android:id="@+id/silence_icon"
android:src="@drawable/ic_notifications_off_24dp"
android:background="@android:color/transparent"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false"/>
<TextView
android:id="@+id/silence_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:clickable="false"
android:focusable="false"
android:layout_toEndOf="@id/silence_icon"
android:layout_marginStart="@dimen/notification_importance_drawable_padding"
android:textAppearance="@style/TextAppearance.NotificationImportanceButton.Unselected"
android:text="@string/notification_silence_title"/>
<TextView
android:id="@+id/silence_summary"
android:paddingTop="@dimen/notification_importance_button_padding"
android:text="@string/notification_channel_summary_low"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false"
android:ellipsize="end"
android:maxLines="2"
android:layout_below="@id/silence_icon"
android:textAppearance="@style/TextAppearance.NotificationImportanceDetail"
android:visibility="gone" />
</com.android.settings.notification.NotificationButtonRelativeLayout>
</LinearLayout>

View File

@@ -39,7 +39,6 @@
android:layout_height="wrap_content"
android:layout_gravity="left"
android:gravity="center"
android:paddingTop="@dimen/zen_mode_button_padding_vertical"
android:text="@string/zen_mode_button_turn_on"/>
<Button
@@ -51,7 +50,6 @@
android:layout_height="wrap_content"
android:layout_gravity="left"
android:gravity="center"
android:paddingTop="@dimen/zen_mode_button_padding_vertical"
android:text="@string/zen_mode_button_turn_off" />
</LinearLayout>

View File

@@ -7757,13 +7757,13 @@
<!-- Setting summary for controlling how caption text display in real time [CHAR LIMIT=NONE]-->
<string name="live_caption_summary">Automatically caption media</string>
<!-- Sound: Summary for the Do not Disturb option when there is no automatic rules turned on. [CHAR LIMIT=NONE]-->
<string name="zen_mode_settings_summary_off">Never</string>
<!-- Sound: Summary for the Do not Disturb option when there are no automatic rules enabled. [CHAR LIMIT=NONE]-->
<string name="zen_mode_settings_summary_off">None</string>
<!-- Sound: Summary for the Do not Disturb option when at least one automatic rules turned on. [CHAR LIMIT=NONE]-->
<!-- Sound: Summary for the Do not Disturb option when at least one automatic rule is enabled. [CHAR LIMIT=NONE]-->
<plurals name="zen_mode_settings_summary_on">
<item quantity="one">1 enabled</item>
<item quantity="other"><xliff:g id="on_count" example="10">%d</xliff:g> enabled</item>
<item quantity="one">1 schedule set</item>
<item quantity="other"><xliff:g id="on_count" example="10">%d</xliff:g> schedules set</item>
</plurals>
<!-- Sound: Title for the Do not Disturb option and associated settings page. [CHAR LIMIT=50]-->
@@ -7778,26 +7778,8 @@
<!-- Do not disturb: Title for the Do not Disturb dialog to turn on Do not disturb. [CHAR LIMIT=50]-->
<string name="zen_mode_settings_turn_on_dialog_title">Turn on Do Not Disturb</string>
<!-- Do not disturb: Title for the page describing what can bypass DND. [CHAR LIMIT=30] -->
<string name="zen_mode_behavior_settings_title">Exceptions</string>
<!-- Do not disturb: Title for the dnd duration setting (user can specify how long dnd will last when toggling dnd on from qs or settings) [CHAR LIMIT=30] -->
<string name="zen_mode_duration_settings_title">Default duration</string>
<!-- Do not disturb: Instructions indicating what types of sounds can bypass DND. [CHAR LIMIT=52] -->
<string name="zen_mode_behavior_allow_title">Allow sounds and vibrations from</string>
<!-- Do not disturb: Subtitle for DND behavior indicating no sound will get past DND. [CHAR LIMIT=30] -->
<string name="zen_mode_behavior_no_sound">No sound</string>
<!-- Do not disturb: Subtitle for DND behavior indicating no sound will get past DND. [CHAR LIMIT=40] -->
<string name="zen_mode_behavior_total_silence">Total Silence</string>
<!-- Do not disturb: Used before specifying which sounds can bypass DND (ie: No sound except alarms and reminders). [CHAR LIMIT=40] -->
<string name="zen_mode_behavior_no_sound_except">No sound except <xliff:g id="categories" example="alarms, media and system feedback">%1$s</xliff:g></string>
<!-- Do not disturb: Specifies alarms and media can bypass DND. [CHAR LIMIT=100] -->
<string name="zen_mode_behavior_alarms_only">No sound except alarms and media</string>
<string name="zen_mode_behavior_alarms_only">Alarms and media sounds can interrupt</string>
<!-- Do not disturb: Title for the zen mode automation option in Settings. [CHAR LIMIT=40] -->
<string name="zen_mode_automation_settings_title">Schedules</string>
@@ -7832,15 +7814,6 @@
<!-- Do not disturb: Switch toggle to toggle whether to use an automatic dnd rule or not [CHAR LIMIT=40] -->
<string name="zen_mode_use_automatic_rule">Use schedule</string>
<!-- Do not disturb: Zen mode option: Important interruptions [CHAR LIMIT=60] -->
<string name="zen_mode_option_important_interruptions">Priority only</string>
<!-- Do not disturb: Zen mode option: Alarms only [CHAR LIMIT=60] -->
<string name="zen_mode_option_alarms">Alarms only</string>
<!-- Do not disturb: Zen mode option: No interruptions [CHAR LIMIT=60] -->
<string name="zen_mode_option_no_interruptions">Total silence</string>
<!-- 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>
@@ -7853,8 +7826,8 @@
<!-- 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 title [CHAR LIMIT=80] -->
<string name="zen_mode_restrict_notifications_title">Restrict notifications</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] -->
<string name="zen_mode_restrict_notifications_mute">No sound from notifications</string>
<!-- Do not disturb:Mute notifications summary [CHAR LIMIT=NONE] -->
@@ -7993,7 +7966,7 @@
</plurals>
<!-- Do not disturb settings, main screen, category header [CHAR LIMIT=120]-->
<string name="zen_category_behavior">Exceptions when Do Not Disturb is on</string>
<string name="zen_category_behavior">What can interrupt Do Not Disturb</string>
<!-- Do not disturb settings, main screen, field, dnd breakthrough [CHAR LIMIT=100]-->
<string name="zen_category_people">People</string>
<!-- Do not disturb settings, main screen, field, dnd breakthrough [CHAR LIMIT=100]-->
@@ -8002,23 +7975,12 @@
<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, main screen, field, duration setting where user can specify how
long dnd will last when toggling dnd on from qs or settings) [CHAR LIMIT=100] -->
<string name="zen_category_duration">Set duration for Quick Settings</string>
<!-- 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>
<!-- Do not disturb settings, sound and vibrations screen category [CHAR LIMIT=100]-->
<string name="zen_sound_category_title">Mute all except</string>
<!-- Do not disturb settings, sound and vibrations summary [CHAR LIMIT=100]-->
<string name="zen_sound_all_muted">Muted</string>
<!-- Do not disturb settings, sound and vibrations summary [CHAR LIMIT=100]-->
<string name="zen_sound_none_muted">Not muted</string>
<!-- Do not disturb settings, sound and vibrations summary [CHAR LIMIT=100]-->
<string name="zen_sound_one_allowed">Muted, but allow <xliff:g id="sound_type" example="alarms">%1$s</xliff:g></string>
<!-- Do not disturb settings, sound and vibrations summary [CHAR LIMIT=100]-->
<string name="zen_sound_two_allowed">Muted, but allow <xliff:g id="sound_type" example="alarms">%1$s</xliff:g> and <xliff:g id="sound_type" example="media">%2$s</xliff:g></string>
<!-- Do not disturb settings, sound and vibrations summary [CHAR LIMIT=100]-->
<string name="zen_sound_three_allowed">Muted, but allow <xliff:g id="sound_type" example="alarms">%1$s</xliff:g>, <xliff:g id="sound_type" example="alarms">%2$s</xliff:g>, and <xliff:g id="sound_type" example="media">%3$s</xliff:g></string>
<!-- Do not disturb custom settings dialog title [CHAR LIMIT=40]-->
<string name="zen_custom_settings_dialog_title">Custom settings</string>
@@ -8190,11 +8152,11 @@
<!-- Description for the toggle shown on the app-level bubbles page [CHAR LIMIT=NONE] -->
<string name="bubbles_app_toggle_summary">Allow <xliff:g id="app_name" example="YouTube">%1$s</xliff:g> to show some notifications as bubbles</string>
<!-- Title of the dialog shown when the user has disabled bubbles at the feature level but tries to enable it for an app. [CHAR LIMIT=NONE] -->
<string name="bubbles_feature_disabled_dialog_title">Turn on bubbles</string>
<string name="bubbles_feature_disabled_dialog_title">Turn on bubbles for device?</string>
<!-- Description of the dialog shown when the user has disabled bubbles at the feature level but tries to enable it for an app. [CHAR LIMIT=NONE] -->
<string name="bubbles_feature_disabled_dialog_text">To turn on bubbles for this app, first you need to turn them on for your device. This affects other apps in which you previously turned on bubbles.</string>
<string name="bubbles_feature_disabled_dialog_text">Turning on bubbles for this app will also turn on bubbles for your device.\n\nThis affects other apps or conversations that are allowed to bubble.</string>
<!-- Button of the dialog shown when the user has disabled bubbles at the feature level but tries to enable it for an app. [CHAR LIMIT=60]-->
<string name="bubbles_feature_disabled_button_approve">Turn on for device</string>
<string name="bubbles_feature_disabled_button_approve">Turn on</string>
<!-- Button to cancel out of the dialog shown when the user has disabled bubbles at the feature level but tries to enable it for an app. [CHAR LIMIT=60] -->
<string name="bubbles_feature_disabled_button_cancel">Cancel</string>
@@ -8213,8 +8175,8 @@
<string name="bubble_app_setting_none">Nothing can bubble</string>
<!-- Bubble app settings: Title above a list of conversations that have been selected to bubble [CHAR LIMIT=60]-->
<string name="bubble_app_setting_selected_conversation_title">Conversations</string>
<!-- Bubble app settings: Title above a list of conversations that have been excluded from bubbling [CHAR LIMIT=60] -->
<string name="bubble_app_setting_excluded_conversation_title">Excluded</string>
<!-- Bubble app settings: Title above a list of conversations that have been excluded from bubbling [CHAR LIMIT=100] -->
<string name="bubble_app_setting_excluded_conversation_title">All conversations can bubble except</string>
<!-- Configure notifications: title for swipe direction [CHAR LIMIT=60] -->
<string name="swipe_direction_title">Swipe actions</string>
@@ -8444,6 +8406,12 @@
<!-- [CHAR LIMIT=180] Notification importance description. More details from allow_interruption string - specifics of how notifications may interrupt. -->
<string name="allow_interruption_summary">Let the app make sound, vibrate, and/or pop notifications on screen</string>
<!-- [CHAR LIMIT=150] Notification Importance title: important conversation level -->
<string name="notification_priority_title">Priority</string>
<!-- [CHAR LIMIT=150] Notification Importance title: important conversation level summary -->
<string name="notification_channel_summary_priority">Shows at top of conversation section and appears as a bubble.</string>
<!-- Channel summaries for the app notification page -->
<!-- [CHAR LIMIT=150] Notification Importance title: min importance level summary -->
@@ -8923,19 +8891,15 @@
<!-- [CHAR LIMIT=20] Zen mode settings: Calls option -->
<string name="zen_mode_calls">Allow calls</string>
<!-- [CHAR LIMIT=40] Zen mode settings: Allow calls toggle title -->
<string name="zen_mode_calls_title">Calls</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 -->
<string name="zen_mode_custom_calls_footer">For \u2018<xliff:g id="schedule_name" example="Schedule 1">%1$s</xliff:g>\u2019 incoming calls are blocked. You can adjust settings to allow your friends, family, or other contacts to reach you.</string>
<!-- [CHAR LIMIT=50] Zen mode settings: Starred contacts preference title -->
<string name="zen_mode_starred_contacts_title">Starred contacts</string>
<!-- Zen mode settings: Starred contacts summary [CHAR LIMIT=NONE] -->
<plurals name="zen_mode_starred_contacts_summary_additional_contacts">
<item quantity="one">1 other</item>
@@ -8949,128 +8913,119 @@
<!-- [CHAR LIMIT=40] Zen mode settings: Messages option -->
<string name="zen_mode_messages">Allow messages</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>
<!-- [CHAR LIMIT=40] Zen mode settings: Calls or messages option value: From anyone -->
<string name="zen_mode_from_anyone">From 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>
<!-- [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>
<!-- Do not disturb settings, calls summary [CHAR LIMIT=100]-->
<string name="zen_calls_summary_starred_repeat">From starred contacts and repeat callers</string>
<!-- Do not disturb settings, calls summary [CHAR LIMIT=100]-->
<string name="zen_calls_summary_contacts_repeat">From contacts and repeat callers</string>
<!-- 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 -->
<string name="zen_mode_from_none_messages">Don\u2019t allow any messages</string>
<!-- [CHAR LIMIT=80] Zen mode settings: Allow alarms option -->
<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) -->
<string name="zen_mode_alarms_list">alarms</string>
<!-- [CHAR LIMIT=80] Zen mode settings: Allow media (sound from video) to bypass dnd -->
<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) -->
<string name="zen_mode_media_list">media</string>
<!-- [CHAR LIMIT=80] Zen mode settings: allow touch sounds to bypass DND -->
<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) -->
<string name="zen_mode_system_list">touch sounds</string>
<!-- [CHAR LIMIT=80] Zen mode settings: Allow reminder notifications/sounds to bypass DND -->
<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) -->
<string name="zen_mode_reminders_list">reminders</string>
<!-- [CHAR LIMIT=80] Zen mode settings: Allow event notifications/sounds to bypass DND -->
<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 -->
<string name="zen_mode_bypassing_apps">Allow apps to override</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=120] Zen mode settings: No apps are bypassing DND -->
<string name="zen_mode_bypassing_apps_subtext_none">No apps can override Do Not Disturb</string>
<!-- [CHAR LIMIT=120] Zen mode settings: Allow apps to bypass DND -->
<plurals name="zen_mode_bypassing_apps_subtext">
<item quantity="zero">No apps can override Do Not Disturb</item>
<item quantity="one">Notifications from 1 app can override Do Not Disturb</item>
<item quantity="other">Notifications from <xliff:g id="number" example="2">%1$d</xliff:g> apps can override Do Not Disturb</item>
</plurals>
<!-- [CHAR LIMIT=50] Zen mode settings: Events (ie: calendar events) -->
<string name="zen_mode_events_list">events</string>
<!-- [CHAR LIMIT=50] Zen mode settings: All callers summary -->
<string name="zen_mode_all_callers">anyone</string>
<!-- [CHAR LIMIT=100] Zen mode settings: Allow apps to bypass DND -->
<string name="zen_mode_bypassing_apps">Allow apps to override</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 -->
<plurals name="zen_mode_bypassing_apps_subtext">
<item quantity="one"><xliff:g id="app_name" example="Nest">%s</xliff:g> can interrupt</item>
<item quantity="other"><xliff:g id="app_names" example="Nest and Google Play Store">%s</xliff:g> can interrupt</item>
</plurals>
<!-- [CHAR LIMIT=30] Zen mode settings: List item in a summary indicating additional apps are
allowed to bypass Do Not Disturb. For example, "Nest, Messages, and 2 more can interrupt". -->
<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=50] Zen mode settings: Selected callers summary -->
<string name="zen_mode_contacts_callers">contacts</string>
<!-- [CHAR LIMIT=120] Zen mode settings: Summary for sound interruption settings -->
<plurals name="zen_mode_other_sounds_summary">
<item quantity="one"><xliff:g id="sound_category">%s</xliff:g> can interrupt</item>
<item quantity="other"><xliff:g id="sound_categories" example="Alarms, media sounds, and 2 more">%s</xliff:g> can interrupt</item>
</plurals>
<!-- [CHAR LIMIT=120] Zen mode settings: No other sounds are allowed to bypass DND -->
<string name="zen_mode_other_sounds_none">Nothing can interrupt</string>
<!-- [CHAR LIMIT=30] Zen mode settings: List item in a summary indicating additional sounds
are allowed to bypass Do Not Disturb. For example, "Alarms, media sounds, and 2 more can
interrupt". -->
<string name="zen_mode_other_sounds_list_count"><xliff:g id="number" example="2">%d</xliff:g> more</string>
<!-- [CHAR LIMIT=50] Zen mode settings: Selected callers summary -->
<string name="zen_mode_starred_callers">starred contacts</string>
<!-- [CHAR LIMIT=120] Zen mode settings: Summary for people category -->
<string name="zen_mode_people_none">No one can interrupt</string>
<!-- [CHAR LIMIT=120] Zen mode settings: Summary for people category -->
<string name="zen_mode_people_some">Some people can interrupt</string>
<!-- [CHAR LIMIT=120] Zen mode settings: Summary for people category -->
<string name="zen_mode_people_all">All people can interrupt</string>
<!-- [CHAR LIMIT=50] Zen mode settings: Repeat callers option -->
<string name="zen_mode_repeat_callers">Repeat callers</string>
<!-- [CHAR LIMIT=50] Zen mode settings: Repeat callers (ie: repeat callers are allowed to bypass dnd) -->
<string name="zen_mode_repeat_callers_list">repeat callers</string>
<!-- [CHAR LIMIT=70] Zen mode settings: Allow repeat callers toggle title -->
<string name="zen_mode_repeat_callers_title">Allow repeat callers</string>
<!-- [CHAR LIMIT=50] Zen mode settings: All callers summary -->
<string name="zen_mode_all_callers">anyone</string>
<!-- [CHAR LIMIT=50] Zen mode settings: Selected callers summary -->
<string name="zen_mode_contacts_callers">contacts</string>
<!-- [CHAR LIMIT=50] Zen mode settings: Selected callers summary -->
<string name="zen_mode_starred_callers">starred contacts</string>
<!-- [CHAR LIMIT=50] Zen mode settings: Repeat callers (ie: repeat callers are allowed to bypass dnd) -->
<string name="zen_mode_repeat_callers_list">repeat callers</string>
<!-- [CHAR LIMIT=50] Zen mode settings: calls summary -->
<string name="zen_mode_calls_summary_one">Allow from <xliff:g id="caller type" example="contacts">%1$s</xliff:g></string>
<!-- [CHAR LIMIT=50] Zen mode settings: calls summary -->
<string name="zen_mode_calls_summary_two">Allow from <xliff:g id="caller type" example="starred contacts">%1$s</xliff:g> and <xliff:g id="callert tpye" example="repeat callers">%2$s</xliff:g></string>
<!-- [CHAR LIMIT=200] Zen mode settings: Repeat callers option summary -->
<string name="zen_mode_repeat_callers_summary">If the same person calls a second time within a <xliff:g id="minutes">%d</xliff:g> minute period</string>
@@ -9079,43 +9034,33 @@
<!-- [CHAR LIMIT=20] Zen mode settings: When option -->
<string name="zen_mode_when">Automatically turn on</string>
<!-- [CHAR LIMIT=20] Zen mode settings: When option value: Never -->
<string name="zen_mode_when_never">Never</string>
<!-- [CHAR LIMIT=20] Zen mode settings: When option value: Every night -->
<string name="zen_mode_when_every_night">Every night</string>
<!-- [CHAR LIMIT=20] Zen mode settings: When option value: Weeknights -->
<string name="zen_mode_when_weeknights">Weeknights</string>
<!-- [CHAR LIMIT=20] Zen mode settings: Start time option -->
<string name="zen_mode_start_time">Start time</string>
<!-- [CHAR LIMIT=20] Zen mode settings: End time option -->
<string name="zen_mode_end_time">End time</string>
<!-- [CHAR LIMIT=60] Zen mode settings: End time option: Summary text value format when end time = next day -->
<string name="zen_mode_end_time_next_day_summary_format"><xliff:g id="formatted_time" example="7:00 AM">%s</xliff:g> next day</string>
<!-- [CHAR LIMIT=NONE] Zen mode summary spoken when changing mode by voice: switch to alarms only forever. -->
<string name="zen_mode_summary_alarms_only_indefinite">Change to alarms only indefinitely</string>
<!-- [CHAR LIMIT=NONE] Zen mode summary spoken when changing mode by voice: switch to alarms only for < 60 minutes. -->
<plurals name="zen_mode_summary_alarms_only_by_minute">
<item quantity="one">Change to alarms only for one minute until <xliff:g id="formattedTime" example="10:00 PM">%2$s</xliff:g></item>
<item quantity="other">Change to alarms only for <xliff:g id="duration" example="2">%1$d</xliff:g> minutes (until <xliff:g id="formattedTime" example="10:00 PM">%2$s</xliff:g>)</item>
</plurals>
<!-- [CHAR LIMIT=NONE] Zen mode summary spoken when changing mode by voice: switch to alarms only for N hours. -->
<plurals name="zen_mode_summary_alarms_only_by_hour">
<item quantity="one">Change to alarms only for one hour until <xliff:g id="formattedTime" example="10:00 PM">%2$s</xliff:g></item>
<item quantity="other">Change to alarms only for <xliff:g id="duration" example="2">%1$d</xliff:g> hours until <xliff:g id="formattedTime" example="10:00 PM">%2$s</xliff:g></item>
</plurals>
<!-- [CHAR LIMIT=NONE] Zen mode summary spoken when changing mode by voice: switch to alarms only until a specific time. -->
<string name="zen_mode_summary_alarms_only_by_time">Change to alarms only until <xliff:g id="formattedTime" example="10:00 PM">%1$s</xliff:g></string>
<!-- [CHAR LIMIT=NONE] Zen mode summary spoken when changing mode by voice: Turn on all notifications. -->
<string name="zen_mode_summary_always">Change to always interrupt</string>
@@ -11875,6 +11820,51 @@
<!-- Developer settings: text for the bug report handler selection toast shown if an invalid bug report handler was chosen. [CHAR LIMIT=NONE] -->
<string name="select_invalid_bug_report_handler_toast_text">This choice is no longer valid. Try again.</string>
<!-- Quick controls name sentence case [CHAR LIMIT=40] -->
<string name="quick_controls_sentence">Quick controls</string>
<!-- Quick controls name lower case [CHAR LIMIT=40] -->
<string name="quick_controls_lower">quick controls</string>
<!-- Cards and passes name sentence case [CHAR LIMIT=40] -->
<string name="cards_passes_sentence">Cards &amp; passes</string>
<!-- Cards and passes name lower case [CHAR LIMIT=40] -->
<string name="cards_passes_lower">cards &amp; passes</string>
<!-- Power menu setting name [CHAR LIMIT=NONE] -->
<string name="power_menu_setting_name">Power menu</string>
<!-- Power menu setting title [CHAR LIMIT=NONE] -->
<string name="power_menu_setting_title">Power button menu</string>
<!-- Power menu setting option cards and passes [CHAR LIMIT=NONE] -->
<string name="power_menu_cards_passes">Show cards &amp; passes</string>
<!-- Power menu setting option quick controls [CHAR LIMIT=NONE] -->
<string name="power_menu_quick_controls">Show quick controls</string>
<!-- Power menu setting option cards, passes, quick controls [CHAR LIMIT=NONE] -->
<string name="power_menu_cards_passes_quick_controls">Show cards, passes, and quick controls</string>
<!-- Power menu setting option none [CHAR LIMIT=NONE] -->
<string name="power_menu_none">Don\u2019t show any content</string>
<!-- Power menu setting Privacy [CHAR LIMIT=40] -->
<string name="power_menu_privacy">Privacy</string>
<!-- Power menu setting privacy show all [CHAR LIMIT=NONE] -->
<string name="power_menu_privacy_show">Show cards and controls when locked</string>
<!-- Power menu setting privacy hide all [CHAR LIMIT=NONE] -->
<string name="power_menu_privacy_hide">Hide cards and controls when locked</string>
<!-- Quick controls toggle name [CHAR LIMIT=NONE] -->
<string name="quick_controls_setting_toggle">Show quick controls</string>
<!-- Quick controls toggle subtitle [CHAR LIMIT=NONE] -->
<string name="quick_controls_setting_subtitle">To access controls for connected devices, hold the Power button</string>
<!-- Title for RTT setting. [CHAR LIMIT=NONE] -->
<string name="rtt_settings_title"></string>
<!-- Subtext for showing the option of RTT setting. [CHAR LIMIT=NONE] -->

View File

@@ -26,19 +26,11 @@
settings:allowDividerBelow="true"/>
<!-- important conversation -->
<com.android.settingslib.RestrictedSwitchPreference
android:key="important"
<com.android.settings.notification.app.ConversationPriorityPreference
android:key="priority"
android:title="@string/notification_conversation_important"
android:icon="@drawable/ic_important_outline"
settings:restrictedSwitchSummary="@string/enabled_by_admin"
settings:allowDividerAbove="true"/>
<!-- silence -->
<com.android.settingslib.RestrictedSwitchPreference
android:key="alerting"
android:icon="@drawable/ic_notification_alert"
android:title="@string/notification_alert_title"
android:summary="@string/notification_channel_summary_default"/>
settings:allowDividerAbove="true"
settings:allowDividerBelow="true"/>
<!-- bubbles -->
<com.android.settingslib.RestrictedSwitchPreference
@@ -48,47 +40,6 @@
android:icon="@drawable/ic_create_bubble"
settings:restrictedSwitchSummary="@string/enabled_by_admin" />
<!-- peeking -->
<com.android.settingslib.RestrictedSwitchPreference
android:key="high_importance"
android:title="@string/notification_importance_high_title"
android:summary="@string/notification_channel_summary_high"/>
<!-- Visibility Override -->
<com.android.settings.RestrictedListPreference
android:key="visibility_override"
android:icon="@drawable/ic_lock"
android:title="@string/app_notification_visibility_override_title"/>
<!-- Show badge -->
<com.android.settingslib.RestrictedSwitchPreference
android:key="badge"
android:title="@string/notification_channel_badge_title"
settings:useAdditionalSummary="true"
settings:restrictedSwitchSummary="@string/enabled_by_admin"/>
<!-- Lights -->
<com.android.settingslib.RestrictedSwitchPreference
android:key="lights"
android:title="@string/notification_show_lights_title"
settings:useAdditionalSummary="true"/>
<!-- Vibration -->
<com.android.settingslib.RestrictedSwitchPreference
android:key="vibrate"
android:icon="@drawable/ic_volume_ringer_vibrate"
android:title="@string/notification_vibrate_title"
settings:useAdditionalSummary="true" />
<!-- ringtone -->
<com.android.settings.notification.app.NotificationSoundPreference
android:key="ringtone"
android:title="@string/notification_channel_sound_title"
android:dialogTitle="@string/notification_channel_sound_title"
android:icon="@drawable/ic_media_stream"
android:showSilent="true"
android:showDefault="true"/>
<!-- demote -->
<Preference
android:key="demote"
@@ -97,22 +48,55 @@
android:summary="@string/demote_conversation_summary"
settings:allowDividerAbove="true"/>
<Preference
android:key="add_to_home"
android:title="@string/notification_conversation_add_to_home"
android:icon="@drawable/ic_add_to_home"
settings:allowDividerAbove="true"/>
<Preference
android:key="app_link"
android:title="@string/app_settings_link"
settings:allowDividerAbove="true"/>
<com.android.settings.notification.app.NotificationFooterPreference
android:key="desc" />
<com.android.settings.notification.app.NotificationFooterPreference
android:key="block_desc"
settings:allowDividerAbove="false"/>
<PreferenceCategory
android:key="channel_advanced"
android:order="50"
settings:initialExpandedChildrenCount="0">
<!-- peeking -->
<com.android.settingslib.RestrictedSwitchPreference
android:key="high_importance"
android:title="@string/notification_importance_high_title"
android:summary="@string/notification_channel_summary_high"/>
<!-- ringtone -->
<com.android.settings.notification.app.NotificationSoundPreference
android:key="ringtone"
android:title="@string/notification_channel_sound_title"
android:dialogTitle="@string/notification_channel_sound_title"
android:icon="@drawable/ic_media_stream"
android:showSilent="true"
android:showDefault="true"/>
<!-- Visibility Override -->
<com.android.settings.RestrictedListPreference
android:key="visibility_override"
android:icon="@drawable/ic_lock"
android:title="@string/app_notification_visibility_override_title"/>
<!-- Show badge -->
<com.android.settingslib.RestrictedSwitchPreference
android:key="badge"
android:title="@string/notification_channel_badge_title"
settings:useAdditionalSummary="true"
settings:restrictedSwitchSummary="@string/enabled_by_admin"/>
<!-- Lights -->
<com.android.settingslib.RestrictedSwitchPreference
android:key="lights"
android:title="@string/notification_show_lights_title"
settings:useAdditionalSummary="true"/>
<!-- Vibration -->
<com.android.settingslib.RestrictedSwitchPreference
android:key="vibrate"
android:icon="@drawable/ic_volume_ringer_vibrate"
android:title="@string/notification_vibrate_title"
settings:useAdditionalSummary="true" />
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -29,7 +29,7 @@
<PreferenceCategory
android:key="security_settings_face_unlock_category"
android:title="@string/security_settings_face_settings_use_face_category">
<SwitchPreference
<com.android.settingslib.RestrictedSwitchPreference
android:key="security_settings_face_keyguard"
android:title="@string/security_settings_face_settings_use_face_unlock_phone"
app:keywords="@string/keywords_face_unlock"
@@ -39,7 +39,7 @@
android:title="@string/security_settings_face_settings_use_face_for_apps"
app:keywords="@string/keywords_face_unlock"
app:controller="com.android.settings.biometrics.face.FaceSettingsAppPreferenceController"/>
<SwitchPreference
<com.android.settingslib.RestrictedSwitchPreference
android:key="security_lockscreen_bypass"
android:title="@string/lockscreen_bypass_title"
android:summary="@string/lockscreen_bypass_summary"

View File

@@ -26,7 +26,6 @@
android:title="@string/zen_mode_settings_title"
android:selectable="false"
android:layout="@layout/zen_mode_settings_button"
settings:allowDividerAbove="true"
settings:allowDividerBelow="true"
settings:keywords="@string/keywords_zen_mode_settings"/>
@@ -55,26 +54,26 @@
<!-- Automatic rules -->
<Preference
android:key="zen_mode_automation_settings"
android:title="@string/zen_mode_automation_settings_title"
android:title="@string/zen_category_schedule"
settings:allowDividerAbove="true"
settings:allowDividerBelow="true"
android:fragment="com.android.settings.notification.zen.ZenModeAutomationSettings"/>
<PreferenceCategory
android:key="zen_mode_settings_advanced"
settings:initialExpandedChildrenCount="1">
settings:initialExpandedChildrenCount="0">
<!-- DND duration settings -->
<com.android.settings.notification.zen.ZenDurationDialogPreference
android:key="zen_mode_duration_settings"
android:title="@string/zen_category_duration"
android:widgetLayout="@null"/>
<!-- 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 -->

View File

@@ -282,12 +282,12 @@ public class SettingsActivity extends SettingsBaseActivity
launchSettingFragment(initialFragmentName, intent);
}
final boolean deviceProvisioned = WizardManagerHelper.isDeviceProvisioned(this);
final boolean isInSetupWizard = WizardManagerHelper.isAnySetupWizard(getIntent());
final ActionBar actionBar = getActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(deviceProvisioned);
actionBar.setHomeButtonEnabled(deviceProvisioned);
actionBar.setDisplayHomeAsUpEnabled(!isInSetupWizard);
actionBar.setHomeButtonEnabled(!isInSetupWizard);
actionBar.setDisplayShowTitleEnabled(true);
}
mSwitchBar = findViewById(R.id.switch_bar);

View File

@@ -25,6 +25,8 @@ import android.provider.Settings;
import androidx.preference.Preference;
import com.android.settings.Utils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.RestrictedSwitchPreference;
/**
* Preference controller for Face settings page controlling the ability to unlock the phone
@@ -53,7 +55,7 @@ public class FaceSettingsKeyguardPreferenceController extends FaceSettingsPrefer
public boolean isChecked() {
if (!FaceSettings.isAvailable(mContext)) {
return false;
} else if (adminDisabled()) {
} else if (getRestrictingAdmin() != null) {
return false;
}
return Settings.Secure.getIntForUser(mContext.getContentResolver(),
@@ -73,11 +75,12 @@ public class FaceSettingsKeyguardPreferenceController extends FaceSettingsPrefer
@Override
public void updateState(Preference preference) {
EnforcedAdmin admin;
super.updateState(preference);
if (!FaceSettings.isAvailable(mContext)) {
preference.setEnabled(false);
} else if (adminDisabled()) {
preference.setEnabled(false);
} else if ((admin = getRestrictingAdmin()) != null) {
((RestrictedSwitchPreference) preference).setDisabledByAdmin(admin);
} else if (!mFaceManager.hasEnrolledTemplates(getUserId())) {
preference.setEnabled(false);
} else {

View File

@@ -26,6 +26,8 @@ import android.provider.Settings;
import androidx.preference.Preference;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.RestrictedSwitchPreference;
public class FaceSettingsLockscreenBypassPreferenceController
extends FaceSettingsPreferenceController {
@@ -60,11 +62,12 @@ public class FaceSettingsLockscreenBypassPreferenceController
@Override
public void updateState(Preference preference) {
EnforcedAdmin admin;
super.updateState(preference);
if (!FaceSettings.isAvailable(mContext)) {
preference.setEnabled(false);
} else if (adminDisabled()) {
preference.setEnabled(false);
} else if ((admin = getRestrictingAdmin()) != null) {
((RestrictedSwitchPreference) preference).setDisabledByAdmin(admin);
} else if (!mFaceManager.hasEnrolledTemplates(getUserId())) {
preference.setEnabled(false);
} else {

View File

@@ -18,9 +18,10 @@ package com.android.settings.biometrics.face;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.os.UserHandle;
import com.android.settings.core.TogglePreferenceController;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.RestrictedLockUtilsInternal;
/**
* Abstract base class for all face settings toggles.
@@ -41,12 +42,8 @@ public abstract class FaceSettingsPreferenceController extends TogglePreferenceC
return mUserId;
}
protected boolean adminDisabled() {
DevicePolicyManager dpm =
(DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
return dpm != null &&
(dpm.getKeyguardDisabledFeatures(null, UserHandle.myUserId())
& DevicePolicyManager.KEYGUARD_DISABLE_FACE)
!= 0;
protected EnforcedAdmin getRestrictingAdmin() {
return RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
mContext, DevicePolicyManager.KEYGUARD_DISABLE_FACE, mUserId);
}
}

View File

@@ -14,7 +14,8 @@
package com.android.settings.display;
import static com.android.settingslib.display.BrightnessUtils.GAMMA_SPACE_MAX;
import static com.android.settingslib.display.BrightnessUtils.convertLinearToGamma;
import static com.android.settingslib.display.BrightnessUtils.GAMMA_SPACE_MIN;
import static com.android.settingslib.display.BrightnessUtils.convertLinearToGammaFloat;
import android.content.ContentResolver;
import android.content.Context;
@@ -52,16 +53,16 @@ public class BrightnessLevelPreferenceController extends AbstractPreferenceContr
private static final Uri BRIGHTNESS_FOR_VR_URI;
private static final Uri BRIGHTNESS_ADJ_URI;
private final int mMinBrightness;
private final int mMaxBrightness;
private final int mMinVrBrightness;
private final int mMaxVrBrightness;
private final float mMinBrightness;
private final float mMaxBrightness;
private final float mMinVrBrightness;
private final float mMaxVrBrightness;
private final ContentResolver mContentResolver;
private Preference mPreference;
static {
BRIGHTNESS_URI = System.getUriFor(System.SCREEN_BRIGHTNESS);
BRIGHTNESS_URI = System.getUriFor(System.SCREEN_BRIGHTNESS_FLOAT);
BRIGHTNESS_FOR_VR_URI = System.getUriFor(System.SCREEN_BRIGHTNESS_FOR_VR);
BRIGHTNESS_ADJ_URI = System.getUriFor(System.SCREEN_AUTO_BRIGHTNESS_ADJ);
}
@@ -80,10 +81,14 @@ public class BrightnessLevelPreferenceController extends AbstractPreferenceContr
lifecycle.addObserver(this);
}
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mMinBrightness = powerManager.getMinimumScreenBrightnessSetting();
mMaxBrightness = powerManager.getMaximumScreenBrightnessSetting();
mMinVrBrightness = powerManager.getMinimumScreenBrightnessForVrSetting();
mMaxVrBrightness = powerManager.getMaximumScreenBrightnessForVrSetting();
mMinBrightness = powerManager.getBrightnessConstraint(
PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM);
mMaxBrightness = powerManager.getBrightnessConstraint(
PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM);
mMinVrBrightness = powerManager.getBrightnessConstraint(
PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM_VR);
mMaxVrBrightness = powerManager.getBrightnessConstraint(
PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM_VR);
mContentResolver = mContext.getContentResolver();
}
@@ -129,16 +134,15 @@ public class BrightnessLevelPreferenceController extends AbstractPreferenceContr
private double getCurrentBrightness() {
final int value;
if (isInVrMode()) {
value = convertLinearToGamma(System.getInt(mContentResolver,
System.SCREEN_BRIGHTNESS_FOR_VR, mMaxBrightness),
value = convertLinearToGammaFloat(System.getFloat(mContentResolver,
System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT, mMaxBrightness),
mMinVrBrightness, mMaxVrBrightness);
} else {
value = convertLinearToGamma(Settings.System.getInt(mContentResolver,
System.SCREEN_BRIGHTNESS, mMinBrightness),
value = convertLinearToGammaFloat(Settings.System.getFloat(mContentResolver,
System.SCREEN_BRIGHTNESS_FLOAT, mMinBrightness),
mMinBrightness, mMaxBrightness);
}
return getPercentage(value, 0, GAMMA_SPACE_MAX);
return getPercentage(value, GAMMA_SPACE_MIN, GAMMA_SPACE_MAX);
}
private double getPercentage(double value, int min, int max) {

View File

@@ -27,10 +27,6 @@ import android.util.Log;
import androidx.annotation.VisibleForTesting;
import com.android.ims.ImsManager;
import com.android.settings.network.SubscriptionUtil;
import com.android.settings.network.telephony.MobileNetworkUtils;
/**
* Controller class for querying Volte status
*/
@@ -66,12 +62,6 @@ public class VolteQueryImsState extends ImsQueryController {
return (new ImsQueryEnhanced4gLteModeUserSetting(subId)).query();
}
@VisibleForTesting
ImsManager getImsManager(int subId) {
return ImsManager.getInstance(mContext,
SubscriptionUtil.getPhoneId(mContext, subId));
}
/**
* Check whether VoLTE has been provisioned or not on this subscription
*
@@ -101,8 +91,15 @@ public class VolteQueryImsState extends ImsQueryController {
if (!SubscriptionManager.isValidSubscriptionId(mSubId)) {
return false;
}
return isVoLteProvisioned()
&& MobileNetworkUtils.isImsServiceStateReady(getImsManager(mSubId));
if (!isVoLteProvisioned()) {
return false;
}
try {
return isServiceStateReady(mSubId);
} catch (InterruptedException | IllegalArgumentException | ImsException exception) {
Log.w(LOG_TAG, "fail to get VoLte service status. subId=" + mSubId, exception);
}
return false;
}
/**

View File

@@ -204,6 +204,8 @@ public class EnabledNetworkModePreferenceController extends
}
void setPreferenceEntries() {
clearAllEntries();
switch (getEnabledNetworkType()) {
case ENABLED_NETWORKS_CDMA_CHOICES:
add5gEntry(addNrToLteNetworkType(
@@ -608,6 +610,11 @@ public class EnabledNetworkModePreferenceController extends
return mEntries.toArray(new String[0]);
}
private void clearAllEntries() {
mEntries.clear();
mEntriesValue.clear();
}
private String[] getEntryValues() {
Integer intArr[] = mEntriesValue.toArray(new Integer[0]);
return Arrays.stream(intArr)

View File

@@ -68,7 +68,7 @@ public class BubblePreferenceController extends NotificationPreferenceController
if (isDefaultChannel()) {
return true;
} else {
return mAppRow != null && mAppRow.allowBubbles;
return mAppRow != null;
}
}
return true;

View File

@@ -18,15 +18,8 @@ package com.android.settings.notification.app;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceScreen;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.notification.NotificationBackend;
@@ -60,7 +53,7 @@ public class ConversationListSettings extends DashboardFragment {
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
mControllers = new ArrayList<>();
mControllers.add(new ImportantConversationsPreferenceController(context, mBackend));
mControllers.add(new PriorityConversationsPreferenceController(context, mBackend));
mControllers.add(new AllConversationsPreferenceController(context, mBackend));
return new ArrayList<>(mControllers);
}

View File

@@ -79,18 +79,13 @@ public class ConversationNotificationSettings extends NotificationSettings {
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
mControllers = new ArrayList<>();
mControllers.add(new ConversationHeaderPreferenceController(context, this));
mControllers.add(new ConversationImportantPreferenceController(
mControllers.add(new ConversationPriorityPreferenceController(
context, mBackend, mDependentFieldListener));
mControllers.add(new DefaultImportancePreferenceController(
context, mDependentFieldListener, mBackend));
mControllers.add(new AddToHomeScreenPreferenceController(context, mBackend));
mControllers.add(new HighImportancePreferenceController(
context, mDependentFieldListener, mBackend));
mControllers.add(new SoundPreferenceController(context, this,
mDependentFieldListener, mBackend));
mControllers.add(new VibrationPreferenceController(context, mBackend));
mControllers.add(new AppLinkPreferenceController(context));
mControllers.add(new DescriptionPreferenceController(context));
mControllers.add(new VisibilityPreferenceController(context, new LockPatternUtils(context),
mBackend));
mControllers.add(new LightsPreferenceController(context, mBackend));

View File

@@ -0,0 +1,221 @@
/*
* 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.app;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.drawable.Drawable;
import android.transition.AutoTransition;
import android.transition.TransitionManager;
import android.util.AttributeSet;
import android.util.Pair;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
import com.android.settings.Utils;
import com.android.settingslib.R;
public class ConversationPriorityPreference extends Preference {
private boolean mIsConfigurable = true;
private int mImportance;
private int mOriginalImportance;
private boolean mPriorityConversation;
private View mSilenceButton;
private View mAlertButton;
private View mPriorityButton;
private Context mContext;
Drawable selectedBackground;
Drawable unselectedBackground;
private static final int BUTTON_ANIM_TIME_MS = 100;
public ConversationPriorityPreference(Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
public ConversationPriorityPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
public ConversationPriorityPreference(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public ConversationPriorityPreference(Context context) {
super(context);
init(context);
}
private void init(Context context) {
mContext = context;
selectedBackground = mContext.getDrawable(R.drawable.button_border_selected);
unselectedBackground = mContext.getDrawable(R.drawable.button_border_unselected);
setLayoutResource(R.layout.notif_priority_conversation_preference);
}
public void setImportance(int importance) {
mImportance = importance;
}
public void setConfigurable(boolean configurable) {
mIsConfigurable = configurable;
}
public void setPriorityConversation(boolean priorityConversation) {
mPriorityConversation = priorityConversation;
}
public void setOriginalImportance(int importance) {
mOriginalImportance = importance;
}
@Override
public void onBindViewHolder(final PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
holder.itemView.setClickable(false);
mSilenceButton = holder.findViewById(R.id.silence);
mAlertButton = holder.findViewById(R.id.alert);
mPriorityButton = holder.findViewById(R.id.priority_group);
if (!mIsConfigurable) {
mSilenceButton.setEnabled(false);
mAlertButton.setEnabled(false);
mPriorityButton.setEnabled(false);
}
updateToggles((ViewGroup) holder.itemView, mImportance, mPriorityConversation,
false);
mSilenceButton.setOnClickListener(v -> {
callChangeListener(new Pair(IMPORTANCE_LOW, false));
updateToggles((ViewGroup) holder.itemView, IMPORTANCE_LOW, false, true);
});
mAlertButton.setOnClickListener(v -> {
int newImportance = Math.max(mOriginalImportance, IMPORTANCE_DEFAULT);
callChangeListener(new Pair(newImportance, false));
updateToggles((ViewGroup) holder.itemView, newImportance, false, true);
});
mPriorityButton.setOnClickListener(v -> {
int newImportance = Math.max(mOriginalImportance, IMPORTANCE_DEFAULT);
callChangeListener(new Pair(newImportance, true));
updateToggles((ViewGroup) holder.itemView, newImportance, true, true);
});
}
private ColorStateList getAccentTint() {
return Utils.getColorAccent(getContext());
}
private ColorStateList getRegularTint() {
return Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary);
}
void updateToggles(ViewGroup parent, int importance, boolean isPriority,
boolean fromUser) {
if (fromUser) {
AutoTransition transition = new AutoTransition();
transition.setDuration(BUTTON_ANIM_TIME_MS);
TransitionManager.beginDelayedTransition(parent, transition);
}
ColorStateList colorAccent = getAccentTint();
ColorStateList colorNormal = getRegularTint();
ImageView silenceIcon = parent.findViewById(R.id.silence_icon);
TextView silenceLabel = parent.findViewById(R.id.silence_label);
TextView silenceSummary = parent.findViewById(R.id.silence_summary);
ImageView alertIcon = parent.findViewById(R.id.alert_icon);
TextView alertLabel = parent.findViewById(R.id.alert_label);
TextView alertSummary = parent.findViewById(R.id.alert_summary);
ImageView priorityIcon = parent.findViewById(R.id.priority_icon);
TextView priorityLabel = parent.findViewById(R.id.priority_label);
TextView prioritySummary = parent.findViewById(R.id.priority_summary);
if (importance <= IMPORTANCE_LOW && importance > IMPORTANCE_UNSPECIFIED) {
alertSummary.setVisibility(GONE);
alertIcon.setImageTintList(colorNormal);
alertLabel.setTextColor(colorNormal);
prioritySummary.setVisibility(GONE);
priorityIcon.setImageTintList(colorNormal);
priorityLabel.setTextColor(colorNormal);
silenceIcon.setImageTintList(colorAccent);
silenceLabel.setTextColor(colorAccent);
silenceSummary.setVisibility(VISIBLE);
mAlertButton.setBackground(unselectedBackground);
mPriorityButton.setBackground(unselectedBackground);
mSilenceButton.setBackground(selectedBackground);
// a11y service won't always read the newly appearing text in the right order if the
// selection happens too soon (readback happens on a different thread as layout). post
// the selection to make that conflict less likely
parent.post(() -> mSilenceButton.setSelected(true));
} else {
if (isPriority) {
alertSummary.setVisibility(GONE);
alertIcon.setImageTintList(colorNormal);
alertLabel.setTextColor(colorNormal);
prioritySummary.setVisibility(VISIBLE);
priorityIcon.setImageTintList(colorAccent);
priorityLabel.setTextColor(colorAccent);
silenceIcon.setImageTintList(colorNormal);
silenceLabel.setTextColor(colorNormal);
silenceSummary.setVisibility(GONE);
mAlertButton.setBackground(unselectedBackground);
mPriorityButton.setBackground(selectedBackground);
mSilenceButton.setBackground(unselectedBackground);
parent.post(() -> mPriorityButton.setSelected(true));
} else {
alertSummary.setVisibility(VISIBLE);
alertIcon.setImageTintList(colorAccent);
alertLabel.setTextColor(colorAccent);
prioritySummary.setVisibility(GONE);
priorityIcon.setImageTintList(colorNormal);
priorityLabel.setTextColor(colorNormal);
silenceIcon.setImageTintList(colorNormal);
silenceLabel.setTextColor(colorNormal);
silenceSummary.setVisibility(GONE);
mAlertButton.setBackground(selectedBackground);
mPriorityButton.setBackground(unselectedBackground);
mSilenceButton.setBackground(unselectedBackground);
parent.post(() -> mAlertButton.setSelected(true));
}
}
}
}

View File

@@ -16,25 +16,22 @@
package com.android.settings.notification.app;
import static android.provider.Settings.Secure.BUBBLE_IMPORTANT_CONVERSATIONS;
import android.content.Context;
import android.provider.Settings;
import android.util.Pair;
import androidx.preference.Preference;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.notification.NotificationBackend;
import com.android.settingslib.RestrictedSwitchPreference;
public class ConversationImportantPreferenceController extends NotificationPreferenceController
public class ConversationPriorityPreferenceController extends NotificationPreferenceController
implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
private static final String TAG = "ConvoImpPC";
private static final String KEY = "important";
private static final String TAG = "ConvoPriorityPC";
private static final String KEY = "priority";
private final NotificationSettings.DependentFieldListener mDependentFieldListener;
public ConversationImportantPreferenceController(Context context,
public ConversationPriorityPreferenceController(Context context,
NotificationBackend backend, NotificationSettings.DependentFieldListener listener) {
super(context, backend);
mDependentFieldListener = listener;
@@ -58,10 +55,12 @@ public class ConversationImportantPreferenceController extends NotificationPrefe
public void updateState(Preference preference) {
if (mAppRow != null) {
RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference;
pref.setDisabledByAdmin(mAdmin);
pref.setChecked(mChannel.isImportantConversation());
pref.setEnabled(!pref.isDisabledByAdmin());
preference.setEnabled(mAdmin == null && !mChannel.isImportanceLockedByOEM());
ConversationPriorityPreference pref = (ConversationPriorityPreference) preference;
pref.setConfigurable(!mChannel.isImportanceLockedByOEM());
pref.setImportance(mChannel.getImportance());
pref.setOriginalImportance(mChannel.getOriginalImportance());
pref.setPriorityConversation(mChannel.isImportantConversation());
}
}
@@ -70,19 +69,21 @@ public class ConversationImportantPreferenceController extends NotificationPrefe
if (mChannel == null) {
return false;
}
final boolean value = (Boolean) newValue;
mChannel.setImportantConversation(value);
if (value && bubbleImportantConversations()) {
boolean wasPriorityConversation = mChannel.isImportantConversation();
final Pair<Integer, Boolean> value = (Pair) newValue;
mChannel.setImportance(value.first);
mChannel.setImportantConversation(value.second);
if (value.second) {
mChannel.setAllowBubbles(true);
} else if (wasPriorityConversation) {
mChannel.setAllowBubbles(false);
}
mDependentFieldListener.onFieldValueChanged();
saveChannel();
return true;
}
private boolean bubbleImportantConversations() {
return Settings.Secure.getInt(mContext.getContentResolver(),
BUBBLE_IMPORTANT_CONVERSATIONS, 1) == 1;
}
}

View File

@@ -1,85 +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.app;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import android.app.NotificationChannel;
import android.content.Context;
import androidx.preference.Preference;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.notification.NotificationBackend;
import com.android.settingslib.RestrictedSwitchPreference;
public class DefaultImportancePreferenceController extends NotificationPreferenceController
implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
private static final String KEY = "alerting";
private NotificationSettings.DependentFieldListener mDependentFieldListener;
public DefaultImportancePreferenceController(Context context,
NotificationSettings.DependentFieldListener dependentFieldListener,
NotificationBackend backend) {
super(context, backend);
mDependentFieldListener = dependentFieldListener;
}
@Override
public String getPreferenceKey() {
return KEY;
}
@Override
public boolean isAvailable() {
if (!super.isAvailable()) {
return false;
}
if (mChannel == null) {
return false;
}
if (isDefaultChannel()) {
return false;
}
return true;
}
@Override
public void updateState(Preference preference) {
if (mAppRow != null && mChannel != null) {
preference.setEnabled(mAdmin == null && !mChannel.isImportanceLockedByOEM());
RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference;
pref.setChecked(mChannel.getImportance() >= IMPORTANCE_DEFAULT);
}
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (mChannel != null) {
final boolean checked = (boolean) newValue;
mChannel.setImportance(checked ? IMPORTANCE_DEFAULT : IMPORTANCE_LOW);
mChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
saveChannel();
mDependentFieldListener.onFieldValueChanged();
}
return true;
}
}

View File

@@ -28,14 +28,14 @@ import com.android.settings.notification.NotificationBackend;
import java.util.Collections;
import java.util.List;
public class ImportantConversationsPreferenceController extends
public class PriorityConversationsPreferenceController extends
ConversationListPreferenceController {
private static final String KEY = "important_conversations";
private static final String LIST_KEY = "important_conversations_list";
private List<ConversationChannelWrapper> mConversations;
public ImportantConversationsPreferenceController(Context context,
public PriorityConversationsPreferenceController(Context context,
NotificationBackend backend) {
super(context, backend);
}

View File

@@ -1,19 +1,53 @@
package com.android.settings.notification.zen;
import android.app.Application;
import android.app.NotificationChannel;
import android.content.Context;
import android.os.UserHandle;
import android.icu.text.ListFormatter;
import android.provider.Settings;
import android.text.TextUtils;
import androidx.core.text.BidiFormatter;
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.notification.NotificationBackend;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.core.lifecycle.Lifecycle;
public class ZenModeBypassingAppsPreferenceController extends AbstractZenModePreferenceController {
import java.util.ArrayList;
import java.util.List;
/**
* Controls the summary for preference found at:
* Settings > Sound > Do Not Disturb > Apps
*/
public class ZenModeBypassingAppsPreferenceController extends AbstractZenModePreferenceController
implements PreferenceControllerMixin {
protected static final String KEY = "zen_mode_behavior_apps";
@VisibleForTesting protected Preference mPreference;
private ApplicationsState.Session mAppSession;
private NotificationBackend mNotificationBackend = new NotificationBackend();
public ZenModeBypassingAppsPreferenceController(Context context, Lifecycle lifecycle) {
private String mSummary;
public ZenModeBypassingAppsPreferenceController(Context context, Application app,
Fragment host, Lifecycle lifecycle) {
this(context, app == null ? null : ApplicationsState.getInstance(app), host, lifecycle);
}
private ZenModeBypassingAppsPreferenceController(Context context, ApplicationsState appState,
Fragment host, Lifecycle lifecycle) {
super(context, KEY, lifecycle);
if (appState != null && host != null) {
mAppSession = appState.newSession(mAppSessionCallbacks, host.getLifecycle());
}
}
@Override
@@ -22,13 +56,125 @@ public class ZenModeBypassingAppsPreferenceController extends AbstractZenModePre
}
@Override
public String getSummary() {
final int channelsBypassing =
mNotificationBackend.getNumAppsBypassingDnd(UserHandle.getCallingUserId());
if (channelsBypassing == 0) {
return mContext.getResources().getString(R.string.zen_mode_bypassing_apps_subtext_none);
}
return mContext.getResources().getQuantityString(R.plurals.zen_mode_bypassing_apps_subtext,
channelsBypassing, channelsBypassing);
public String getPreferenceKey() {
return KEY;
}
@Override
public void displayPreference(PreferenceScreen screen) {
mPreference = screen.findPreference(KEY);
updateAppsBypassingDndSummaryText();
super.displayPreference(screen);
}
@Override
public String getSummary() {
return mSummary;
}
private void updateAppsBypassingDndSummaryText() {
if (mAppSession == null) {
return;
}
ApplicationsState.AppFilter filter = ApplicationsState.FILTER_ALL_ENABLED;
List<ApplicationsState.AppEntry> apps = mAppSession.rebuild(filter,
ApplicationsState.ALPHA_COMPARATOR);
updateAppsBypassingDndSummaryText(apps);
}
@VisibleForTesting
void updateAppsBypassingDndSummaryText(List<ApplicationsState.AppEntry> apps) {
switch (getZenMode()) {
case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
case Settings.Global.ZEN_MODE_ALARMS:
// users cannot change their DND settings when an app puts the device total
// silence or alarms only (both deprecated) modes
mPreference.setEnabled(false);
mSummary = mContext.getResources().getString(
R.string.zen_mode_bypassing_apps_subtext_none);
return;
default:
mPreference.setEnabled(true);
}
if (apps == null) {
return;
}
List<String> appsBypassingDnd = new ArrayList<>();
for (ApplicationsState.AppEntry entry : apps) {
String pkg = entry.info.packageName;
for (NotificationChannel channel : mNotificationBackend
.getNotificationChannelsBypassingDnd(pkg, entry.info.uid).getList()) {
if (!TextUtils.isEmpty(channel.getConversationId())) {
// conversation channels that bypass dnd will be shown on the People page
continue;
}
appsBypassingDnd.add(BidiFormatter.getInstance().unicodeWrap(entry.label));
continue;
}
}
if (appsBypassingDnd.size() == 0) {
mSummary = mContext.getResources().getString(
R.string.zen_mode_bypassing_apps_subtext_none);
refreshSummary(mPreference);
return;
}
List<String> displayAppsBypassing = new ArrayList<>();
if (appsBypassingDnd.size() <= 2) {
displayAppsBypassing = appsBypassingDnd;
} else {
displayAppsBypassing.add(appsBypassingDnd.get(0));
displayAppsBypassing.add(appsBypassingDnd.get(1));
displayAppsBypassing.add(mContext.getResources().getString(
R.string.zen_mode_apps_bypassing_list_count,
appsBypassingDnd.size() - 2));
}
mSummary = mContext.getResources().getQuantityString(
R.plurals.zen_mode_bypassing_apps_subtext,
appsBypassingDnd.size(),
ListFormatter.getInstance().format(displayAppsBypassing));
refreshSummary(mPreference);
}
private final ApplicationsState.Callbacks mAppSessionCallbacks =
new ApplicationsState.Callbacks() {
@Override
public void onRunningStateChanged(boolean running) {
updateAppsBypassingDndSummaryText();
}
@Override
public void onPackageListChanged() {
updateAppsBypassingDndSummaryText();
}
@Override
public void onRebuildComplete(ArrayList<ApplicationsState.AppEntry> apps) {
updateAppsBypassingDndSummaryText(apps);
}
@Override
public void onPackageIconChanged() { }
@Override
public void onPackageSizeChanged(String packageName) {
updateAppsBypassingDndSummaryText();
}
@Override
public void onAllSizesComputed() { }
@Override
public void onLauncherInfoChanged() { }
@Override
public void onLoadEntriesCompleted() {
updateAppsBypassingDndSummaryText();
}
};
}

View File

@@ -16,25 +16,33 @@
package com.android.settings.notification.zen;
import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE;
import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_NONE;
import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_REPEAT_CALLERS;
import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_ANY;
import android.app.NotificationManager;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.lifecycle.Lifecycle;
/**
* Controls the summary for preference found at:
* Settings > Sound > Do Not Disturb > People
*/
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
@@ -60,8 +68,28 @@ public class ZenModePeoplePreferenceController extends
break;
default:
preference.setEnabled(true);
// TODO: How do all of the people options roll up into the summary?
//preference.setSummary(mSummaryBuilder.getMessagesSettingSummary(getPolicy()));
preference.setSummary(getPeopleSummary());
}
}
private String getPeopleSummary() {
final int callersAllowed = mBackend.getPriorityCallSenders();
final int messagesAllowed = mBackend.getPriorityMessageSenders();
final int conversationsAllowed = mBackend.getPriorityConversationSenders();
final boolean areRepeatCallersAllowed =
mBackend.isPriorityCategoryEnabled(PRIORITY_CATEGORY_REPEAT_CALLERS);
if (callersAllowed == PRIORITY_SENDERS_ANY
&& messagesAllowed == PRIORITY_SENDERS_ANY
&& conversationsAllowed == CONVERSATION_SENDERS_ANYONE) {
return mContext.getResources().getString(R.string.zen_mode_people_all);
} else if (callersAllowed == ZenModeBackend.SOURCE_NONE
&& messagesAllowed == ZenModeBackend.SOURCE_NONE
&& conversationsAllowed == CONVERSATION_SENDERS_NONE
&& !areRepeatCallersAllowed) {
return mContext.getResources().getString(R.string.zen_mode_people_none);
} else {
return mContext.getResources().getString(R.string.zen_mode_people_some);
}
}
}

View File

@@ -25,15 +25,19 @@ import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS
import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_REPEAT_CALLERS;
import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM;
import android.app.Activity;
import android.app.Application;
import android.app.AutomaticZenRule;
import android.app.NotificationManager;
import android.app.NotificationManager.Policy;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.icu.text.ListFormatter;
import android.provider.Settings;
import android.service.notification.ZenModeConfig;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import com.android.settings.R;
@@ -67,7 +71,9 @@ public class ZenModeSettings extends ZenModeSettingsBase {
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
return buildPreferenceControllers(context, getSettingsLifecycle(), getFragmentManager());
final Activity activity = getActivity();
return buildPreferenceControllers(context, getSettingsLifecycle(), getFragmentManager(),
activity != null ? activity.getApplication() : null, this);
}
@Override
@@ -76,15 +82,19 @@ public class ZenModeSettings extends ZenModeSettingsBase {
}
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
Lifecycle lifecycle, FragmentManager fragmentManager) {
Lifecycle lifecycle, FragmentManager fragmentManager, Application app,
Fragment fragment) {
List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new ZenModeButtonPreferenceController(context, lifecycle, fragmentManager));
controllers.add(new ZenModePeoplePreferenceController(context, lifecycle,
"zen_mode_behavior_people"));
controllers.add(new ZenModeBypassingAppsPreferenceController(context, lifecycle));
controllers.add(new ZenModeBlockedEffectsPreferenceController(context, lifecycle));
controllers.add(new ZenModeDurationPreferenceController(context, lifecycle));
controllers.add(new ZenModeBypassingAppsPreferenceController(context, app,
fragment, lifecycle));
controllers.add(new ZenModeSoundVibrationPreferenceController(context, lifecycle,
"zen_sound_vibration_settings"));
controllers.add(new ZenModeAutomationPreferenceController(context));
controllers.add(new ZenModeButtonPreferenceController(context, lifecycle, fragmentManager));
controllers.add(new ZenModeDurationPreferenceController(context, lifecycle));
controllers.add(new ZenModeBlockedEffectsPreferenceController(context, lifecycle));
controllers.add(new ZenModeSettingsFooterPreferenceController(context, lifecycle,
fragmentManager));
return controllers;
@@ -110,29 +120,34 @@ public class ZenModeSettings extends ZenModeSettingsBase {
PRIORITY_CATEGORY_REPEAT_CALLERS,
};
String getSoundSettingSummary(Policy policy) {
List<String> enabledCategories = getEnabledCategories(policy,
String getOtherSoundCategoriesSummary(Policy policy) {
List<String> enabledCategories = getEnabledCategories(
policy,
category -> PRIORITY_CATEGORY_ALARMS == category
|| PRIORITY_CATEGORY_MEDIA == category
|| PRIORITY_CATEGORY_SYSTEM == category, false);
|| PRIORITY_CATEGORY_SYSTEM == category
|| PRIORITY_CATEGORY_REMINDERS == category
|| PRIORITY_CATEGORY_EVENTS == category,
true);
int numCategories = enabledCategories.size();
if (numCategories == 0) {
return mContext.getString(R.string.zen_sound_all_muted);
} else if (numCategories == 1) {
return mContext.getString(R.string.zen_sound_one_allowed,
enabledCategories.get(0));
} else if (numCategories == 2) {
return mContext.getString(R.string.zen_sound_two_allowed,
enabledCategories.get(0),
enabledCategories.get(1));
} else if (numCategories == 3) {
return mContext.getString(R.string.zen_sound_three_allowed,
enabledCategories.get(0),
enabledCategories.get(1),
enabledCategories.get(2));
} else {
return mContext.getString(R.string.zen_sound_none_muted);
return mContext.getResources().getString(R.string.zen_mode_other_sounds_none);
}
List<String> displayCategories = new ArrayList<>();
if (numCategories <= 2) {
displayCategories = enabledCategories;
} else {
displayCategories.add(enabledCategories.get(0));
displayCategories.add(enabledCategories.get(1));
displayCategories.add(mContext.getString(R.string.zen_mode_other_sounds_list_count,
numCategories - 2));
}
return mContext.getResources().getQuantityString(
R.plurals.zen_mode_other_sounds_summary,
numCategories /* quantity */,
ListFormatter.getInstance().format(displayCategories));
}
String getCallsSettingSummary(Policy policy) {
@@ -322,7 +337,8 @@ public class ZenModeSettings extends ZenModeSettingsBase {
@Override
public List<AbstractPreferenceController> createPreferenceControllers(Context
context) {
return buildPreferenceControllers(context, null, null);
return buildPreferenceControllers(context, null, null,
null, null);
}
};
}

View File

@@ -0,0 +1,72 @@
/*
* 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.content.Context;
import android.provider.Settings;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.lifecycle.Lifecycle;
/**
* Controls the summary for preference found at:
* Settings > Sound > Do Not Disturb > Alarms & other interruptions
*/
public class ZenModeSoundVibrationPreferenceController extends
AbstractZenModePreferenceController implements PreferenceControllerMixin {
private final String mKey;
private final ZenModeSettings.SummaryBuilder mSummaryBuilder;
public ZenModeSoundVibrationPreferenceController(Context context, Lifecycle lifecycle,
String key) {
super(context, key, lifecycle);
mKey = key;
mSummaryBuilder = new ZenModeSettings.SummaryBuilder(context);
}
@Override
public String getPreferenceKey() {
return mKey;
}
@Override
public boolean isAvailable() {
return true;
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
switch (getZenMode()) {
case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
preference.setEnabled(false);
preference.setSummary(mContext.getString(R.string.zen_mode_other_sounds_none));
break;
case Settings.Global.ZEN_MODE_ALARMS:
preference.setEnabled(false);
preference.setSummary(mContext.getString(R.string.zen_mode_behavior_alarms_only));
break;
default:
preference.setEnabled(true);
preference.setSummary(mSummaryBuilder.getOtherSoundCategoriesSummary(getPolicy()));
}
}
}

View File

@@ -21,14 +21,17 @@ import android.content.Context;
import com.android.settings.R;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.search.Indexable;
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;
/**
* Settings > Sound > Do Not Disturb > Alarms & Other Interruptions
*/
@SearchIndexable
public class ZenModeSoundVibrationSettings extends ZenModeSettingsBase implements Indexable {
@@ -40,10 +43,6 @@ public class ZenModeSoundVibrationSettings extends ZenModeSettingsBase implement
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
Lifecycle lifecycle) {
List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new ZenModeCallsPreferenceController(context, lifecycle,
"zen_mode_calls_settings"));
controllers.add(new ZenModeMessagesPreferenceController(context, lifecycle,
"zen_mode_messages_settings"));
controllers.add(new ZenModeAlarmsPreferenceController(context, lifecycle,
"zen_mode_alarms"));
controllers.add(new ZenModeMediaPreferenceController(context, lifecycle));
@@ -52,7 +51,6 @@ public class ZenModeSoundVibrationSettings extends ZenModeSettingsBase implement
controllers.add(new ZenModeEventsPreferenceController(context, lifecycle));
controllers.add(new ZenModeBehaviorFooterPreferenceController(context, lifecycle,
R.string.zen_sound_footer));
controllers.add(new ZenModeBypassingAppsPreferenceController(context, lifecycle));
return controllers;
}

View File

@@ -67,10 +67,14 @@ public class BrightnessLevelPreferenceControllerTest {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mContentResolver = mContext.getContentResolver();
when(mPowerManager.getMinimumScreenBrightnessSetting()).thenReturn(0);
when(mPowerManager.getMaximumScreenBrightnessSetting()).thenReturn(100);
when(mPowerManager.getMinimumScreenBrightnessForVrSetting()).thenReturn(0);
when(mPowerManager.getMaximumScreenBrightnessForVrSetting()).thenReturn(100);
when(mPowerManager.getBrightnessConstraint(
PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM)).thenReturn(0.0f);
when(mPowerManager.getBrightnessConstraint(
PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM)).thenReturn(1.0f);
when(mPowerManager.getBrightnessConstraint(
PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM_VR)).thenReturn(0.0f);
when(mPowerManager.getBrightnessConstraint(
PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM_VR)).thenReturn(1.0f);
ShadowApplication.getInstance().setSystemService(POWER_SERVICE,
mPowerManager);
when(mScreen.findPreference(anyString())).thenReturn(mPreference);
@@ -98,7 +102,7 @@ public class BrightnessLevelPreferenceControllerTest {
controller.onStart();
assertThat(shadowContentResolver.getContentObservers(
System.getUriFor(System.SCREEN_BRIGHTNESS))).isNotEmpty();
System.getUriFor(System.SCREEN_BRIGHTNESS_FLOAT))).isNotEmpty();
assertThat(shadowContentResolver.getContentObservers(
System.getUriFor(System.SCREEN_BRIGHTNESS_FOR_VR))).isNotEmpty();
assertThat(shadowContentResolver.getContentObservers(
@@ -116,9 +120,9 @@ public class BrightnessLevelPreferenceControllerTest {
controller.onStop();
assertThat(shadowContentResolver.getContentObservers(
System.getUriFor(System.SCREEN_BRIGHTNESS))).isEmpty();
System.getUriFor(System.SCREEN_BRIGHTNESS_FLOAT))).isEmpty();
assertThat(shadowContentResolver.getContentObservers(
System.getUriFor(System.SCREEN_BRIGHTNESS_FOR_VR))).isEmpty();
System.getUriFor(System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT))).isEmpty();
assertThat(shadowContentResolver.getContentObservers(
System.getUriFor(System.SCREEN_AUTO_BRIGHTNESS_ADJ))).isEmpty();
}
@@ -126,11 +130,11 @@ public class BrightnessLevelPreferenceControllerTest {
@Test
public void updateState_inVrMode_shouldSetSummaryToVrBrightness() {
doReturn(true).when(mController).isInVrMode();
System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS_FOR_VR, 85);
System.putFloat(mContentResolver, System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT, 0.6f);
mController.updateState(mPreference);
verify(mPreference).setSummary("97%");
verify(mPreference).setSummary("91%");
}
@Test
@@ -139,11 +143,11 @@ public class BrightnessLevelPreferenceControllerTest {
System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS_MODE,
System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS, 31);
System.putFloat(mContentResolver, System.SCREEN_BRIGHTNESS_FLOAT, 0.1f);
mController.updateState(mPreference);
verify(mPreference).setSummary("78%");
verify(mPreference).setSummary("54%");
}
@Test
@@ -152,11 +156,11 @@ public class BrightnessLevelPreferenceControllerTest {
System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS_MODE,
System.SCREEN_BRIGHTNESS_MODE_MANUAL);
System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS, 45);
System.putFloat(mContentResolver, System.SCREEN_BRIGHTNESS_FLOAT, 0.5f);
mController.updateState(mPreference);
verify(mPreference).setSummary("85%");
verify(mPreference).setSummary("87%");
}
@Test
@@ -164,11 +168,11 @@ public class BrightnessLevelPreferenceControllerTest {
// VR mode
doReturn(true).when(mController).isInVrMode();
System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS_FOR_VR, 105);
System.putFloat(mContentResolver, System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT, 1.05f);
mController.updateState(mPreference);
verify(mPreference).setSummary("100%");
System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS_FOR_VR, -20);
System.putFloat(mContentResolver, System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT, -20f);
mController.updateState(mPreference);
verify(mPreference).setSummary("0%");
@@ -178,11 +182,11 @@ public class BrightnessLevelPreferenceControllerTest {
System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
reset(mPreference);
System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS, 115);
System.putFloat(mContentResolver, System.SCREEN_BRIGHTNESS_FLOAT, 1.15f);
mController.updateState(mPreference);
verify(mPreference).setSummary("100%");
System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS, -10);
System.putFloat(mContentResolver, System.SCREEN_BRIGHTNESS_FLOAT, -10f);
mController.updateState(mPreference);
verify(mPreference).setSummary("0%");
@@ -191,11 +195,11 @@ public class BrightnessLevelPreferenceControllerTest {
System.SCREEN_BRIGHTNESS_MODE_MANUAL);
reset(mPreference);
System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS, 115);
System.putFloat(mContentResolver, System.SCREEN_BRIGHTNESS_FLOAT, 1.15f);
mController.updateState(mPreference);
verify(mPreference).setSummary("100%");
System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS, -10);
System.putFloat(mContentResolver, System.SCREEN_BRIGHTNESS_FLOAT, -10f);
mController.updateState(mPreference);
verify(mPreference).setSummary("0%");
}

View File

@@ -19,10 +19,6 @@ package com.android.settings.network.ims;
import android.content.Context;
import android.telephony.ims.ImsException;
import com.android.ims.ImsManager;
/**
* Controller class for mock VoLte status
*/
@@ -31,6 +27,7 @@ public class MockVolteQueryImsState extends VolteQueryImsState {
private Boolean mIsTtyOnVolteEnabled;
private Boolean mIsSupported;
private Boolean mIsProvisionedOnDevice;
private Boolean mIsServiceStateReady;
private Boolean mIsEnabledByUser;
/**
@@ -43,10 +40,6 @@ public class MockVolteQueryImsState extends VolteQueryImsState {
super(context, subId);
}
public ImsManager getImsManager(int subId) {
return super.getImsManager(subId);
}
public void setIsTtyOnVolteEnabled(boolean enabled) {
mIsTtyOnVolteEnabled = enabled;
}
@@ -84,6 +77,19 @@ public class MockVolteQueryImsState extends VolteQueryImsState {
return super.isProvisionedOnDevice(subId);
}
public void setServiceStateReady(boolean isReady) {
mIsServiceStateReady = isReady;
}
@Override
boolean isServiceStateReady(int subId) throws InterruptedException, ImsException,
IllegalArgumentException {
if (mIsServiceStateReady != null) {
return mIsServiceStateReady;
}
return super.isServiceStateReady(subId);
}
public void setIsEnabledByUser(boolean enabled) {
mIsEnabledByUser = enabled;
}

View File

@@ -28,12 +28,9 @@ import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.ims.ProvisioningManager;
import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import androidx.preference.SwitchPreference;
import com.android.ims.ImsManager;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.network.ims.MockVolteQueryImsState;
import com.android.settingslib.RestrictedSwitchPreference;
@@ -59,8 +56,6 @@ public class Enhanced4gBasePreferenceControllerTest {
@Mock
private CarrierConfigManager mCarrierConfigManager;
@Mock
private ImsManager mImsManager;
@Mock
private ProvisioningManager mProvisioningManager;
private MockVolteQueryImsState mQueryImsState;
@@ -86,9 +81,10 @@ public class Enhanced4gBasePreferenceControllerTest {
doReturn(mCarrierConfig).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
mQueryImsState = spy(new MockVolteQueryImsState(mContext, SUB_ID));
doReturn(mImsManager).when(mQueryImsState).getImsManager(anyInt());
mQueryImsState.setEnabledByPlatform(true);
mQueryImsState.setIsProvisionedOnDevice(true);
mQueryImsState.setIsTtyOnVolteEnabled(true);
mQueryImsState.setServiceStateReady(true);
mQueryImsState.setIsEnabledByUser(true);
mPreference = new RestrictedSwitchPreference(mContext);
@@ -100,6 +96,9 @@ public class Enhanced4gBasePreferenceControllerTest {
@Test
public void getAvailabilityStatus_default_returnUnavailable() {
mQueryImsState.setEnabledByPlatform(false);
mQueryImsState.setIsProvisionedOnDevice(false);
mController.init(SUB_ID);
assertThat(mController.getAvailabilityStatus()).isEqualTo(
@@ -109,9 +108,6 @@ public class Enhanced4gBasePreferenceControllerTest {
@Test
public void getAvailabilityStatus_volteDisabled_returnUnavailable() {
mQueryImsState.setEnabledByPlatform(false);
doReturn(true).when(mProvisioningManager).getProvisioningStatusForCapability(
MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
@@ -123,7 +119,6 @@ public class Enhanced4gBasePreferenceControllerTest {
mPreference.setEnabled(false);
mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 1);
mController.mCallState = TelephonyManager.CALL_STATE_IDLE;
doReturn(true).when(mImsManager).isNonTtyOrTtyOnVolteEnabled();
mCarrierConfig.putBoolean(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, true);
mController.updateState(mPreference);
@@ -135,8 +130,6 @@ public class Enhanced4gBasePreferenceControllerTest {
public void updateState_configOn_prefChecked() {
mQueryImsState.setIsEnabledByUser(true);
mPreference.setChecked(false);
doReturn(true).when(mImsManager).isEnhanced4gLteModeSettingEnabledByUser();
doReturn(true).when(mImsManager).isNonTtyOrTtyOnVolteEnabled();
mController.updateState(mPreference);

View File

@@ -43,7 +43,6 @@ import androidx.slice.core.SliceAction;
import androidx.slice.core.SliceQuery;
import androidx.slice.widget.SliceLiveData;
import com.android.ims.ImsManager;
import com.android.settings.R;
import com.android.settings.network.ims.MockVolteQueryImsState;
import com.android.settings.slices.CustomSliceRegistry;
@@ -73,8 +72,6 @@ public class Enhanced4gLteSliceHelperTest {
@Mock
private CarrierConfigManager mMockCarrierConfigManager;
@Mock
private ImsManager mMockImsManager;
@Mock
private ProvisioningManager mProvisioningManager;
@@ -109,9 +106,10 @@ public class Enhanced4gLteSliceHelperTest {
mReceiver = spy(new SliceBroadcastReceiver());
mQueryImsState = spy(new MockVolteQueryImsState(mContext, SUB_ID));
doReturn(mMockImsManager).when(mQueryImsState).getImsManager(anyInt());
mQueryImsState.setEnabledByPlatform(true);
mQueryImsState.setIsProvisionedOnDevice(true);
mQueryImsState.setIsTtyOnVolteEnabled(true);
mQueryImsState.setServiceStateReady(true);
mQueryImsState.setIsEnabledByUser(true);
mEnhanced4gLteSliceHelper = spy(new FakeEnhanced4gLteSliceHelper(mContext));
@@ -149,7 +147,6 @@ public class Enhanced4gLteSliceHelperTest {
public void test_CreateEnhanced4gLteSlice_success() {
mQueryImsState.setEnabledByPlatform(true);
mQueryImsState.setIsProvisionedOnDevice(true);
when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
when(mMockCarrierConfigManager.getConfigForSubId(1)).thenReturn(null);
final Slice slice = mEnhanced4gLteSliceHelper.createEnhanced4gLteSlice(
@@ -163,7 +160,6 @@ public class Enhanced4gLteSliceHelperTest {
public void test_SettingSliceProvider_getsRightSliceEnhanced4gLte() {
mQueryImsState.setEnabledByPlatform(true);
mQueryImsState.setIsProvisionedOnDevice(true);
when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
when(mMockCarrierConfigManager.getConfigForSubId(1)).thenReturn(null);
when(mSlicesFeatureProvider.getNewEnhanced4gLteSliceHelper(mContext))
.thenReturn(mEnhanced4gLteSliceHelper);
@@ -180,7 +176,6 @@ public class Enhanced4gLteSliceHelperTest {
mQueryImsState.setEnabledByPlatform(true);
mQueryImsState.setIsProvisionedOnDevice(true);
mQueryImsState.setIsEnabledByUser(false);
when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
when(mSlicesFeatureProvider.getNewEnhanced4gLteSliceHelper(mContext))
.thenReturn(mEnhanced4gLteSliceHelper);
@@ -194,7 +189,7 @@ public class Enhanced4gLteSliceHelperTest {
// change the setting
mReceiver.onReceive(mContext, intent);
verify((mMockImsManager)).setEnhanced4gLteModeSetting(
verify(mEnhanced4gLteSliceHelper).setEnhanced4gLteModeSetting(anyInt(),
mEnhanced4gLteSettingCaptor.capture());
// assert the change

View File

@@ -122,7 +122,7 @@ public class BubblePreferenceControllerTest {
}
@Test
public void testIsAvailable_channel_notIfAppOff() {
public void testIsAvailable_channel_yesIfAppOff() {
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.allowBubbles = false;
@@ -130,7 +130,7 @@ public class BubblePreferenceControllerTest {
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null, null, null);
assertFalse(mController.isAvailable());
assertTrue(mController.isAvailable());
}
@Test
@@ -199,18 +199,6 @@ public class BubblePreferenceControllerTest {
assertTrue(mController.isAvailable());
}
@Test
public void testIsAvailable_channelAppOff() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.allowBubbles = false;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null, null, null);
Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
assertFalse(mController.isAvailable());
}
@Test
public void testUpdateState_disabledByAdmin() {
NotificationChannel channel = mock(NotificationChannel.class);

View File

@@ -1,206 +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.app;
import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.provider.Settings.Secure.BUBBLE_IMPORTANT_CONVERSATIONS;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.os.UserManager;
import android.provider.Settings;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.notification.NotificationBackend;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedSwitchPreference;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication;
@RunWith(RobolectricTestRunner.class)
public class ConversationImportantPreferenceControllerTest {
private Context mContext;
@Mock
private NotificationBackend mBackend;
@Mock
private NotificationManager mNm;
@Mock
private UserManager mUm;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private PreferenceScreen mScreen;
@Mock
private NotificationSettings.DependentFieldListener mDependentFieldListener;
private ConversationImportantPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
mContext = RuntimeEnvironment.application;
mController = spy(new ConversationImportantPreferenceController(
mContext, mBackend, mDependentFieldListener));
}
@Test
public void testNoCrashIfNoOnResume() {
mController.isAvailable();
mController.updateState(mock(Preference.class));
mController.onPreferenceChange(mock(Preference.class), true);
}
@Test
public void testIsAvailable_notChannelNull() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
mController.onResume(appRow, null, null, null, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
mController.onResume(appRow, channel, null, null, null, null);
assertTrue(mController.isAvailable());
}
@Test
public void testUpdateState_disabledByAdmin() {
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn("something");
mController.onResume(new NotificationBackend.AppRow(), channel, null, null, null, mock(
RestrictedLockUtils.EnforcedAdmin.class));
Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertFalse(pref.isEnabled());
}
@Test
public void testUpdateState() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
channel.setImportantConversation(true);
mController.onResume(appRow, channel, null, null, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertTrue(pref.isChecked());
channel.setImportantConversation(false);
mController.onResume(appRow, channel, null, null, null, null);
mController.updateState(pref);
assertFalse(pref.isChecked());
}
@Test
public void testOnPreferenceChange_on() {
Settings.Secure.putInt(mContext.getContentResolver(),
BUBBLE_IMPORTANT_CONVERSATIONS, 0);
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_DEFAULT);
channel.setImportantConversation(false);
channel.setAllowBubbles(false);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
mController.onPreferenceChange(pref, true);
assertTrue(channel.isImportantConversation());
assertFalse(channel.canBubble());
verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
verify(mDependentFieldListener, times(1)).onFieldValueChanged();
}
@Test
public void testOnPreferenceChange_on_bubble() {
Settings.Secure.putInt(mContext.getContentResolver(),
BUBBLE_IMPORTANT_CONVERSATIONS, 1);
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_DEFAULT);
channel.setImportantConversation(false);
channel.setAllowBubbles(false);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
mController.onPreferenceChange(pref, true);
assertTrue(channel.isImportantConversation());
assertTrue(channel.canBubble());
verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
verify(mDependentFieldListener).onFieldValueChanged();
}
@Test
public void testOnPreferenceChange_off() {
Settings.Secure.putInt(mContext.getContentResolver(),
BUBBLE_IMPORTANT_CONVERSATIONS, 1);
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH);
channel.setImportantConversation(true);
channel.setAllowBubbles(false);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
mController.onPreferenceChange(pref, false);
assertFalse(channel.isImportantConversation());
assertFalse(channel.canBubble());
verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
verify(mDependentFieldListener, times(1)).onFieldValueChanged();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2017 The Android Open Source Project
* 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.
@@ -20,28 +20,32 @@ import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.os.UserManager;
import android.util.Pair;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.notification.NotificationBackend;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedSwitchPreference;
import org.junit.Before;
import org.junit.Test;
@@ -54,21 +58,21 @@ import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication;
@RunWith(RobolectricTestRunner.class)
public class DefaultImportancePreferenceControllerTest {
public class ConversationPriorityPreferenceControllerTest {
private Context mContext;
@Mock
private NotificationManager mNm;
@Mock
private NotificationBackend mBackend;
@Mock
private NotificationSettings.DependentFieldListener mDependentFieldListener;
private NotificationManager mNm;
@Mock
private UserManager mUm;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private PreferenceScreen mScreen;
@Mock
private NotificationSettings.DependentFieldListener mDependentFieldListener;
private DefaultImportancePreferenceController mController;
private ConversationPriorityPreferenceController mController;
@Before
public void setUp() {
@@ -77,54 +81,28 @@ public class DefaultImportancePreferenceControllerTest {
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
mContext = RuntimeEnvironment.application;
mController = spy(new DefaultImportancePreferenceController(
mContext, mDependentFieldListener, mBackend));
mController = spy(new ConversationPriorityPreferenceController(
mContext, mBackend, mDependentFieldListener));
}
@Test
public void testNoCrashIfNoOnResume() {
mController.isAvailable();
mController.updateState(mock(Preference.class));
mController.onPreferenceChange(mock(Preference.class), true);
}
@Test
public void testIsAvailable_notIfNull() {
mController.onResume(null, null, null, null, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_ifAppBlocked() {
public void testIsAvailable_notChannelNull() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.banned = true;
mController.onResume(appRow, mock(NotificationChannel.class), null, null, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfChannelBlocked() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
mController.onResume(appRow, channel, null, null, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notForDefaultChannel() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID);
mController.onResume(appRow, channel, null, null, null, null);
mController.onResume(appRow, null, null, null, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_DEFAULT);
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
mController.onResume(appRow, channel, null, null, null, null);
assertTrue(mController.isAvailable());
}
@@ -136,7 +114,7 @@ public class DefaultImportancePreferenceControllerTest {
mController.onResume(new NotificationBackend.AppRow(), channel, null, null, null, mock(
RestrictedLockUtils.EnforcedAdmin.class));
Preference pref = new RestrictedSwitchPreference(mContext, null);
Preference pref = new ConversationPriorityPreference(mContext, null);
mController.updateState(pref);
assertFalse(pref.isEnabled());
@@ -150,7 +128,7 @@ public class DefaultImportancePreferenceControllerTest {
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null, null, null);
Preference pref = new RestrictedSwitchPreference(mContext, null);
Preference pref = new ConversationPriorityPreference(mContext, null);
mController.updateState(pref);
assertFalse(pref.isEnabled());
@@ -165,7 +143,7 @@ public class DefaultImportancePreferenceControllerTest {
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null, null, null);
Preference pref = new RestrictedSwitchPreference(mContext, null);
Preference pref = new ConversationPriorityPreference(mContext, null);
mController.updateState(pref);
assertTrue(pref.isEnabled());
@@ -180,67 +158,120 @@ public class DefaultImportancePreferenceControllerTest {
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null, null, null);
Preference pref = new RestrictedSwitchPreference(mContext, null);
Preference pref = new ConversationPriorityPreference(mContext, null);
mController.updateState(pref);
assertTrue(pref.isEnabled());
}
@Test
public void testUpdateState_default() {
public void testUpdateState() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
channel.setImportantConversation(true);
channel.setOriginalImportance(IMPORTANCE_DEFAULT);
mController.onResume(appRow, channel, null, null, null, null);
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
ConversationPriorityPreference pref = mock(ConversationPriorityPreference.class);
mController.updateState(pref);
assertTrue(pref.isChecked());
verify(pref, times(1)).setConfigurable(anyBoolean());
verify(pref, times(1)).setImportance(IMPORTANCE_HIGH);
verify(pref, times(1)).setOriginalImportance(IMPORTANCE_DEFAULT);
verify(pref, times(1)).setPriorityConversation(true);
}
@Test
public void testUpdateState_low() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_LOW);
mController.onResume(appRow, channel, null, null, null, null);
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
mController.updateState(pref);
assertFalse(pref.isChecked());
}
@Test
public void onPreferenceChange_onToOff() {
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null, null, null);
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext, null);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
mController.onPreferenceChange(pref, false);
assertEquals(IMPORTANCE_LOW, channel.getImportance());
verify(mDependentFieldListener, times(1)).onFieldValueChanged();
}
@Test
public void onPreferenceChange_offToOn() {
public void testImportanceLowToImportant() {
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_LOW);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null, null, null);
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext, null);
ConversationPriorityPreference pref = new ConversationPriorityPreference(mContext, null);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
mController.onPreferenceChange(pref, true);
mController.onPreferenceChange(pref, new Pair(IMPORTANCE_HIGH, true));
assertEquals(IMPORTANCE_HIGH, channel.getImportance());
assertTrue(channel.canBubble());
assertTrue(channel.isImportantConversation());
}
@Test
public void testImportanceLowToDefault() {
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_LOW);
channel.setAllowBubbles(false);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null, null, null);
ConversationPriorityPreference pref = new ConversationPriorityPreference(mContext, null);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
mController.onPreferenceChange(pref, new Pair(IMPORTANCE_HIGH, false));
assertEquals(IMPORTANCE_HIGH, channel.getImportance());
assertFalse(channel.canBubble());
assertFalse(channel.isImportantConversation());
}
@Test
public void testImportanceDefaultToLow() {
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_DEFAULT);
channel.setAllowBubbles(false);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null, null, null);
ConversationPriorityPreference pref = new ConversationPriorityPreference(mContext, null);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
mController.onPreferenceChange(pref, new Pair(IMPORTANCE_LOW, false));
assertEquals(IMPORTANCE_LOW, channel.getImportance());
assertFalse(channel.canBubble());
assertFalse(channel.isImportantConversation());
}
@Test
public void testImportanceLowToDefault_bubblesMaintained() {
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_LOW);
channel.setAllowBubbles(true);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null, null, null);
ConversationPriorityPreference pref = new ConversationPriorityPreference(mContext, null);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
mController.onPreferenceChange(pref, new Pair(IMPORTANCE_DEFAULT, false));
assertEquals(IMPORTANCE_DEFAULT, channel.getImportance());
verify(mDependentFieldListener, times(1)).onFieldValueChanged();
assertTrue(channel.canBubble());
assertFalse(channel.isImportantConversation());
}
@Test
public void testImportancePriorityToDefault() {
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH);
channel.setAllowBubbles(true);
channel.setImportantConversation(true);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null, null, null);
ConversationPriorityPreference pref = new ConversationPriorityPreference(mContext, null);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
mController.onPreferenceChange(pref, new Pair(IMPORTANCE_HIGH, false));
assertEquals(IMPORTANCE_HIGH, channel.getImportance());
assertFalse(channel.canBubble());
assertFalse(channel.isImportantConversation());
}
}

View File

@@ -0,0 +1,172 @@
/*
* 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.app;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import androidx.preference.PreferenceViewHolder;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class ConversationPriorityPreferenceTest {
private Context mContext;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
}
@Test
public void createNewPreference_shouldSetLayout() {
final ConversationPriorityPreference preference =
new ConversationPriorityPreference(mContext);
assertThat(preference.getLayoutResource()).isEqualTo(
R.layout.notif_priority_conversation_preference);
}
@Test
public void onBindViewHolder_nonConfigurable() {
final ConversationPriorityPreference preference =
new ConversationPriorityPreference(mContext);
final LayoutInflater inflater = LayoutInflater.from(mContext);
PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
inflater.inflate(preference.getLayoutResource(), null));
Drawable unselected = mock(Drawable.class);
Drawable selected = mock(Drawable.class);
preference.selectedBackground = selected;
preference.unselectedBackground = unselected;
preference.setConfigurable(false);
preference.setImportance(IMPORTANCE_DEFAULT);
preference.setPriorityConversation(true);
preference.onBindViewHolder(holder);
assertThat(holder.itemView.findViewById(R.id.silence).isEnabled()).isFalse();
assertThat(holder.itemView.findViewById(R.id.priority_group).isEnabled()).isFalse();
assertThat(holder.itemView.findViewById(R.id.alert).isEnabled()).isFalse();
assertThat(holder.itemView.findViewById(R.id.priority_group).getBackground())
.isEqualTo(selected);
assertThat(holder.itemView.findViewById(R.id.alert).getBackground()).isEqualTo(unselected);
assertThat(holder.itemView.findViewById(R.id.silence).getBackground())
.isEqualTo(unselected);
// other button
preference.setPriorityConversation(false);
holder = PreferenceViewHolder.createInstanceForTests(
inflater.inflate(preference.getLayoutResource(), null));
preference.onBindViewHolder(holder);
assertThat(holder.itemView.findViewById(R.id.alert).getBackground()).isEqualTo(selected);
assertThat(holder.itemView.findViewById(R.id.silence).getBackground())
.isEqualTo(unselected);
assertThat(holder.itemView.findViewById(R.id.priority_group).getBackground())
.isEqualTo(unselected);
// other other button
preference.setImportance(IMPORTANCE_LOW);
holder = PreferenceViewHolder.createInstanceForTests(
inflater.inflate(preference.getLayoutResource(), null));
preference.onBindViewHolder(holder);
assertThat(holder.itemView.findViewById(R.id.priority_group).getBackground())
.isEqualTo(unselected);
assertThat(holder.itemView.findViewById(R.id.alert).getBackground()).isEqualTo(unselected);
assertThat(holder.itemView.findViewById(R.id.silence).getBackground()).isEqualTo(selected);
}
@Test
public void onBindViewHolder_selectButtonAndText() {
final ConversationPriorityPreference preference =
new ConversationPriorityPreference(mContext);
final LayoutInflater inflater = LayoutInflater.from(mContext);
final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
inflater.inflate(preference.getLayoutResource(), null));
Drawable unselected = mock(Drawable.class);
Drawable selected = mock(Drawable.class);
preference.selectedBackground = selected;
preference.unselectedBackground = unselected;
preference.setConfigurable(true);
preference.setImportance(IMPORTANCE_LOW);
preference.setPriorityConversation(true);
preference.onBindViewHolder(holder);
assertThat(holder.itemView.findViewById(R.id.priority_group).getBackground())
.isEqualTo(unselected);
assertThat(holder.itemView.findViewById(R.id.alert).getBackground()).isEqualTo(unselected);
assertThat(holder.itemView.findViewById(R.id.silence).getBackground())
.isEqualTo(selected);
assertThat(holder.itemView.findViewById(R.id.silence_summary).getVisibility())
.isEqualTo(View.VISIBLE);
}
@Test
public void onClick_changesUICallsListener() {
final ConversationPriorityPreference preference =
spy(new ConversationPriorityPreference(mContext));
final LayoutInflater inflater = LayoutInflater.from(mContext);
final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
inflater.inflate(preference.getLayoutResource(), null));
Drawable unselected = mock(Drawable.class);
Drawable selected = mock(Drawable.class);
preference.selectedBackground = selected;
preference.unselectedBackground = unselected;
preference.setConfigurable(true);
preference.setImportance(IMPORTANCE_DEFAULT);
preference.setPriorityConversation(true);
preference.setOriginalImportance(IMPORTANCE_DEFAULT);
preference.onBindViewHolder(holder);
View silenceButton = holder.itemView.findViewById(R.id.silence);
silenceButton.callOnClick();
assertThat(holder.itemView.findViewById(R.id.alert).getBackground()).isEqualTo(unselected);
assertThat(holder.itemView.findViewById(R.id.priority_group).getBackground())
.isEqualTo(unselected);
assertThat(holder.itemView.findViewById(R.id.silence).getBackground())
.isEqualTo(selected);
verify(preference, times(1)).callChangeListener(new Pair(IMPORTANCE_LOW, false));
}
}

View File

@@ -18,16 +18,23 @@ package com.android.settings.notification.zen;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.app.NotificationChannel;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.ParceledListSlice;
import android.provider.Settings;
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
import com.android.settings.notification.NotificationBackend;
import com.android.settings.notification.zen.ZenModeBypassingAppsPreferenceController;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -37,6 +44,9 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class ZenModeBypassingAppsPreferenceControllerTest {
@@ -45,30 +55,156 @@ public class ZenModeBypassingAppsPreferenceControllerTest {
private Context mContext;
@Mock
private NotificationBackend mBackend;
private int mPreviousZenSetting;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mController = new ZenModeBypassingAppsPreferenceController(mContext, mock(Lifecycle.class));
mController = new ZenModeBypassingAppsPreferenceController(
mContext, null, mock(Fragment.class), mock(Lifecycle.class));
mController.mPreference = new Preference(mContext);
mPreviousZenSetting =
Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.ZEN_MODE,
Settings.Global.ZEN_MODE_OFF);
ReflectionHelpers.setField(mController, "mNotificationBackend", mBackend);
}
@After
public void tearDown() {
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.ZEN_MODE,
mPreviousZenSetting);
}
@Test
public void testIsAvailable() {
when(mBackend.getNumAppsBypassingDnd(anyInt())).thenReturn(5);
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void testNotAvailable() {
when(mBackend.getNumAppsBypassingDnd(anyInt())).thenReturn(0);
assertThat(mController.isAvailable()).isFalse();
public void testUpdateBypassingApps() {
// GIVEN DND is off
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.ZEN_MODE,
Settings.Global.ZEN_MODE_OFF);
// mock app list
ApplicationsState.AppEntry entry = mock(ApplicationsState.AppEntry.class);
entry.info = new ApplicationInfo();
entry.info.packageName = "test";
entry.label = "test";
entry.info.uid = 0;
List<ApplicationsState.AppEntry> appEntries = new ArrayList<>();
appEntries.add(entry);
List<NotificationChannel> channelsBypassing = new ArrayList<>();
channelsBypassing.add(mock(NotificationChannel.class));
when(mBackend.getNotificationChannelsBypassingDnd(entry.info.packageName,
entry.info.uid)).thenReturn(new ParceledListSlice<>(channelsBypassing));
// WHEN a single app is passed to the controller
mController.updateAppsBypassingDndSummaryText(appEntries);
// THEN the preference is enabled and the summary contains the app name from the list
assertThat(mController.mPreference.isEnabled()).isTrue();
assertThat(mController.getSummary().contains(entry.label)).isTrue();
}
@Test
public void testHasSummary() {
assertThat(mController.getSummary()).isNotNull();
public void testUpdateBypassingApps_multipleApps() {
// GIVEN DND is off
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.ZEN_MODE,
Settings.Global.ZEN_MODE_OFF);
// mock app list
ApplicationsState.AppEntry entry1 = mock(ApplicationsState.AppEntry.class);
entry1.info = new ApplicationInfo();
entry1.info.packageName = "test1";
entry1.label = "test1";
entry1.info.uid = 1;
ApplicationsState.AppEntry entry2 = mock(ApplicationsState.AppEntry.class);
entry2.info = new ApplicationInfo();
entry2.info.packageName = "test2";
entry2.label = "test2";
entry2.info.uid = 2;
List<ApplicationsState.AppEntry> appEntries = new ArrayList<>();
appEntries.add(entry1);
appEntries.add(entry2);
List<NotificationChannel> channelsBypassing = new ArrayList<>();
channelsBypassing.add(mock(NotificationChannel.class));
when(mBackend.getNotificationChannelsBypassingDnd(entry1.info.packageName,
entry1.info.uid)).thenReturn(new ParceledListSlice<>(channelsBypassing));
when(mBackend.getNotificationChannelsBypassingDnd(entry2.info.packageName,
entry2.info.uid)).thenReturn(new ParceledListSlice<>(channelsBypassing));
// WHEN a list of apps is passed to the controller
mController.updateAppsBypassingDndSummaryText(appEntries);
// THEN the preference is enabled and the summary contains the app names from the list
assertThat(mController.mPreference.isEnabled()).isTrue();
assertThat(mController.getSummary().contains(entry1.label)).isTrue();
assertThat(mController.getSummary().contains(entry2.label)).isTrue();
}
@Test
public void testUpdateAppsBypassingDnd_nullAppsList() {
// GIVEN DND is off
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.ZEN_MODE,
Settings.Global.ZEN_MODE_OFF);
// WHEN the list of apps is null
mController.updateAppsBypassingDndSummaryText(null);
// THEN the preference is enabled and summary is unchanged (in this case, null)
assertThat(mController.mPreference.isEnabled()).isTrue();
assertThat(mController.getSummary()).isNull();
}
@Test
public void testUpdateAppsBypassingDnd_emptyAppsList() {
// GIVEN the DND is off
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.ZEN_MODE,
Settings.Global.ZEN_MODE_OFF);
// WHEN the list of apps is an empty list
mController.updateAppsBypassingDndSummaryText(new ArrayList<>());
// THEN the preference is enabled and summary is updated
assertThat(mController.mPreference.isEnabled()).isTrue();
assertThat(mController.getSummary().contains("No apps")).isTrue();
}
@Test
public void testUpdateAppsBypassingDnd_alarmsOnly() {
// GIVEN alarms only DND mode
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.ZEN_MODE,
Settings.Global.ZEN_MODE_ALARMS);
// mock app entries
ApplicationsState.AppEntry entry = mock(ApplicationsState.AppEntry.class);
entry.info = new ApplicationInfo();
entry.info.packageName = "test";
entry.label = "test";
entry.info.uid = 0;
List<ApplicationsState.AppEntry> appEntries = new ArrayList<>();
appEntries.add(entry);
List<NotificationChannel> channelsBypassing = new ArrayList<>();
channelsBypassing.add(mock(NotificationChannel.class));
when(mBackend.getNotificationChannelsBypassingDnd(entry.info.packageName,
entry.info.uid)).thenReturn(new ParceledListSlice<>(channelsBypassing));
// WHEN we update apps bypassing dnd summary text
mController.updateAppsBypassingDndSummaryText(appEntries);
// THEN the preference is disabled and the summary says no apps can bypass
assertThat(mController.mPreference.isEnabled()).isFalse();
assertThat(mController.getSummary().contains("No apps")).isTrue();
}
}

View File

@@ -97,34 +97,6 @@ public class ZenModeSettingsTest {
.isEqualTo("Allow from starred contacts and repeat callers");
}
@Test
public void testGetSoundSettingSummary_allOff() {
Policy policy = new Policy(0, 0, 0, 0);
assertThat(mBuilder.getSoundSettingSummary(policy)).isEqualTo("Muted");
}
@Test
public void testGetSoundSettingSummary_allOn() {
Policy policy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS | Policy.PRIORITY_CATEGORY_SYSTEM
| Policy.PRIORITY_CATEGORY_MEDIA, 0, 0, 0);
assertThat(mBuilder.getSoundSettingSummary(policy))
.isEqualTo("Muted, but allow alarms, media, and touch sounds");
}
@Test
public void testGetSoundSettingSummary_allOffButOne() {
Policy policy = new Policy(Policy.PRIORITY_CATEGORY_MEDIA, 0, 0, 0);
assertThat(mBuilder.getSoundSettingSummary(policy)).isEqualTo("Muted, but allow media");
}
@Test
public void testGetSoundSettingSummary_allOffButTwo() {
Policy policy = new Policy(Policy.PRIORITY_CATEGORY_SYSTEM
| Policy.PRIORITY_CATEGORY_MEDIA, 0, 0, 0);
assertThat(mBuilder.getSoundSettingSummary(policy))
.isEqualTo("Muted, but allow media and touch sounds");
}
@Test
public void searchProvider_shouldIndexDefaultXml() {
final List<SearchIndexableResource> sir = ZenModeSettings.SEARCH_INDEX_DATA_PROVIDER