Merge "Move strings related to user creation to SettingsLib." into rvc-dev
diff --git a/res/layout/notif_priority_conversation_preference.xml b/res/layout/notif_priority_conversation_preference.xml
new file mode 100644
index 0000000..981cd69
--- /dev/null
+++ b/res/layout/notif_priority_conversation_preference.xml
@@ -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>
\ No newline at end of file
diff --git a/res/layout/zen_mode_settings_button.xml b/res/layout/zen_mode_settings_button.xml
index 49aa287..72731cc 100644
--- a/res/layout/zen_mode_settings_button.xml
+++ b/res/layout/zen_mode_settings_button.xml
@@ -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>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7dfe2d1..a5bbfa7 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2186,8 +2186,6 @@
     <string name="wifi_connected_to_message">@string/bluetooth_connected_summary</string>
     <!-- Button label to connecting progress to a Wi-Fi network [CHAR LIMIT=20] -->
     <string name="wifi_connecting">Connecting\u2026</string>
-    <!-- Button label to disconnect to a Wi-Fi network [CHAR LIMIT=NONE] -->
-    <string name="wifi_disconnect">@string/bluetooth_device_context_disconnect</string>
     <!-- Failured notification for connect -->
     <string name="wifi_failed_connect_message">Failed to connect to network</string>
     <!-- Not in range notification for connect [CHAR LIMIT=40] -->
@@ -7725,13 +7723,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]-->
@@ -7746,26 +7744,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>
@@ -7800,29 +7780,20 @@
     <!--  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>
 
+    <!-- Do not disturb: zen settings screens category title [CHAR LIMIT=100] -->
+    <string name="zen_mode_settings_category">Allow interruptions that make sound</string>
+
     <!--  Do not disturb: Title for the Visual interruptions option and associated settings page. [CHAR LIMIT=30] -->
     <string name="zen_mode_visual_interruptions_settings_title">Block visual disturbances</string>
 
     <!--  Do not disturb: Subtitle for the Visual signals option to toggle on/off visual signals/alerts when the screen is on/when screen is off. [CHAR LIMIT=30] -->
     <string name="zen_mode_visual_signals_settings_subtitle">Allow visual signals</string>
 
-    <!-- Do not disturb: zen settings screens category title [CHAR LIMIT=100] -->
-    <string name="zen_mode_settings_category">Allow interruptions that make sound</string>
-
-    <!-- Do not disturb: restrict notifications 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] -->
@@ -7961,7 +7932,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]-->
@@ -7970,23 +7941,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>
@@ -8158,11 +8118,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>
 
@@ -8181,8 +8141,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>
@@ -8412,6 +8372,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 -->
@@ -8889,156 +8855,174 @@
     <!-- [CHAR LIMIT=40] General template for a verbal start to end range in a text summary -->
     <string name="summary_range_verbal_combination"><xliff:g id="start" example="Sun">%1$s</xliff:g> to <xliff:g id="end" example="Thu">%2$s</xliff:g></string>
 
-    <!-- [CHAR LIMIT=20] Zen mode settings: Calls option -->
-    <string name="zen_mode_calls">Allow calls</string>
+    <!-- [CHAR LIMIT=120] Zen mode settings: Title for conversations settings page -->
+    <string name="zen_mode_conversations_title">Conversations</string>
+    <!-- [CHAR LIMIT=120] Zen mode settings: Header for conversations settings page -->
+    <string name="zen_mode_conversations_section_title">Conversations that can interrupt</string>
+    <string name="zen_mode_from_all_conversations">All conversations</string>
+    <string name="zen_mode_from_important_conversations">Important conversations</string>
+    <string name="zen_mode_from_no_conversations">None</string>
+    <plurals name="zen_mode_conversations_count">
+        <item quantity="one">1 conversation</item>
+        <item quantity="other"><xliff:g id="conversations" example="3">%d</xliff:g> conversations</item>
+    </plurals>
+    <!-- [CHAR LIMIT=40] Zen mode settings: No conversations are allowed to bypass DND -->
+    <string name="zen_mode_conversations_count_none">None</string>
+    <!-- [CHAR LIMIT=120] Zen mode settings: Header for calls and messages section of conversations
+    setting page -->
+    <string name="zen_mode_people_calls_messages_section_title">Who can interrupt</string>
 
     <!-- [CHAR LIMIT=40] Zen mode settings: Allow calls toggle title -->
     <string name="zen_mode_calls_title">Calls</string>
-
+    <!-- [CHAR LIMIT=20] Zen mode settings: Calls option -->
+    <string name="zen_mode_calls">Calls</string>
+    <!-- [CHAR LIMIT=20] Zen mode settings: Calls option -->
+    <string name="zen_mode_calls_list">calls</string>
+    <!-- [CHAR LIMIT=120] Zen mode settings: Calls settings header -->
+    <string name="zen_mode_calls_header">Calls that can interrupt</string>
     <!-- [CHAR LIMIT=NONE] Zen mode settings: Calls screen footer -->
     <string name="zen_mode_calls_footer">To be sure allowed calls make sound, check whether your device is set to ring, vibrate, or silent.</string>
-
     <!-- [CHAR LIMIT=NONE] Zen mode custom rule settings: Calls screen footer -->
     <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>
         <item quantity="other"><xliff:g id="num_people" example="3">%d</xliff:g> others</item>
     </plurals>
 
-    <string name="zen_mode_conversations_title">Conversations</string>
-    <string name="zen_mode_from_all_conversations">From all conversations</string>
-    <string name="zen_mode_from_important_conversations">From important conversations</string>
-    <string name="zen_mode_from_no_conversations">Don\u2019t allow any conversations</string>
-
     <!-- [CHAR LIMIT=40] Zen mode settings: Messages option -->
-    <string name="zen_mode_messages">Allow messages</string>
-
+    <string name="zen_mode_messages">Messages</string>
+    <!-- [CHAR LIMIT=40] Zen mode settings: Messages option -->
+    <string name="zen_mode_messages_list">messages</string>
+    <!-- [CHAR LIMIT=40] Zen mode settings: Allow messages to bypass DND title -->
+    <string name="zen_mode_messages_title">SMS, MMS, and messaging apps</string>
+    <!-- [CHAR LIMIT=120] Zen mode settings: Messages settings header -->
+    <string name="zen_mode_messages_header">Messages that can interrupt</string>
     <!-- Do not disturb settings, messages, events and reminders footer [CHAR LIMIT=NONE]-->
     <string name="zen_mode_messages_footer">To be sure allowed messages make sound, check whether your device is set to ring, vibrate, or silent.</string>
-
     <!-- [CHAR LIMIT=NONE] Zen mode custom rule settings: Messages screen footer -->
     <string name="zen_mode_custom_messages_footer">For \u2018<xliff:g id="schedule_name" example="Schedule 1">%1$s</xliff:g>\u2019 incoming messages are blocked. You can adjust settings to allow your friends, family, or other contacts to reach you.</string>
 
-    <!-- [CHAR LIMIT=40] Zen mode settings: Allow messages to bypass DND title -->
-    <string name="zen_mode_messages_title">SMS, MMS, and messaging apps</string>
+    <!-- Zen mode settings: All senders can bypass DND summary [CHAR LIMIT=NONE -->
+    <string name="zen_mode_all_senders_summary">All <xliff:g id="sender_category" example="messages">%s</xliff:g> can reach you</string>
+    <!-- Zen mode settings: Senders in contacts can bypass DND summary summary [CHAR LIMIT=NONE -->
+    <string name="zen_mode_contacts_senders_summary"><xliff:g id="num_contacts" example="120">%d</xliff:g> contacts</string>
 
     <!-- [CHAR LIMIT=40] Zen mode settings: Calls or messages option value: From anyone -->
-    <string name="zen_mode_from_anyone">From anyone</string>
-
+    <string name="zen_mode_from_anyone">Anyone</string>
     <!-- [CHAR LIMIT=40] Zen mode settings: Calls or messages option value: From contacts only -->
-    <string name="zen_mode_from_contacts">From contacts only</string>
-
+    <string name="zen_mode_from_contacts">Contacts</string>
     <!-- [CHAR LIMIT=40] Zen mode settings: Calls or messages option value: From starred contacts only -->
-    <string name="zen_mode_from_starred">From starred contacts only</string>
-
-    <!-- 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>
-
+    <string name="zen_mode_from_starred">Starred contacts</string>
     <!-- [CHAR LIMIT=40] Zen mode settings: Calls and/or messages from none-->
     <string name="zen_mode_from_none">None</string>
 
+    <!-- Do not disturb settings, calls summary [CHAR LIMIT=100]-->
+    <string name="zen_calls_summary_starred_repeat">From starred contacts and repeat callers</string>
+    <!-- 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 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=100] Zen mode settings: Allow apps to bypass DND header -->
+    <string name="zen_mode_bypassing_apps_header">Apps that can interrupt</string>
+    <!-- [CHAR LIMIT=120] Zen mode settings: No apps are bypassing DND -->
+    <string name="zen_mode_bypassing_apps_subtext_none">No apps can interrupt</string>
+    <!-- [CHAR LIMIT=120] Zen mode settings: Allow apps to bypass DND -->
+    <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=100] Zen mode settings: App that can bypass DND's secondary text describing which notification channels from the app can bypass DND-->
+    <string name="zen_mode_bypassing_apps_all_summary">All notifications</string>
+    <!-- [CHAR LIMIT=100] Zen mode settings: App that can bypass DND's secondary text describing which notification channels from the app can bypass DND-->
+    <string name="zen_mode_bypassing_apps_some_summary">Some notifications</string>
 
-    <!-- [CHAR LIMIT=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>
 
@@ -9047,43 +9031,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>
 
@@ -11843,6 +11817,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] -->
diff --git a/res/xml/conversation_list_settings.xml b/res/xml/conversation_list_settings.xml
index 5b9f0c4..238e92b 100644
--- a/res/xml/conversation_list_settings.xml
+++ b/res/xml/conversation_list_settings.xml
@@ -16,11 +16,12 @@
 
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:settings="http://schemas.android.com/apk/res-auto"
-        android:key="conversation_list">
+        android:key="conversation_list"
+        android:title="zen_mode_conversations_title">
 
     <PreferenceCategory
-        android:title="@string/important_conversations"
         android:key="important_conversations"
+        android:title="@string/important_conversations"
         android:visibility="gone"
         settings:allowDividerAbove="false"
         settings:allowDividerBelow="true" >
diff --git a/res/xml/conversation_notification_settings.xml b/res/xml/conversation_notification_settings.xml
index d0db428..be1c980 100644
--- a/res/xml/conversation_notification_settings.xml
+++ b/res/xml/conversation_notification_settings.xml
@@ -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>
diff --git a/res/xml/zen_mode_calls_settings.xml b/res/xml/zen_mode_calls_settings.xml
index 8366b09..cbadc7d 100644
--- a/res/xml/zen_mode_calls_settings.xml
+++ b/res/xml/zen_mode_calls_settings.xml
@@ -19,28 +19,20 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:key="zen_mode_calls_settings_page"
-    android:title="@string/zen_mode_calls_title" >
+    android:title="@string/zen_mode_calls_title">
 
     <PreferenceCategory
-        android:title="@string/zen_mode_settings_category"
-        android:key="zen_mode_settings_category_calls">
-        <!-- Calls -->
-        <ListPreference
-            android:key="zen_mode_calls"
-            android:title="@string/zen_mode_calls"
-            android:entries="@array/zen_mode_contacts_calls_entries"
-            android:entryValues="@array/zen_mode_contacts_values"/>
-
-        <Preference
-            android:key="zen_mode_starred_contacts_callers"
-            android:title="@string/zen_mode_starred_contacts_title"/>
-
-        <!-- Repeat callers -->
-        <SwitchPreference
-            android:key="zen_mode_repeat_callers"
-            android:title="@string/zen_mode_repeat_callers_title" />
+        android:key="zen_mode_settings_category_calls"
+        android:title="@string/zen_mode_calls_header"
+        settings:allowDividerBelow="true">
     </PreferenceCategory>
 
+    <!-- Repeat callers -->
+    <SwitchPreference
+        android:key="zen_mode_repeat_callers"
+        android:title="@string/zen_mode_repeat_callers_title"
+        settings:allowDividerAbove="true"/>
+
     <com.android.settingslib.widget.FooterPreference/>
 
 </PreferenceScreen>
diff --git a/res/xml/zen_mode_conversations_settings.xml b/res/xml/zen_mode_conversations_settings.xml
new file mode 100644
index 0000000..773a8b2
--- /dev/null
+++ b/res/xml/zen_mode_conversations_settings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:key="zen_mode_conversations_settings"
+    android:title="@string/zen_mode_conversations_title">
+    <!-- Conversations -->
+    <PreferenceCategory
+        android:key="zen_mode_conversations_radio_buttons"
+        android:title="@string/zen_mode_conversations_section_title">
+        <!-- TODO: add preference with chat images here (b/151845457) -->
+    </PreferenceCategory>
+</PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/zen_mode_messages_settings.xml b/res/xml/zen_mode_messages_settings.xml
index 2d0129e..c302b02 100644
--- a/res/xml/zen_mode_messages_settings.xml
+++ b/res/xml/zen_mode_messages_settings.xml
@@ -21,18 +21,8 @@
     android:title="@string/zen_mode_messages_title" >
 
     <PreferenceCategory
-        android:title="@string/zen_mode_settings_category"
-        android:key="zen_mode_settings_category_messages">
-        <!-- Messages -->
-        <ListPreference
-            android:key="zen_mode_messages"
-            android:title="@string/zen_mode_messages"
-            android:entries="@array/zen_mode_contacts_messages_entries"
-            android:entryValues="@array/zen_mode_contacts_values"/>
-
-        <Preference
-            android:key="zen_mode_starred_contacts_messages"
-            android:title="@string/zen_mode_starred_contacts_title"/>
+        android:key="zen_mode_settings_category_messages"
+        android:title="@string/zen_mode_messages_header">
     </PreferenceCategory>
 
     <com.android.settingslib.widget.FooterPreference/>
diff --git a/res/xml/zen_mode_people_settings.xml b/res/xml/zen_mode_people_settings.xml
index 7755bb7..140c241 100644
--- a/res/xml/zen_mode_people_settings.xml
+++ b/res/xml/zen_mode_people_settings.xml
@@ -20,51 +20,31 @@
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:title="@string/zen_category_people" >
 
+   <!-- Conversations -->
    <PreferenceCategory
-       android:title="@string/zen_mode_calls_title"
-       android:key="zen_mode_settings_category_calls">
-      <!-- Calls -->
-      <ListPreference
-          android:key="zen_mode_calls"
-          android:title="@string/zen_mode_calls"
-          android:entries="@array/zen_mode_contacts_calls_entries"
-          android:entryValues="@array/zen_mode_contacts_values"/>
+       android:key="zen_mode_settings_category_conversations"
+       android:title="@string/zen_mode_conversations_section_title">
 
       <Preference
-          android:key="zen_mode_starred_contacts_callers"
-          android:title="@string/zen_mode_starred_contacts_title"/>
-
-      <!-- Repeat callers -->
-      <SwitchPreference
-          android:key="zen_mode_repeat_callers"
-          android:title="@string/zen_mode_repeat_callers_title" />
-   </PreferenceCategory>
-
-   <PreferenceCategory
-       android:title="@string/zen_mode_messages_title"
-       android:key="zen_mode_settings_category_messages">
-      <!-- Messages -->
-      <ListPreference
-          android:key="zen_mode_messages"
-          android:title="@string/zen_mode_messages"
-          android:entries="@array/zen_mode_contacts_messages_entries"
-          android:entryValues="@array/zen_mode_contacts_values"/>
-
-      <Preference
-          android:key="zen_mode_starred_contacts_messages"
-          android:title="@string/zen_mode_starred_contacts_title"/>
-   </PreferenceCategory>
-
-   <PreferenceCategory
-       android:title="@string/zen_mode_conversations_title"
-       android:key="zen_mode_settings_category_conversations">
-
-      <!-- Conversations -->
-      <ListPreference
           android:key="zen_mode_conversations"
           android:title="@string/zen_mode_conversations_title"
-          android:entries="@array/zen_mode_conversations_entries"
-          android:entryValues="@array/zen_mode_conversations_values"/>
+          android:fragment="com.android.settings.notification.zen.ZenModeConversationsSettings"/>
+   </PreferenceCategory>
+
+   <!-- Calls & Messages -->
+   <PreferenceCategory
+       android:key="zen_mode_people_calls_messages_section"
+       android:title="@string/zen_mode_people_calls_messages_section_title">
+
+      <Preference
+          android:key="zen_mode_people_calls"
+          android:title="@string/zen_mode_calls_title"
+          android:fragment="com.android.settings.notification.zen.ZenModeCallsSettings"/>
+
+      <Preference
+          android:key="zen_mode_people_messages"
+          android:title="@string/zen_mode_messages_title"
+          android:fragment="com.android.settings.notification.zen.ZenModeMessagesSettings"/>
    </PreferenceCategory>
 
    <!-- Footer that shows if user is put into alarms only or total silence mode by an app -->
diff --git a/res/xml/zen_mode_settings.xml b/res/xml/zen_mode_settings.xml
index ce2d132..9649207 100644
--- a/res/xml/zen_mode_settings.xml
+++ b/res/xml/zen_mode_settings.xml
@@ -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 -->
diff --git a/src/com/android/settings/IccLockSettings.java b/src/com/android/settings/IccLockSettings.java
index a9b496a..4340039 100644
--- a/src/com/android/settings/IccLockSettings.java
+++ b/src/com/android/settings/IccLockSettings.java
@@ -31,6 +31,7 @@
 import android.os.PersistableBundle;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
@@ -231,13 +232,16 @@
         for (int i = 0; i < numSims; ++i) {
             final SubscriptionInfo subInfo =
                     getActiveSubscriptionInfoForSimSlotIndex(subInfoList, i);
-            final CarrierConfigManager carrierConfigManager = getContext().getSystemService(
-                    CarrierConfigManager.class);
-            final PersistableBundle bundle = carrierConfigManager.getConfigForSubId(
-                    subInfo.getSubscriptionId());
-            if (bundle != null
-                    && !bundle.getBoolean(CarrierConfigManager.KEY_HIDE_SIM_LOCK_SETTINGS_BOOL)) {
-                componenterList.add(subInfo);
+            if (subInfo != null) {
+                final CarrierConfigManager carrierConfigManager = getContext().getSystemService(
+                        CarrierConfigManager.class);
+                final PersistableBundle bundle = carrierConfigManager.getConfigForSubId(
+                        subInfo.getSubscriptionId());
+                if (bundle != null
+                        && !bundle.getBoolean(CarrierConfigManager
+                        .KEY_HIDE_SIM_LOCK_SETTINGS_BOOL)) {
+                    componenterList.add(subInfo);
+                }
             }
         }
 
@@ -292,7 +296,8 @@
         final List<SubscriptionInfo> subInfoList =
                 mProxySubscriptionMgr.getActiveSubscriptionsInfo();
         final SubscriptionInfo sir = getActiveSubscriptionInfoForSimSlotIndex(subInfoList, mSlotId);
-        mSubId = sir.getSubscriptionId();
+        mSubId = (sir == null) ? SubscriptionManager.INVALID_SUBSCRIPTION_ID
+            : sir.getSubscriptionId();
 
         if (mPinDialog != null) {
             mPinDialog.setEnabled(sir != null);
@@ -679,8 +684,6 @@
         @Override
         public void onTabChanged(String tabId) {
             mSlotId = Integer.parseInt(tabId);
-            final SubscriptionInfo sir = getActiveSubscriptionInfoForSimSlotIndex(
-                    mProxySubscriptionMgr.getActiveSubscriptionsInfo(), mSlotId);
 
             // The User has changed tab; update the body.
             updatePreferences();
diff --git a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
index 30ba084..3906fc8 100644
--- a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
+++ b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
@@ -268,7 +268,8 @@
                 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
                         | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
                         | PhoneStateListener.LISTEN_SERVICE_STATE);
-        mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
+        mSubscriptionManager.addOnSubscriptionsChangedListener(
+                mContext.getMainExecutor(), mOnSubscriptionsChangedListener);
         registerImsRegistrationCallback(mSubscriptionInfo.getSubscriptionId());
 
         if (mShowLatestAreaInfo) {
diff --git a/src/com/android/settings/network/ActiveSubsciptionsListener.java b/src/com/android/settings/network/ActiveSubsciptionsListener.java
index d3702f1..99dfd55 100644
--- a/src/com/android/settings/network/ActiveSubsciptionsListener.java
+++ b/src/com/android/settings/network/ActiveSubsciptionsListener.java
@@ -266,6 +266,12 @@
         mCachedActiveSubscriptionInfo = null;
     }
 
+    @VisibleForTesting
+    void registerForSubscriptionsChange() {
+        getSubscriptionManager().addOnSubscriptionsChangedListener(
+                mContext.getMainExecutor(), this);
+    }
+
     private void monitorSubscriptionsChange(boolean on) {
         if (on) {
             if (!mCacheState.compareAndSet(STATE_NOT_LISTENING, STATE_PREPARING)) {
@@ -277,7 +283,7 @@
             }
             mContext.registerReceiver(mSubscriptionChangeReceiver,
                     mSubscriptionChangeIntentFilter, null, new Handler(mLooper));
-            getSubscriptionManager().addOnSubscriptionsChangedListener(this);
+            registerForSubscriptionsChange();
             mCacheState.compareAndSet(STATE_PREPARING, STATE_LISTENING);
             return;
         }
diff --git a/src/com/android/settings/network/SubscriptionsChangeListener.java b/src/com/android/settings/network/SubscriptionsChangeListener.java
index 1ecd770..1b50a54 100644
--- a/src/com/android/settings/network/SubscriptionsChangeListener.java
+++ b/src/com/android/settings/network/SubscriptionsChangeListener.java
@@ -67,7 +67,8 @@
     }
 
     public void start() {
-        mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionsChangedListener);
+        mSubscriptionManager.addOnSubscriptionsChangedListener(
+                mContext.getMainExecutor(), mSubscriptionsChangedListener);
         mContext.getContentResolver()
                 .registerContentObserver(mAirplaneModeSettingUri, false, this);
         final IntentFilter radioTechnologyChangedFilter = new IntentFilter(
diff --git a/src/com/android/settings/notification/app/BubblePreferenceController.java b/src/com/android/settings/notification/app/BubblePreferenceController.java
index 879f17a..d33ba7e 100644
--- a/src/com/android/settings/notification/app/BubblePreferenceController.java
+++ b/src/com/android/settings/notification/app/BubblePreferenceController.java
@@ -68,7 +68,7 @@
             if (isDefaultChannel()) {
                 return true;
             } else {
-                return mAppRow != null && mAppRow.allowBubbles;
+                return mAppRow != null;
             }
         }
         return true;
diff --git a/src/com/android/settings/notification/app/ConversationListSettings.java b/src/com/android/settings/notification/app/ConversationListSettings.java
index aaeaa95..1eb997a 100644
--- a/src/com/android/settings/notification/app/ConversationListSettings.java
+++ b/src/com/android/settings/notification/app/ConversationListSettings.java
@@ -18,15 +18,8 @@
 
 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 @@
     @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);
     }
diff --git a/src/com/android/settings/notification/app/ConversationNotificationSettings.java b/src/com/android/settings/notification/app/ConversationNotificationSettings.java
index c5a8e6e..210af20 100644
--- a/src/com/android/settings/notification/app/ConversationNotificationSettings.java
+++ b/src/com/android/settings/notification/app/ConversationNotificationSettings.java
@@ -79,18 +79,13 @@
     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));
diff --git a/src/com/android/settings/notification/app/ConversationPriorityPreference.java b/src/com/android/settings/notification/app/ConversationPriorityPreference.java
new file mode 100644
index 0000000..ff1dc6c
--- /dev/null
+++ b/src/com/android/settings/notification/app/ConversationPriorityPreference.java
@@ -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));
+            }
+        }
+    }
+}
diff --git a/src/com/android/settings/notification/app/ConversationImportantPreferenceController.java b/src/com/android/settings/notification/app/ConversationPriorityPreferenceController.java
similarity index 63%
rename from src/com/android/settings/notification/app/ConversationImportantPreferenceController.java
rename to src/com/android/settings/notification/app/ConversationPriorityPreferenceController.java
index 0b1ee16..e59f277 100644
--- a/src/com/android/settings/notification/app/ConversationImportantPreferenceController.java
+++ b/src/com/android/settings/notification/app/ConversationPriorityPreferenceController.java
@@ -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 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 @@
         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;
-    }
 }
diff --git a/src/com/android/settings/notification/app/DefaultImportancePreferenceController.java b/src/com/android/settings/notification/app/DefaultImportancePreferenceController.java
deleted file mode 100644
index 616d64a..0000000
--- a/src/com/android/settings/notification/app/DefaultImportancePreferenceController.java
+++ /dev/null
@@ -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;
-    }
-}
diff --git a/src/com/android/settings/notification/app/ImportantConversationsPreferenceController.java b/src/com/android/settings/notification/app/PriorityConversationsPreferenceController.java
similarity index 94%
rename from src/com/android/settings/notification/app/ImportantConversationsPreferenceController.java
rename to src/com/android/settings/notification/app/PriorityConversationsPreferenceController.java
index 2089d9d..ed12d7d 100644
--- a/src/com/android/settings/notification/app/ImportantConversationsPreferenceController.java
+++ b/src/com/android/settings/notification/app/PriorityConversationsPreferenceController.java
@@ -28,14 +28,14 @@
 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);
     }
diff --git a/src/com/android/settings/notification/zen/ZenModeBackend.java b/src/com/android/settings/notification/zen/ZenModeBackend.java
index 836f435..bb406c1 100644
--- a/src/com/android/settings/notification/zen/ZenModeBackend.java
+++ b/src/com/android/settings/notification/zen/ZenModeBackend.java
@@ -16,8 +16,6 @@
 
 package com.android.settings.notification.zen;
 
-import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE;
-import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON;
@@ -501,7 +499,7 @@
     private List<String> getStarredContacts() {
         Cursor cursor = null;
         try {
-            cursor = queryData();
+            cursor = queryStarredContactsData();
             return getStarredContacts(cursor);
         } finally {
             if (cursor != null) {
@@ -510,7 +508,7 @@
         }
     }
 
-    public String getStarredContactsSummary(Context context) {
+    String getStarredContactsSummary(Context context) {
         List<String> starredContacts = getStarredContacts();
         int numStarredContacts = starredContacts.size();
 
@@ -536,13 +534,24 @@
         return ListFormatter.getInstance().format(displayContacts);
     }
 
-    private Cursor queryData() {
+    String getContactsNumberSummary(Context context) {
+        return context.getResources().getString(R.string.zen_mode_contacts_senders_summary,
+                queryAllContactsData().getCount());
+    }
+
+    private Cursor queryStarredContactsData() {
         return mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
                 new String[]{ContactsContract.Contacts.DISPLAY_NAME_PRIMARY},
                 ContactsContract.Data.STARRED + "=1", null,
                 ContactsContract.Data.TIMES_CONTACTED);
     }
 
+    private Cursor queryAllContactsData() {
+        return mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
+                new String[]{ContactsContract.Contacts.DISPLAY_NAME_PRIMARY},
+                null, null, null);
+    }
+
     @VisibleForTesting
     public static final Comparator<Map.Entry<String, AutomaticZenRule>> RULE_COMPARATOR =
             new Comparator<Map.Entry<String, AutomaticZenRule>>() {
diff --git a/src/com/android/settings/notification/zen/ZenModeBypassingAppsPreferenceController.java b/src/com/android/settings/notification/zen/ZenModeBypassingAppsPreferenceController.java
index a93fa1b..7459394 100644
--- a/src/com/android/settings/notification/zen/ZenModeBypassingAppsPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenModeBypassingAppsPreferenceController.java
@@ -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 @@
     }
 
     @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();
+                }
+            };
 }
diff --git a/src/com/android/settings/notification/zen/ZenModeCallsSettings.java b/src/com/android/settings/notification/zen/ZenModeCallsSettings.java
new file mode 100644
index 0000000..1b5412e
--- /dev/null
+++ b/src/com/android/settings/notification/zen/ZenModeCallsSettings.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification.zen;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.provider.SearchIndexableResource;
+
+import com.android.settings.R;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.search.SearchIndexable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * DND Calls Settings page to determine which priority senders can bypass DND.
+ */
+@SearchIndexable
+public class ZenModeCallsSettings extends ZenModeSettingsBase {
+
+    @Override
+    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+        return buildPreferenceControllers(context, getSettingsLifecycle());
+    }
+
+    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
+            Lifecycle lifecycle) {
+        List<AbstractPreferenceController> controllers = new ArrayList<>();
+        controllers.add(new ZenModePrioritySendersPreferenceController(context,
+                "zen_mode_settings_category_calls", lifecycle, false));
+        controllers.add(new ZenModeRepeatCallersPreferenceController(context, lifecycle,
+                context.getResources().getInteger(com.android.internal.R.integer
+                        .config_zen_repeat_callers_threshold)));
+        controllers.add(new ZenModeBehaviorFooterPreferenceController(
+                context, lifecycle, R.string.zen_mode_calls_footer));
+        return controllers;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.zen_mode_calls_settings;
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.DND_CALLS;
+    }
+
+    /**
+     * For Search.
+     */
+    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider() {
+        @Override
+        public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
+                boolean enabled) {
+            final ArrayList<SearchIndexableResource> result = new ArrayList<>();
+
+            final SearchIndexableResource sir = new SearchIndexableResource(context);
+            sir.xmlResId = R.xml.zen_mode_calls_settings;
+            result.add(sir);
+            return result;
+        }
+
+        @Override
+        public List<AbstractPreferenceController> createPreferenceControllers(
+                Context context) {
+            return buildPreferenceControllers(context, null);
+        }
+    };
+}
diff --git a/src/com/android/settings/notification/zen/ZenModeConversationsPreferenceController.java b/src/com/android/settings/notification/zen/ZenModeConversationsPreferenceController.java
new file mode 100644
index 0000000..f23bf61
--- /dev/null
+++ b/src/com/android/settings/notification/zen/ZenModeConversationsPreferenceController.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification.zen;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.provider.Settings;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+/**
+ * Controls the summary for preference found at:
+ *  Settings > Sound > Do Not Disturb > People > Conversations
+ */
+public class ZenModeConversationsPreferenceController extends AbstractZenModePreferenceController {
+    private final ZenModeBackend mBackend;
+    private Preference mPreference;
+
+    public ZenModeConversationsPreferenceController(Context context,
+            String key, Lifecycle lifecycle) {
+        super(context, key, lifecycle);
+        mBackend = ZenModeBackend.getInstance(context);
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY;
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return true;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = screen.findPreference(KEY);
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        super.updateState(preference);
+        switch (getZenMode()) {
+            case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
+            case Settings.Global.ZEN_MODE_ALARMS:
+                mPreference.setEnabled(false);
+                mPreference.setSummary(mBackend.getAlarmsTotalSilencePeopleSummary(
+                        NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS));
+                break;
+            default:
+                preference.setEnabled(true);
+                preference.setSummary(mBackend.getConversationSummary());
+        }
+    }
+}
diff --git a/src/com/android/settings/notification/zen/ZenModeConversationsSettings.java b/src/com/android/settings/notification/zen/ZenModeConversationsSettings.java
new file mode 100644
index 0000000..4307538
--- /dev/null
+++ b/src/com/android/settings/notification/zen/ZenModeConversationsSettings.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification.zen;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+
+import com.android.settings.R;
+import com.android.settings.notification.NotificationBackend;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.search.SearchIndexable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Settings > Sound > Do Not Disturb > Conversationss
+ */
+@SearchIndexable
+public class ZenModeConversationsSettings extends ZenModeSettingsBase {
+    private final NotificationBackend mNotificationBackend = new NotificationBackend();
+
+    @Override
+    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+        return buildPreferenceControllers(context, getSettingsLifecycle(), mNotificationBackend);
+    }
+
+    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
+            Lifecycle lifecycle, NotificationBackend notificationBackend) {
+        List<AbstractPreferenceController> controllers = new ArrayList<>();
+        controllers.add(new ZenModePriorityConversationsPreferenceController(context,
+                "zen_mode_conversations_radio_buttons", lifecycle, notificationBackend));
+        return controllers;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.zen_mode_conversations_settings;
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.DND_CONVERSATIONS;
+    }
+
+    /**
+     * For Search.
+     */
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.zen_mode_conversations_settings) {
+
+                @Override
+                public List<AbstractPreferenceController> createPreferenceControllers(
+                        Context context) {
+                    return buildPreferenceControllers(context, null, null);
+                }
+            };
+}
diff --git a/src/com/android/settings/notification/zen/ZenModeMessagesSettings.java b/src/com/android/settings/notification/zen/ZenModeMessagesSettings.java
new file mode 100644
index 0000000..d15a4aa
--- /dev/null
+++ b/src/com/android/settings/notification/zen/ZenModeMessagesSettings.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification.zen;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.provider.SearchIndexableResource;
+
+import com.android.settings.R;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.search.SearchIndexable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * DND Messages Settings page to determine which priority senders can bypass DND.
+ * "Messages" include SMS, MMS, and messaging apps.
+ */
+@SearchIndexable
+public class ZenModeMessagesSettings extends ZenModeSettingsBase {
+
+    @Override
+    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+        return buildPreferenceControllers(context, getSettingsLifecycle());
+    }
+
+    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
+            Lifecycle lifecycle) {
+        List<AbstractPreferenceController> controllers = new ArrayList<>();
+        controllers.add(new ZenModePrioritySendersPreferenceController(context,
+                "zen_mode_settings_category_messages", lifecycle, true));
+        controllers.add(new ZenModeBehaviorFooterPreferenceController(
+                context, lifecycle, R.string.zen_mode_messages_footer));
+        return controllers;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.zen_mode_messages_settings;
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.DND_MESSAGES;
+    }
+
+    /**
+     * For Search.
+     */
+    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider() {
+        @Override
+        public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
+                boolean enabled) {
+            final ArrayList<SearchIndexableResource> result = new ArrayList<>();
+
+            final SearchIndexableResource sir = new SearchIndexableResource(context);
+            sir.xmlResId = R.xml.zen_mode_messages_settings;
+            result.add(sir);
+            return result;
+        }
+
+        @Override
+        public List<AbstractPreferenceController> createPreferenceControllers(
+                Context context) {
+            return buildPreferenceControllers(context, null);
+        }
+    };
+}
diff --git a/src/com/android/settings/notification/zen/ZenModePeoplePreferenceController.java b/src/com/android/settings/notification/zen/ZenModePeoplePreferenceController.java
index a48c93d..cb185dd 100644
--- a/src/com/android/settings/notification/zen/ZenModePeoplePreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenModePeoplePreferenceController.java
@@ -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 @@
                 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);
         }
     }
 }
diff --git a/src/com/android/settings/notification/zen/ZenModePeopleSettings.java b/src/com/android/settings/notification/zen/ZenModePeopleSettings.java
index ff768db..4971e54 100644
--- a/src/com/android/settings/notification/zen/ZenModePeopleSettings.java
+++ b/src/com/android/settings/notification/zen/ZenModePeopleSettings.java
@@ -16,9 +16,6 @@
 
 package com.android.settings.notification.zen;
 
-import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS;
-import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES;
-
 import android.app.Activity;
 import android.app.Application;
 import android.app.settings.SettingsEnums;
@@ -56,16 +53,12 @@
     private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
             Lifecycle lifecycle, Application app, Fragment host, FragmentManager fragmentManager) {
         List<AbstractPreferenceController> controllers = new ArrayList<>();
-        controllers.add(new ZenModePriorityMessagesPreferenceController(context, lifecycle));
-        controllers.add(new ZenModeStarredContactsPreferenceController(context, lifecycle,
-                PRIORITY_CATEGORY_MESSAGES, "zen_mode_starred_contacts_messages"));
-        controllers.add(new ZenModePriorityCallsPreferenceController(context, lifecycle));
-        controllers.add(new ZenModeStarredContactsPreferenceController(context, lifecycle,
-                PRIORITY_CATEGORY_CALLS, "zen_mode_starred_contacts_callers"));
-        controllers.add(new ZenModeRepeatCallersPreferenceController(context, lifecycle,
-                context.getResources().getInteger(com.android.internal.R.integer
-                        .config_zen_repeat_callers_threshold)));
-        controllers.add(new ZenModePriorityConversationsPreferenceController(context, lifecycle));
+        controllers.add(new ZenModeConversationsPreferenceController(context,
+                "zen_mode_conversations", lifecycle));
+        controllers.add(new ZenModeCallsPreferenceController(context, lifecycle,
+                "zen_mode_people_calls"));
+        controllers.add(new ZenModeMessagesPreferenceController(context, lifecycle,
+                "zen_mode_people_messages"));
         controllers.add(new ZenModeSettingsFooterPreferenceController(context, lifecycle,
                 fragmentManager));
         return controllers;
diff --git a/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java b/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java
index afd17ad..b6824a9 100644
--- a/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java
@@ -16,37 +16,65 @@
 
 package com.android.settings.notification.zen;
 
-import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_ANYONE;
-import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_IMPORTANT;
-import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_NONE;
-
 import android.app.NotificationManager;
 import android.content.Context;
-import android.provider.Settings;
+import android.content.pm.ParceledListSlice;
+import android.os.AsyncTask;
+import android.service.notification.ConversationChannelWrapper;
 
-import androidx.preference.ListPreference;
+import androidx.annotation.VisibleForTesting;
 import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
+import com.android.settings.notification.NotificationBackend;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
 
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Options to choose the priority conversations that are allowed to bypass DND.
+ */
 public class ZenModePriorityConversationsPreferenceController
-        extends AbstractZenModePreferenceController
-        implements Preference.OnPreferenceChangeListener {
+        extends AbstractZenModePreferenceController {
+    private static final int UNSET = -1;
+    @VisibleForTesting static final String KEY_ALL = "conversations_all";
+    @VisibleForTesting static final String KEY_IMPORTANT = "conversations_important";
+    @VisibleForTesting static final String KEY_NONE = "conversations_none";
 
-    protected static final String KEY = "zen_mode_conversations";
-    private final ZenModeBackend mBackend;
-    private ListPreference mPreference;
+    private final NotificationBackend mNotificationBackend;
 
-    public ZenModePriorityConversationsPreferenceController(Context context, Lifecycle lifecycle) {
-        super(context, KEY, lifecycle);
-        mBackend = ZenModeBackend.getInstance(context);
+    private int mNumImportantConversations = UNSET;
+    private int mNumConversations = UNSET;
+    private PreferenceCategory mPreferenceCategory;
+    private List<RadioButtonPreference> mRadioButtonPreferences = new ArrayList<>();
+
+    public ZenModePriorityConversationsPreferenceController(Context context, String key,
+            Lifecycle lifecycle, NotificationBackend notificationBackend) {
+        super(context, key, lifecycle);
+        mNotificationBackend = notificationBackend;
     }
 
     @Override
-    public String getPreferenceKey() {
-        return KEY;
+    public void displayPreference(PreferenceScreen screen) {
+        mPreferenceCategory = screen.findPreference(getPreferenceKey());
+        if (mPreferenceCategory.findPreference(KEY_ALL) == null) {
+            makeRadioPreference(KEY_ALL, R.string.zen_mode_from_all_conversations);
+            makeRadioPreference(KEY_IMPORTANT, R.string.zen_mode_from_important_conversations);
+            makeRadioPreference(KEY_NONE, R.string.zen_mode_from_no_conversations);
+            updateChannelCounts();
+        }
+
+        super.displayPreference(screen);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        updateChannelCounts();
     }
 
     @Override
@@ -55,50 +83,98 @@
     }
 
     @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        mPreference = screen.findPreference(KEY);
+    public String getPreferenceKey() {
+        return KEY;
     }
 
     @Override
     public void updateState(Preference preference) {
-        super.updateState(preference);
-        updateValue(preference);
-    }
+        final int currSetting = mBackend.getPriorityConversationSenders();
 
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object selectedContactsFrom) {
-        mBackend.saveConversationSenders(Integer.parseInt(selectedContactsFrom.toString()));
-        updateValue(preference);
-        return true;
-    }
-
-    private void updateValue(Preference preference) {
-        mPreference = (ListPreference) preference;
-        switch (getZenMode()) {
-            case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
-            case Settings.Global.ZEN_MODE_ALARMS:
-                mPreference.setEnabled(false);
-                mPreference.setValue(String.valueOf(CONVERSATION_SENDERS_NONE));
-                mPreference.setSummary(mBackend.getAlarmsTotalSilencePeopleSummary(
-                        NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS));
-                break;
-            default:
-                preference.setEnabled(true);
-                preference.setSummary(mBackend.getConversationSummary());
-                int senders = mBackend.getPriorityConversationSenders();
-
-                switch (senders) {
-                    case CONVERSATION_SENDERS_NONE:
-                        mPreference.setValue(String.valueOf(CONVERSATION_SENDERS_NONE));
-                        break;
-                    case CONVERSATION_SENDERS_IMPORTANT:
-                        mPreference.setValue(String.valueOf(CONVERSATION_SENDERS_IMPORTANT));
-                        break;
-                    default:
-                        mPreference.setValue(String.valueOf(CONVERSATION_SENDERS_ANYONE));
-                        break;
-                }
+        for (RadioButtonPreference pref : mRadioButtonPreferences) {
+            pref.setChecked(keyToSetting(pref.getKey()) == currSetting);
+            pref.setSummary(getSummary(pref.getKey()));
         }
     }
+
+    private static int keyToSetting(String key) {
+        switch (key) {
+            case KEY_ALL:
+                return NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE;
+            case KEY_IMPORTANT:
+                return NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
+            default:
+                return NotificationManager.Policy.CONVERSATION_SENDERS_NONE;
+        }
+    }
+
+    private String getSummary(String key) {
+        int numConversations;
+        if (KEY_ALL.equals(key)) {
+            numConversations = mNumConversations;
+        } else if (KEY_IMPORTANT.equals(key)) {
+            numConversations = mNumImportantConversations;
+        } else {
+            return null;
+        }
+
+        if (numConversations == UNSET) {
+            return null;
+        } else if (numConversations == 0) {
+            return mContext.getResources().getString(
+                    R.string.zen_mode_conversations_count_none);
+        } else {
+            return mContext.getResources().getQuantityString(
+                    R.plurals.zen_mode_conversations_count, numConversations);
+        }
+    }
+
+    private void updateChannelCounts() {
+        // Load conversations
+        new AsyncTask<Void, Void, Void>() {
+            @Override
+            protected Void doInBackground(Void... unused) {
+                ParceledListSlice<ConversationChannelWrapper> allConversations =
+                        mNotificationBackend.getConversations(false);
+                if (allConversations != null) {
+                    mNumConversations = allConversations.getList().size();
+                }
+                ParceledListSlice<ConversationChannelWrapper> importantConversations =
+                        mNotificationBackend.getConversations(true);
+                if (importantConversations != null) {
+                    mNumImportantConversations = importantConversations.getList().size();
+                }
+                return null;
+            }
+
+            @Override
+            protected void onPostExecute(Void unused) {
+                if (mContext == null) {
+                    return;
+                }
+                updateState(mPreferenceCategory);
+            }
+        }.execute();
+    }
+
+    private RadioButtonPreference makeRadioPreference(String key, int titleId) {
+        RadioButtonPreference pref = new RadioButtonPreference(mPreferenceCategory.getContext());
+        pref.setKey(key);
+        pref.setTitle(titleId);
+        pref.setOnClickListener(mRadioButtonClickListener);
+        mPreferenceCategory.addPreference(pref);
+        mRadioButtonPreferences.add(pref);
+        return pref;
+    }
+
+    private RadioButtonPreference.OnClickListener mRadioButtonClickListener =
+            new RadioButtonPreference.OnClickListener() {
+        @Override
+        public void onRadioButtonClicked(RadioButtonPreference preference) {
+            int selectedConversationSetting = keyToSetting(preference.getKey());
+            if (selectedConversationSetting != mBackend.getPriorityConversationSenders()) {
+                mBackend.saveConversationSenders(selectedConversationSetting);
+            }
+        }
+    };
 }
diff --git a/src/com/android/settings/notification/zen/ZenModePriorityMessagesPreferenceController.java b/src/com/android/settings/notification/zen/ZenModePriorityMessagesPreferenceController.java
deleted file mode 100644
index 6476c63..0000000
--- a/src/com/android/settings/notification/zen/ZenModePriorityMessagesPreferenceController.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.notification.zen;
-
-import android.app.NotificationManager;
-import android.content.Context;
-import android.provider.Settings;
-import android.text.TextUtils;
-
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.ListPreference;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.R;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
-public class ZenModePriorityMessagesPreferenceController extends AbstractZenModePreferenceController
-        implements Preference.OnPreferenceChangeListener {
-
-    protected static final String KEY = "zen_mode_messages";
-    private final ZenModeBackend mBackend;
-    private ListPreference mPreference;
-    private final String[] mListValues;
-
-    public ZenModePriorityMessagesPreferenceController(Context context, Lifecycle lifecycle) {
-        super(context, KEY, lifecycle);
-        mBackend = ZenModeBackend.getInstance(context);
-        mListValues = context.getResources().getStringArray(R.array.zen_mode_contacts_values);
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return KEY;
-    }
-
-    @Override
-    public boolean isAvailable() {
-        return true;
-    }
-
-    @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        mPreference = screen.findPreference(KEY);
-    }
-
-    @Override
-    public void updateState(Preference preference) {
-        super.updateState(preference);
-        updateFromContactsValue(preference);
-    }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object selectedContactsFrom) {
-        mBackend.saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES,
-                ZenModeBackend.getSettingFromPrefKey(selectedContactsFrom.toString()));
-        updateFromContactsValue(preference);
-        return true;
-    }
-
-    private void updateFromContactsValue(Preference preference) {
-        mPreference = (ListPreference) preference;
-        switch (getZenMode()) {
-            case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
-            case Settings.Global.ZEN_MODE_ALARMS:
-                mPreference.setEnabled(false);
-                mPreference.setValue(ZenModeBackend.ZEN_MODE_FROM_NONE);
-                mPreference.setSummary(mBackend.getAlarmsTotalSilencePeopleSummary(
-                        NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES));
-                break;
-            default:
-                preference.setEnabled(true);
-                preference.setSummary(mBackend.getContactsSummary(
-                        NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES));
-
-                final String currentVal = ZenModeBackend.getKeyFromSetting(
-                        mBackend.getPriorityMessageSenders());
-                mPreference.setValue(mListValues[getIndexOfSendersValue(currentVal)]);
-        }
-    }
-
-    @VisibleForTesting
-    protected int getIndexOfSendersValue(String currentVal) {
-        int index = 3; // defaults to "none" based on R.array.zen_mode_contacts_values
-        for (int i = 0; i < mListValues.length; i++) {
-            if (TextUtils.equals(currentVal, mListValues[i])) {
-                return i;
-            }
-        }
-
-        return index;
-    }
-}
diff --git a/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceController.java b/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceController.java
new file mode 100644
index 0000000..da7b24d
--- /dev/null
+++ b/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceController.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification.zen;
+
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS;
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES;
+
+import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_GONE;
+import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_SETTING;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.provider.Contacts;
+import android.view.View;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.widget.RadioButtonPreferenceWithExtraWidget;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Common preference controller functionality shared by
+ * ZenModePriorityMessagesPreferenceController and ZenModePriorityCallsPreferenceController.
+ *
+ * This includes the options to choose the priority senders that are allowed to bypass DND for
+ * calls or messages. This can be one of four values: starred contacts, all contacts, anyone, or
+ * no one.
+ */
+public class ZenModePrioritySendersPreferenceController
+        extends AbstractZenModePreferenceController {
+    @VisibleForTesting static final String KEY_ANY = "senders_anyone";
+    @VisibleForTesting static final String KEY_CONTACTS = "senders_contacts";
+    @VisibleForTesting static final String KEY_STARRED = "senders_starred_contacts";
+    @VisibleForTesting static final String KEY_NONE = "senders_none";
+
+    private static final Intent ALL_CONTACTS_INTENT =
+            new Intent(Contacts.Intents.UI.LIST_ALL_CONTACTS_ACTION);
+    private static final Intent STARRED_CONTACTS_INTENT =
+            new Intent(Contacts.Intents.UI.LIST_STARRED_ACTION);
+    private static final Intent FALLBACK_INTENT = new Intent(Intent.ACTION_MAIN);
+
+    private final PackageManager mPackageManager;
+    private final boolean mIsMessages; // if this is false, then this preference is for calls
+
+    private PreferenceCategory mPreferenceCategory;
+    private List<RadioButtonPreferenceWithExtraWidget> mRadioButtonPreferences = new ArrayList<>();
+
+    public ZenModePrioritySendersPreferenceController(Context context, String key,
+            Lifecycle lifecycle, boolean isMessages) {
+        super(context, key, lifecycle);
+        mIsMessages = isMessages;
+
+        mPackageManager = mContext.getPackageManager();
+        if (!FALLBACK_INTENT.hasCategory(Intent.CATEGORY_APP_CONTACTS)) {
+            FALLBACK_INTENT.addCategory(Intent.CATEGORY_APP_CONTACTS);
+        }
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        mPreferenceCategory = screen.findPreference(getPreferenceKey());
+        if (mPreferenceCategory.findPreference(KEY_ANY) == null) {
+            makeRadioPreference(KEY_STARRED,
+                    com.android.settings.R.string.zen_mode_from_starred);
+            makeRadioPreference(KEY_CONTACTS,
+                    com.android.settings.R.string.zen_mode_from_contacts);
+            makeRadioPreference(KEY_ANY,
+                    com.android.settings.R.string.zen_mode_from_anyone);
+            makeRadioPreference(KEY_NONE,
+                    com.android.settings.R.string.zen_mode_from_none);
+            updateSummaries();
+        }
+
+        super.displayPreference(screen);
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return true;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY;
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        final int currSetting = getPrioritySenders();
+
+        for (RadioButtonPreferenceWithExtraWidget pref : mRadioButtonPreferences) {
+            pref.setChecked(keyToSetting(pref.getKey()) == currSetting);
+        }
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        updateSummaries();
+    }
+
+    private void updateSummaries() {
+        for (RadioButtonPreferenceWithExtraWidget pref : mRadioButtonPreferences) {
+            pref.setSummary(getSummary(pref.getKey()));
+        }
+    }
+
+    private static int keyToSetting(String key) {
+        switch (key) {
+            case KEY_STARRED:
+                return NotificationManager.Policy.PRIORITY_SENDERS_STARRED;
+            case KEY_CONTACTS:
+                return NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS;
+            case KEY_ANY:
+                return NotificationManager.Policy.PRIORITY_SENDERS_ANY;
+            case KEY_NONE:
+            default:
+                return ZenModeBackend.SOURCE_NONE;
+        }
+    }
+
+    private String getSummary(String key) {
+        switch (key) {
+            case KEY_STARRED:
+                return mBackend.getStarredContactsSummary(mContext);
+            case KEY_CONTACTS:
+                return mBackend.getContactsNumberSummary(mContext);
+            case KEY_ANY:
+                return mContext.getResources().getString(R.string.zen_mode_all_senders_summary,
+                        mContext.getResources().getString(mIsMessages
+                                ? R.string.zen_mode_messages_list
+                                : R.string.zen_mode_calls_list));
+            case KEY_NONE:
+            default:
+                return null;
+        }
+    }
+
+    private int getPrioritySenders() {
+        if (mIsMessages) {
+            return mBackend.getPriorityMessageSenders();
+        } else {
+            return mBackend.getPriorityCallSenders();
+        }
+    }
+
+    private RadioButtonPreferenceWithExtraWidget makeRadioPreference(String key, int titleId) {
+        RadioButtonPreferenceWithExtraWidget pref =
+                new RadioButtonPreferenceWithExtraWidget(mPreferenceCategory.getContext());
+        View.OnClickListener widgetClickListener = getWidgetClickListener(key);
+        if (widgetClickListener != null) {
+            pref.setExtraWidgetOnClickListener(widgetClickListener);
+            pref.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_SETTING);
+        } else {
+            pref.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_GONE);
+        }
+
+        pref.setKey(key);
+        pref.setTitle(titleId);
+        pref.setOnClickListener(mRadioButtonClickListener);
+        mPreferenceCategory.addPreference(pref);
+        mRadioButtonPreferences.add(pref);
+        return pref;
+    }
+
+    private RadioButtonPreference.OnClickListener mRadioButtonClickListener =
+            new RadioButtonPreference.OnClickListener() {
+        @Override
+        public void onRadioButtonClicked(RadioButtonPreference preference) {
+            int selectedSetting = keyToSetting(preference.getKey());
+            if (selectedSetting != getPrioritySenders()) {
+                mBackend.saveSenders(
+                        mIsMessages ? PRIORITY_CATEGORY_MESSAGES : PRIORITY_CATEGORY_CALLS,
+                        selectedSetting);
+            }
+        }
+    };
+
+    private View.OnClickListener getWidgetClickListener(String key) {
+        if (!KEY_CONTACTS.equals(key) && !KEY_STARRED.equals(key)) {
+            return null;
+        }
+
+        if (KEY_STARRED.equals(key) && !isStarredIntentValid()) {
+            return null;
+        }
+
+        if (KEY_CONTACTS.equals(key) && !isContactsIntentValid()) {
+            return null;
+        }
+
+        return new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (KEY_STARRED.equals(key)
+                        && STARRED_CONTACTS_INTENT.resolveActivity(mPackageManager) != null) {
+                    mContext.startActivity(STARRED_CONTACTS_INTENT);
+                } else if (KEY_CONTACTS.equals(key)
+                        && ALL_CONTACTS_INTENT.resolveActivity(mPackageManager) != null) {
+                    mContext.startActivity(ALL_CONTACTS_INTENT);
+                } else {
+                    mContext.startActivity(FALLBACK_INTENT);
+                }
+            }
+        };
+    }
+
+    private boolean isStarredIntentValid() {
+        return STARRED_CONTACTS_INTENT.resolveActivity(mPackageManager) != null
+                || FALLBACK_INTENT.resolveActivity(mPackageManager) != null;
+    }
+
+    private boolean isContactsIntentValid() {
+        return ALL_CONTACTS_INTENT.resolveActivity(mPackageManager) != null
+                || FALLBACK_INTENT.resolveActivity(mPackageManager) != null;
+    }
+}
diff --git a/src/com/android/settings/notification/zen/ZenModeSettings.java b/src/com/android/settings/notification/zen/ZenModeSettings.java
index 871974b..c92099a 100644
--- a/src/com/android/settings/notification/zen/ZenModeSettings.java
+++ b/src/com/android/settings/notification/zen/ZenModeSettings.java
@@ -25,15 +25,19 @@
 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 @@
 
     @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 @@
     }
 
     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 @@
                 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 @@
                 @Override
                 public List<AbstractPreferenceController> createPreferenceControllers(Context
                         context) {
-                    return buildPreferenceControllers(context, null, null);
+                    return buildPreferenceControllers(context, null, null,
+                            null, null);
                 }
             };
 }
diff --git a/src/com/android/settings/notification/zen/ZenModeSoundVibrationPreferenceController.java b/src/com/android/settings/notification/zen/ZenModeSoundVibrationPreferenceController.java
new file mode 100644
index 0000000..691c2ae
--- /dev/null
+++ b/src/com/android/settings/notification/zen/ZenModeSoundVibrationPreferenceController.java
@@ -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()));
+        }
+    }
+}
diff --git a/src/com/android/settings/notification/zen/ZenModeSoundVibrationSettings.java b/src/com/android/settings/notification/zen/ZenModeSoundVibrationSettings.java
index 3d4f3c2..c07ee77 100644
--- a/src/com/android/settings/notification/zen/ZenModeSoundVibrationSettings.java
+++ b/src/com/android/settings/notification/zen/ZenModeSoundVibrationSettings.java
@@ -21,14 +21,17 @@
 
 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 @@
     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 @@
         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;
     }
 
diff --git a/src/com/android/settings/notification/zen/ZenModeStarredContactsPreferenceController.java b/src/com/android/settings/notification/zen/ZenModeStarredContactsPreferenceController.java
deleted file mode 100644
index 64f2010..0000000
--- a/src/com/android/settings/notification/zen/ZenModeStarredContactsPreferenceController.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.notification.zen;
-
-import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS;
-import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES;
-import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_STARRED;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.provider.Contacts;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.dashboard.DashboardFragment;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
-public class ZenModeStarredContactsPreferenceController extends
-        AbstractZenModePreferenceController implements Preference.OnPreferenceClickListener {
-    private Preference mPreference;
-    private final int mPriorityCategory;
-    private final PackageManager mPackageManager;
-
-    private Intent mStarredContactsIntent;
-    private Intent mFallbackIntent;
-
-    public ZenModeStarredContactsPreferenceController(Context context, Lifecycle lifecycle, int
-            priorityCategory, String key) {
-        super(context, key, lifecycle);
-        mPriorityCategory = priorityCategory;
-        mPackageManager = mContext.getPackageManager();
-
-        mStarredContactsIntent = new Intent(Contacts.Intents.UI.LIST_STARRED_ACTION);
-
-        mFallbackIntent =  new Intent(Intent.ACTION_MAIN);
-        mFallbackIntent.addCategory(Intent.CATEGORY_APP_CONTACTS);
-    }
-
-    @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        mPreference = screen.findPreference(KEY);
-
-        if (mPreference != null) {
-            mPreference.setOnPreferenceClickListener(this);
-        }
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return KEY;
-    }
-
-    @Override
-    public boolean isAvailable() {
-        if (mPriorityCategory == PRIORITY_CATEGORY_CALLS) {
-            return mBackend.isPriorityCategoryEnabled(PRIORITY_CATEGORY_CALLS)
-                    && mBackend.getPriorityCallSenders() == PRIORITY_SENDERS_STARRED
-                    && isIntentValid();
-        } else if (mPriorityCategory == PRIORITY_CATEGORY_MESSAGES) {
-            return mBackend.isPriorityCategoryEnabled(PRIORITY_CATEGORY_MESSAGES)
-                    && mBackend.getPriorityMessageSenders() == PRIORITY_SENDERS_STARRED
-                    && isIntentValid();
-        } else {
-            // invalid category
-            return false;
-        }
-    }
-
-    @Override
-    public CharSequence getSummary() {
-        return mBackend.getStarredContactsSummary(mContext);
-    }
-
-    @Override
-    public boolean onPreferenceClick(Preference preference) {
-        mMetricsFeatureProvider.logClickedPreference(preference,
-                 preference.getExtras().getInt(DashboardFragment.CATEGORY));
-        if (mStarredContactsIntent.resolveActivity(mPackageManager) != null) {
-            mContext.startActivity(mStarredContactsIntent);
-        } else {
-            mContext.startActivity(mFallbackIntent);
-        }
-        return true;
-    }
-
-    private boolean isIntentValid() {
-        return mStarredContactsIntent.resolveActivity(mPackageManager) != null
-                || mFallbackIntent.resolveActivity(mPackageManager) != null;
-    }
-}
diff --git a/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java b/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java
index 70567ac..106aef9 100644
--- a/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java
+++ b/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java
@@ -456,7 +456,8 @@
         }
     }
 
-    private void updateNetworkInfo() {
+    @VisibleForTesting
+    void updateNetworkInfo() {
         if (mWifiEntry.getConnectedState() == WifiEntry.CONNECTED_STATE_CONNECTED) {
             mNetwork = mWifiManager.getCurrentNetwork();
             mLinkProperties = mConnectivityManager.getLinkProperties(mNetwork);
@@ -632,7 +633,7 @@
     }
 
     private void refreshMacAddress() {
-        String macAddress = getMacAddress();
+        String macAddress = mWifiEntry.getMacAddress();
         if (macAddress == null) {
             mMacAddressPref.setVisible(false);
             return;
@@ -649,21 +650,6 @@
         refreshMacTitle();
     }
 
-    private String getMacAddress() {
-        if (mWifiEntry.isSaved() && mWifiEntry.getPrivacy() == WifiEntry.PRIVACY_RANDOMIZED_MAC) {
-            return mWifiEntry.getMacAddress();
-        }
-
-        // return device MAC address
-        final String[] macAddresses = mWifiManager.getFactoryMacAddresses();
-        if (macAddresses != null && macAddresses.length > 0) {
-            return macAddresses[0];
-        }
-
-        Log.e(TAG, "Can't get device MAC address!");
-        return null;
-    }
-
     private void updatePreference(Preference pref, String detailText) {
         if (!TextUtils.isEmpty(detailText)) {
             pref.setSummary(detailText);
@@ -969,6 +955,7 @@
      */
     @Override
     public void onUpdated() {
+        updateNetworkInfo();
         refreshPage();
 
         // Refresh the Preferences in fragment.
diff --git a/tests/robotests/src/com/android/settings/network/ActiveSubsciptionsListenerTest.java b/tests/robotests/src/com/android/settings/network/ActiveSubsciptionsListenerTest.java
index 4c7b55b..5565ca3 100644
--- a/tests/robotests/src/com/android/settings/network/ActiveSubsciptionsListenerTest.java
+++ b/tests/robotests/src/com/android/settings/network/ActiveSubsciptionsListenerTest.java
@@ -108,6 +108,10 @@
         private ActiveSubsciptionsListenerImpl(Looper looper, Context context) {
             super(looper, context);
         }
+
+        @Override
+        void registerForSubscriptionsChange() {}
+
         public void onChanged() {}
     }
 
diff --git a/tests/robotests/src/com/android/settings/network/SubscriptionsChangeListenerTest.java b/tests/robotests/src/com/android/settings/network/SubscriptionsChangeListenerTest.java
index 9f302df..d075655 100644
--- a/tests/robotests/src/com/android/settings/network/SubscriptionsChangeListenerTest.java
+++ b/tests/robotests/src/com/android/settings/network/SubscriptionsChangeListenerTest.java
@@ -83,7 +83,7 @@
         initListener(false);
         verify(contentResolver, never()).registerContentObserver(any(Uri.class), anyBoolean(),
                 any(ContentObserver.class));
-        verify(mSubscriptionManager, never()).addOnSubscriptionsChangedListener(any());
+        verify(mSubscriptionManager, never()).addOnSubscriptionsChangedListener(any(), any());
         verify(mContext, never()).registerReceiver(any(), any());
     }
 
@@ -92,7 +92,7 @@
         initListener(true);
         final ArgumentCaptor<SubscriptionManager.OnSubscriptionsChangedListener> captor =
                 ArgumentCaptor.forClass(SubscriptionManager.OnSubscriptionsChangedListener.class);
-        verify(mSubscriptionManager).addOnSubscriptionsChangedListener(captor.capture());
+        verify(mSubscriptionManager).addOnSubscriptionsChangedListener(any(), captor.capture());
         captor.getValue().onSubscriptionsChanged();
         verify(mClient).onSubscriptionsChanged();
     }
diff --git a/tests/robotests/src/com/android/settings/notification/app/BubblePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/BubblePreferenceControllerTest.java
index 404625e..c2c45cb 100644
--- a/tests/robotests/src/com/android/settings/notification/app/BubblePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/app/BubblePreferenceControllerTest.java
@@ -122,7 +122,7 @@
     }
 
     @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 @@
         when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
         mController.onResume(appRow, channel, null, null, null, null);
 
-        assertFalse(mController.isAvailable());
+        assertTrue(mController.isAvailable());
     }
 
     @Test
@@ -200,18 +200,6 @@
     }
 
     @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);
         when(channel.getId()).thenReturn("something");
diff --git a/tests/robotests/src/com/android/settings/notification/app/ConversationImportantPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/ConversationImportantPreferenceControllerTest.java
deleted file mode 100644
index 42b7859..0000000
--- a/tests/robotests/src/com/android/settings/notification/app/ConversationImportantPreferenceControllerTest.java
+++ /dev/null
@@ -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();
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/notification/app/ConversationPriorityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/ConversationPriorityPreferenceControllerTest.java
new file mode 100644
index 0000000..d74715c
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/app/ConversationPriorityPreferenceControllerTest.java
@@ -0,0 +1,277 @@
+/*
+ * 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.app.NotificationManager.IMPORTANCE_LOW;
+
+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 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 ConversationPriorityPreferenceControllerTest {
+
+    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 ConversationPriorityPreferenceController 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 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_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.getImportance()).thenReturn(IMPORTANCE_HIGH);
+        mController.onResume(new NotificationBackend.AppRow(), channel, null, null, null, mock(
+                RestrictedLockUtils.EnforcedAdmin.class));
+
+        Preference pref = new ConversationPriorityPreference(mContext, null);
+        mController.updateState(pref);
+
+        assertFalse(pref.isEnabled());
+    }
+
+    @Test
+    public void testUpdateState_notConfigurable() {
+        NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+        NotificationChannel channel = mock(NotificationChannel.class);
+        when(channel.isImportanceLockedByOEM()).thenReturn(true);
+        when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
+        mController.onResume(appRow, channel, null, null, null, null);
+
+        Preference pref = new ConversationPriorityPreference(mContext, null);
+        mController.updateState(pref);
+
+        assertFalse(pref.isEnabled());
+    }
+
+    @Test
+    public void testUpdateState_systemButConfigurable() {
+        NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+        appRow.systemApp = true;
+        NotificationChannel channel = mock(NotificationChannel.class);
+        when(channel.isImportanceLockedByOEM()).thenReturn(false);
+        when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
+        mController.onResume(appRow, channel, null, null, null, null);
+
+        Preference pref = new ConversationPriorityPreference(mContext, null);
+        mController.updateState(pref);
+
+        assertTrue(pref.isEnabled());
+    }
+
+    @Test
+    public void testUpdateState_defaultApp() {
+        NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+        appRow.systemApp = true;
+        NotificationChannel channel = mock(NotificationChannel.class);
+        when(channel.isImportanceLockedByCriticalDeviceFunction()).thenReturn(true);
+        when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
+        mController.onResume(appRow, channel, null, null, null, null);
+
+        Preference pref = new ConversationPriorityPreference(mContext, null);
+        mController.updateState(pref);
+
+        assertTrue(pref.isEnabled());
+    }
+
+    @Test
+    public void testUpdateState() {
+        NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+        channel.setImportantConversation(true);
+        channel.setOriginalImportance(IMPORTANCE_DEFAULT);
+        mController.onResume(appRow, channel, null, null, null, null);
+
+        ConversationPriorityPreference pref = mock(ConversationPriorityPreference.class);
+        mController.updateState(pref);
+
+        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 testImportanceLowToImportant() {
+        NotificationChannel channel =
+                new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_LOW);
+        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, 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());
+        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());
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/app/ConversationPriorityPreferenceTest.java b/tests/robotests/src/com/android/settings/notification/app/ConversationPriorityPreferenceTest.java
new file mode 100644
index 0000000..12e1f35
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/app/ConversationPriorityPreferenceTest.java
@@ -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));
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/app/DefaultImportancePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/DefaultImportancePreferenceControllerTest.java
deleted file mode 100644
index 5b85322..0000000
--- a/tests/robotests/src/com/android/settings/notification/app/DefaultImportancePreferenceControllerTest.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.notification.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.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.assertTrue;
-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 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 DefaultImportancePreferenceControllerTest {
-
-    private Context mContext;
-    @Mock
-    private NotificationManager mNm;
-    @Mock
-    private NotificationBackend mBackend;
-    @Mock
-    private NotificationSettings.DependentFieldListener mDependentFieldListener;
-    @Mock
-    private UserManager mUm;
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private PreferenceScreen mScreen;
-
-    private DefaultImportancePreferenceController 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 DefaultImportancePreferenceController(
-                mContext, mDependentFieldListener, mBackend));
-    }
-
-    @Test
-    public void testNoCrashIfNoOnResume() {
-        mController.isAvailable();
-        mController.updateState(mock(Preference.class));
-    }
-
-    @Test
-    public void testIsAvailable_notIfNull() {
-        mController.onResume(null, null, null, null, null, null);
-        assertFalse(mController.isAvailable());
-    }
-
-    @Test
-    public void testIsAvailable_ifAppBlocked() {
-        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);
-        assertFalse(mController.isAvailable());
-    }
-
-    @Test
-    public void testIsAvailable() {
-        NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
-        NotificationChannel channel = mock(NotificationChannel.class);
-        when(channel.getImportance()).thenReturn(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.getImportance()).thenReturn(IMPORTANCE_HIGH);
-        mController.onResume(new NotificationBackend.AppRow(), channel, null, null, null, mock(
-                RestrictedLockUtils.EnforcedAdmin.class));
-
-        Preference pref = new RestrictedSwitchPreference(mContext, null);
-        mController.updateState(pref);
-
-        assertFalse(pref.isEnabled());
-    }
-
-    @Test
-    public void testUpdateState_notConfigurable() {
-        NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
-        NotificationChannel channel = mock(NotificationChannel.class);
-        when(channel.isImportanceLockedByOEM()).thenReturn(true);
-        when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
-        mController.onResume(appRow, channel, null, null, null, null);
-
-        Preference pref = new RestrictedSwitchPreference(mContext, null);
-        mController.updateState(pref);
-
-        assertFalse(pref.isEnabled());
-    }
-
-    @Test
-    public void testUpdateState_systemButConfigurable() {
-        NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
-        appRow.systemApp = true;
-        NotificationChannel channel = mock(NotificationChannel.class);
-        when(channel.isImportanceLockedByOEM()).thenReturn(false);
-        when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
-        mController.onResume(appRow, channel, null, null, null, null);
-
-        Preference pref = new RestrictedSwitchPreference(mContext, null);
-        mController.updateState(pref);
-
-        assertTrue(pref.isEnabled());
-    }
-
-    @Test
-    public void testUpdateState_defaultApp() {
-        NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
-        appRow.systemApp = true;
-        NotificationChannel channel = mock(NotificationChannel.class);
-        when(channel.isImportanceLockedByCriticalDeviceFunction()).thenReturn(true);
-        when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
-        mController.onResume(appRow, channel, null, null, null, null);
-
-        Preference pref = new RestrictedSwitchPreference(mContext, null);
-        mController.updateState(pref);
-
-        assertTrue(pref.isEnabled());
-    }
-
-    @Test
-    public void testUpdateState_default() {
-        NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
-        mController.onResume(appRow, channel, null, null, null, null);
-
-        RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
-        mController.updateState(pref);
-
-        assertTrue(pref.isChecked());
-    }
-
-    @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() {
-        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);
-        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
-        mController.displayPreference(mScreen);
-        mController.updateState(pref);
-
-        mController.onPreferenceChange(pref, true);
-
-        assertEquals(IMPORTANCE_DEFAULT, channel.getImportance());
-        verify(mDependentFieldListener, times(1)).onFieldValueChanged();
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModeBypassingAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModeBypassingAppsPreferenceControllerTest.java
index 8760d4c..a6efaaf 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenModeBypassingAppsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModeBypassingAppsPreferenceControllerTest.java
@@ -18,16 +18,23 @@
 
 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.RuntimeEnvironment;
 import org.robolectric.util.ReflectionHelpers;
 
+import java.util.ArrayList;
+import java.util.List;
+
 @RunWith(RobolectricTestRunner.class)
 public class ZenModeBypassingAppsPreferenceControllerTest {
 
@@ -45,30 +55,156 @@
     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();
     }
 }
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceControllerTest.java
index 1583b91..a8a8a7a 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceControllerTest.java
@@ -19,173 +19,131 @@
 import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE;
 import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
 import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_NONE;
-import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS;
-import static android.provider.Settings.Global.ZEN_MODE;
-import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
-import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
 
+import static com.android.settings.notification.zen.ZenModePriorityConversationsPreferenceController.KEY_ALL;
+import static com.android.settings.notification.zen.ZenModePriorityConversationsPreferenceController.KEY_IMPORTANT;
+import static com.android.settings.notification.zen.ZenModePriorityConversationsPreferenceController.KEY_NONE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.NotificationManager;
 import android.content.ContentResolver;
 import android.content.Context;
-import android.provider.Settings;
 
-import androidx.preference.ListPreference;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
 import androidx.preference.PreferenceScreen;
 
-import com.android.settings.R;
+import com.android.settings.notification.NotificationBackend;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
-import org.robolectric.shadows.ShadowApplication;
 import org.robolectric.util.ReflectionHelpers;
 
+import java.util.List;
+
 @RunWith(RobolectricTestRunner.class)
 public class ZenModePriorityConversationsPreferenceControllerTest {
 
     private ZenModePriorityConversationsPreferenceController mController;
 
     @Mock
-    private ZenModeBackend mBackend;
+    private ZenModeBackend mZenBackend;
     @Mock
-    private NotificationManager mNotificationManager;
-    @Mock
-    private ListPreference mockPref;
+    private PreferenceCategory mMockPrefCategory;
     @Mock
     private NotificationManager.Policy mPolicy;
     @Mock
     private PreferenceScreen mPreferenceScreen;
+    @Mock
+    private NotificationBackend mNotifBackend;
+
+    private List<RadioButtonPreference> mRadioButtonPreferences;
     private ContentResolver mContentResolver;
     private Context mContext;
-
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
-        ShadowApplication shadowApplication = ShadowApplication.getInstance();
-        shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
-
         mContext = RuntimeEnvironment.application;
-        mContentResolver = RuntimeEnvironment.application.getContentResolver();
-        when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
-
-        when(mBackend.getPriorityConversationSenders())
-            .thenReturn(CONVERSATION_SENDERS_IMPORTANT);
-        when(mBackend.getAlarmsTotalSilencePeopleSummary(PRIORITY_CATEGORY_CONVERSATIONS))
-                .thenCallRealMethod();
-        when(mBackend.getConversationSummary()).thenCallRealMethod();
-
         mController = new ZenModePriorityConversationsPreferenceController(
-                mContext, mock(Lifecycle.class));
-        ReflectionHelpers.setField(mController, "mBackend", mBackend);
+                mContext, "test_key", mock(Lifecycle.class), mNotifBackend);
+        ReflectionHelpers.setField(mController, "mBackend", mZenBackend);
 
-        when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+        when(mMockPrefCategory.getContext()).thenReturn(mContext);
+        when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
+                .thenReturn(mMockPrefCategory);
+        captureRadioButtons();
+    }
+
+    @Test
+    public void displayPreference_radioButtonsCreatedOnlyOnce() {
+        when(mMockPrefCategory.findPreference(any())).thenReturn(mock(Preference.class));
+
+        // radio buttons were already created, so don't re-create them
         mController.displayPreference(mPreferenceScreen);
+        verify(mMockPrefCategory, never()).addPreference(any());
     }
 
     @Test
-    public void updateState_TotalSilence() {
-        Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_NO_INTERRUPTIONS);
+    public void clickAllConversations() {
+        RadioButtonPreference allConversationsRb = getButton(KEY_ALL);
+        allConversationsRb.onClick();
 
-        when(mBackend.isPriorityCategoryEnabled(PRIORITY_CATEGORY_CONVERSATIONS)).thenReturn(true);
-        final ListPreference mockPref = mock(ListPreference.class);
-        mController.updateState(mockPref);
-
-        verify(mockPref).setEnabled(false);
-        verify(mockPref).setSummary(R.string.zen_mode_from_no_conversations);
+        verify(mZenBackend).saveConversationSenders(CONVERSATION_SENDERS_ANYONE);
     }
 
     @Test
-    public void updateState_AlarmsOnly() {
-        Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_ALARMS);
+    public void clickImportantConversations() {
+        RadioButtonPreference importantConversationsRb = getButton(KEY_IMPORTANT);
+        importantConversationsRb.onClick();
 
-        final ListPreference mockPref = mock(ListPreference.class);
-        mController.updateState(mockPref);
-
-        verify(mockPref).setEnabled(false);
-        verify(mockPref).setSummary(R.string.zen_mode_from_no_conversations);
+        verify(mZenBackend).saveConversationSenders(CONVERSATION_SENDERS_IMPORTANT);
     }
 
     @Test
-    public void updateState_Priority_important() {
-        Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
-        when(mBackend.isPriorityCategoryEnabled(PRIORITY_CATEGORY_CONVERSATIONS)).thenReturn(true);
+    public void clickNoConversations() {
+        RadioButtonPreference noConversationsRb = getButton(KEY_NONE);
+        noConversationsRb.onClick();
 
-        mController.updateState(mockPref);
-
-        verify(mockPref).setEnabled(true);
-        verify(mockPref).setSummary(R.string.zen_mode_from_important_conversations);
-        verify(mockPref).setValue(String.valueOf(CONVERSATION_SENDERS_IMPORTANT));
+        verify(mZenBackend)
+                .saveConversationSenders(CONVERSATION_SENDERS_NONE);
     }
 
-    @Test
-    public void updateState_Priority_all() {
-        Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
-        when(mBackend.getPriorityConversationSenders()).thenReturn(CONVERSATION_SENDERS_ANYONE);
-        when(mBackend.isPriorityCategoryEnabled(PRIORITY_CATEGORY_CONVERSATIONS)).thenReturn(true);
+    private void captureRadioButtons() {
+        ArgumentCaptor<RadioButtonPreference> rbCaptor =
+                ArgumentCaptor.forClass(RadioButtonPreference.class);
+        mController.displayPreference(mPreferenceScreen);
 
+        // verifies 3 buttons were added
+        verify(mMockPrefCategory, times(3)).addPreference(rbCaptor.capture());
+        mRadioButtonPreferences = rbCaptor.getAllValues();
+        assertThat(mRadioButtonPreferences.size()).isEqualTo(3);
 
-        mController.updateState(mockPref);
-
-        verify(mockPref).setEnabled(true);
-        verify(mockPref).setSummary(R.string.zen_mode_from_all_conversations);
-        verify(mockPref).setValue(String.valueOf(CONVERSATION_SENDERS_ANYONE));
+        reset(mMockPrefCategory);
     }
 
-    @Test
-    public void updateState_Priority_none() {
-        Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
-        when(mBackend.getPriorityConversationSenders()).thenReturn(CONVERSATION_SENDERS_NONE);
-        when(mBackend.isPriorityCategoryEnabled(PRIORITY_CATEGORY_CONVERSATIONS)).thenReturn(false);
-
-        mController.updateState(mockPref);
-
-        verify(mockPref).setEnabled(true);
-        verify(mockPref).setSummary(R.string.zen_mode_from_no_conversations);
-        verify(mockPref).setValue(String.valueOf(CONVERSATION_SENDERS_NONE));
-    }
-
-    @Test
-    public void onPreferenceChange_noneToImportant() {
-        // start with none
-
-        Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
-        when(mBackend.getPriorityConversationSenders()).thenReturn(CONVERSATION_SENDERS_NONE);
-        when(mBackend.isPriorityCategoryEnabled(PRIORITY_CATEGORY_CONVERSATIONS)).thenReturn(false);
-
-        mController.updateState(mockPref);
-        reset(mBackend);
-
-        mController.onPreferenceChange(mockPref, String.valueOf(CONVERSATION_SENDERS_IMPORTANT));
-
-        verify(mBackend).saveConversationSenders(CONVERSATION_SENDERS_IMPORTANT);
-        verify(mBackend).getPriorityConversationSenders();
-    }
-
-    @Test
-    public void onPreferenceChange_allToNone() {
-        // start with none
-
-        Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
-        when(mBackend.getPriorityConversationSenders()).thenReturn(CONVERSATION_SENDERS_ANYONE);
-        when(mBackend.isPriorityCategoryEnabled(PRIORITY_CATEGORY_CONVERSATIONS)).thenReturn(true);
-
-        mController.updateState(mockPref);
-        reset(mBackend);
-
-        mController.onPreferenceChange(mockPref, String.valueOf(CONVERSATION_SENDERS_NONE));
-
-        verify(mBackend).saveConversationSenders(CONVERSATION_SENDERS_NONE);
-        verify(mBackend).getPriorityConversationSenders();
+    private RadioButtonPreference getButton(String key) {
+        for (RadioButtonPreference pref : mRadioButtonPreferences) {
+            if (key.equals(pref.getKey())) {
+                return pref;
+            }
+        }
+        return null;
     }
 }
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityMessagesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityMessagesPreferenceControllerTest.java
deleted file mode 100644
index 7af2211..0000000
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityMessagesPreferenceControllerTest.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.notification.zen;
-
-import static android.provider.Settings.Global.ZEN_MODE;
-import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
-import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.NotificationManager;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.provider.Settings;
-
-import androidx.preference.ListPreference;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.R;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.shadows.ShadowApplication;
-import org.robolectric.util.ReflectionHelpers;
-
-@RunWith(RobolectricTestRunner.class)
-public class ZenModePriorityMessagesPreferenceControllerTest {
-
-    private ZenModePriorityMessagesPreferenceController mController;
-
-    @Mock
-    private ZenModeBackend mBackend;
-    @Mock
-    private NotificationManager mNotificationManager;
-    @Mock
-    private ListPreference mockPref;
-    @Mock
-    private NotificationManager.Policy mPolicy;
-    @Mock
-    private PreferenceScreen mPreferenceScreen;
-    private ContentResolver mContentResolver;
-    private Context mContext;
-
-    /**
-     * Array Values Key
-     * 0: anyone
-     * 1: contacts
-     * 2: starred
-     * 3: none
-     */
-    private String[] mValues;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        ShadowApplication shadowApplication = ShadowApplication.getInstance();
-        shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
-
-        mContext = RuntimeEnvironment.application;
-        mValues = mContext.getResources().getStringArray(R.array.zen_mode_contacts_values);
-        mContentResolver = RuntimeEnvironment.application.getContentResolver();
-        when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
-
-        when(mBackend.getPriorityMessageSenders())
-            .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_STARRED);
-        when(mBackend.getAlarmsTotalSilencePeopleSummary(
-                NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)).thenCallRealMethod();
-        when(mBackend.getContactsSummary(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES))
-                .thenCallRealMethod();
-
-        mController = new ZenModePriorityMessagesPreferenceController(mContext, mock(Lifecycle.class));
-        ReflectionHelpers.setField(mController, "mBackend", mBackend);
-
-        when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
-        mController.displayPreference(mPreferenceScreen);
-    }
-
-    @Test
-    public void updateState_TotalSilence() {
-        Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_NO_INTERRUPTIONS);
-
-        when(mBackend.isPriorityCategoryEnabled(
-                NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES))
-                .thenReturn(false);
-        final ListPreference mockPref = mock(ListPreference.class);
-        mController.updateState(mockPref);
-
-        verify(mockPref).setEnabled(false);
-        verify(mockPref).setSummary(R.string.zen_mode_from_none_messages);
-    }
-
-    @Test
-    public void updateState_AlarmsOnly() {
-        Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_ALARMS);
-
-        final ListPreference mockPref = mock(ListPreference.class);
-        mController.updateState(mockPref);
-
-        verify(mockPref).setEnabled(false);
-        verify(mockPref).setSummary(R.string.zen_mode_from_none_messages);
-    }
-
-    @Test
-    public void updateState_Priority() {
-        Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
-
-        when(mBackend.isPriorityCategoryEnabled(
-                NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES))
-                .thenReturn(true);
-
-        mController.updateState(mockPref);
-
-        verify(mockPref).setEnabled(true);
-        verify(mockPref).setSummary(R.string.zen_mode_from_starred);
-    }
-
-    @Test
-    public void onPreferenceChange_setSelectedContacts_any() {
-        Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
-        when(mBackend.getPriorityMessageSenders()).thenReturn(
-                NotificationManager.Policy.PRIORITY_SENDERS_ANY);
-        mController.updateState(mockPref);
-        verify(mockPref).setValue(mValues[mController.getIndexOfSendersValue(
-                ZenModeBackend.ZEN_MODE_FROM_ANYONE)]);
-    }
-
-    @Test
-    public void onPreferenceChange_setSelectedContacts_none() {
-        Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
-        when(mBackend.getPriorityMessageSenders()).thenReturn(ZenModeBackend.SOURCE_NONE);
-        mController.updateState(mockPref);
-        verify(mockPref).setValue(mValues[mController.getIndexOfSendersValue(
-                ZenModeBackend.ZEN_MODE_FROM_NONE)]);
-    }
-
-    @Test
-    public void onPreferenceChange_setSelectedContacts_starred() {
-        Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
-        when(mBackend.getPriorityMessageSenders()).thenReturn(
-                NotificationManager.Policy.PRIORITY_SENDERS_STARRED);
-        mController.updateState(mockPref);
-        verify(mockPref).setValue(mValues[mController.getIndexOfSendersValue(
-                ZenModeBackend.ZEN_MODE_FROM_STARRED)]);
-    }
-
-    @Test
-    public void onPreferenceChange_setSelectedContacts_contacts() {
-        Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
-        when(mBackend.getPriorityMessageSenders()).thenReturn(
-                NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS);
-        mController.updateState(mockPref);
-        verify(mockPref).setValue(mValues[mController.getIndexOfSendersValue(
-                ZenModeBackend.ZEN_MODE_FROM_CONTACTS)]);
-    }
-}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceControllerTest.java
new file mode 100644
index 0000000..7dde1cd
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModePrioritySendersPreferenceControllerTest.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification.zen;
+
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES;
+import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_ANY;
+import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS;
+import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_STARRED;
+
+import static com.android.settings.notification.zen.ZenModePrioritySendersPreferenceController.KEY_ANY;
+import static com.android.settings.notification.zen.ZenModePrioritySendersPreferenceController.KEY_CONTACTS;
+import static com.android.settings.notification.zen.ZenModePrioritySendersPreferenceController.KEY_NONE;
+import static com.android.settings.notification.zen.ZenModePrioritySendersPreferenceController.KEY_STARRED;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.ContentResolver;
+import android.content.Context;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.notification.NotificationBackend;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.ReflectionHelpers;
+
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+public class ZenModePrioritySendersPreferenceControllerTest {
+
+    private ZenModePrioritySendersPreferenceController mMessagesController;
+
+    @Mock
+    private ZenModeBackend mZenBackend;
+    @Mock
+    private PreferenceCategory mMockPrefCategory;
+    @Mock
+    private NotificationManager.Policy mPolicy;
+    @Mock
+    private PreferenceScreen mPreferenceScreen;
+    @Mock
+    private NotificationBackend mNotifBackend;
+
+    private List<RadioButtonPreference> mRadioButtonPreferences;
+    private ContentResolver mContentResolver;
+    private Context mContext;
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        mMessagesController = new ZenModePrioritySendersPreferenceController(
+                mContext, "test_key_messages", mock(Lifecycle.class), true);
+        ReflectionHelpers.setField(mMessagesController, "mBackend", mZenBackend);
+
+        when(mMockPrefCategory.getContext()).thenReturn(mContext);
+        when(mPreferenceScreen.findPreference(mMessagesController.getPreferenceKey()))
+                .thenReturn(mMockPrefCategory);
+        captureRadioButtons();
+    }
+
+    @Test
+    public void displayPreference_radioButtonsCreatedOnlyOnce() {
+        when(mMockPrefCategory.findPreference(any())).thenReturn(mock(Preference.class));
+
+        // radio buttons were already created, so don't re-create them
+        mMessagesController.displayPreference(mPreferenceScreen);
+        verify(mMockPrefCategory, never()).addPreference(any());
+    }
+
+    @Test
+    public void clickAnySenders() {
+        // GIVEN current priority message senders are STARRED
+        when(mZenBackend.getPriorityMessageSenders()).thenReturn(PRIORITY_SENDERS_STARRED);
+
+        // WHEN user clicks the any senders option
+        RadioButtonPreference allSendersRb = getButton(KEY_ANY);
+        allSendersRb.onClick();
+
+        // THEN any senders gets saved as priority senders for messages
+        verify(mZenBackend).saveSenders(PRIORITY_CATEGORY_MESSAGES, PRIORITY_SENDERS_ANY);
+    }
+
+    @Test
+    public void clickStarredSenders() {
+        // GIVEN current priority message senders are ANY
+        when(mZenBackend.getPriorityMessageSenders()).thenReturn(PRIORITY_SENDERS_ANY);
+
+        // WHEN user clicks the starred contacts option
+        RadioButtonPreference starredRb = getButton(KEY_STARRED);
+        starredRb.onClick();
+
+        // THEN starred contacts gets saved as priority senders for messages
+        verify(mZenBackend).saveSenders(PRIORITY_CATEGORY_MESSAGES, PRIORITY_SENDERS_STARRED);
+    }
+
+    @Test
+    public void clickContactsSenders() {
+        // GIVEN current priority message senders are ANY
+        when(mZenBackend.getPriorityMessageSenders()).thenReturn(PRIORITY_SENDERS_ANY);
+
+        // WHEN user clicks the contacts only option
+        RadioButtonPreference contactsRb = getButton(KEY_CONTACTS);
+        contactsRb.onClick();
+
+        // THEN contacts gets saved as priority senders for messages
+        verify(mZenBackend).saveSenders(PRIORITY_CATEGORY_MESSAGES, PRIORITY_SENDERS_CONTACTS);
+    }
+
+    @Test
+    public void clickNoSenders() {
+        // GIVEN current priority message senders are ANY
+        when(mZenBackend.getPriorityMessageSenders()).thenReturn(PRIORITY_SENDERS_ANY);
+
+        // WHEN user clicks the no senders option
+        RadioButtonPreference noSenders = getButton(KEY_NONE);
+        noSenders.onClick();
+
+        // THEN no senders gets saved as priority senders for messages
+        verify(mZenBackend).saveSenders(PRIORITY_CATEGORY_MESSAGES, ZenModeBackend.SOURCE_NONE);
+    }
+
+    @Test
+    public void clickSameOptionMultipleTimes() {
+        // GIVEN current priority message senders are ANY
+        when(mZenBackend.getPriorityMessageSenders()).thenReturn(PRIORITY_SENDERS_ANY);
+
+        // WHEN user clicks the any senders option multiple times again
+        RadioButtonPreference anySenders = getButton(KEY_ANY);
+        anySenders.onClick();
+        anySenders.onClick();
+        anySenders.onClick();
+
+        // THEN no senders are saved because this setting is already in effect
+        verify(mZenBackend, never()).saveSenders(PRIORITY_CATEGORY_MESSAGES, PRIORITY_SENDERS_ANY);
+    }
+
+    private void captureRadioButtons() {
+        ArgumentCaptor<RadioButtonPreference> rbCaptor =
+                ArgumentCaptor.forClass(RadioButtonPreference.class);
+        mMessagesController.displayPreference(mPreferenceScreen);
+
+        // verifies 4 buttons were added
+        verify(mMockPrefCategory, times(4)).addPreference(rbCaptor.capture());
+        mRadioButtonPreferences = rbCaptor.getAllValues();
+        assertThat(mRadioButtonPreferences.size()).isEqualTo(4);
+
+        reset(mMockPrefCategory);
+    }
+
+    private RadioButtonPreference getButton(String key) {
+        for (RadioButtonPreference pref : mRadioButtonPreferences) {
+            if (key.equals(pref.getKey())) {
+                return pref;
+            }
+        }
+        return null;
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModeSettingsTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModeSettingsTest.java
index da185ad..d3c3a85 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenModeSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModeSettingsTest.java
@@ -98,34 +98,6 @@
     }
 
     @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
                 .getXmlResourcesToIndex(mContext, true /* enabled */);
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModeStarredContactsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModeStarredContactsPreferenceControllerTest.java
deleted file mode 100644
index f27367a..0000000
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenModeStarredContactsPreferenceControllerTest.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.notification.zen;
-
-import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS;
-import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.app.NotificationManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.notification.zen.ZenModeBackend;
-import com.android.settings.notification.zen.ZenModeStarredContactsPreferenceController;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.shadows.ShadowApplication;
-import org.robolectric.util.ReflectionHelpers;
-
-
-@RunWith(RobolectricTestRunner.class)
-public class ZenModeStarredContactsPreferenceControllerTest {
-
-    private ZenModeStarredContactsPreferenceController mCallsController;
-    private ZenModeStarredContactsPreferenceController mMessagesController;
-
-    @Mock
-    private ZenModeBackend mBackend;
-    @Mock
-    private NotificationManager mNotificationManager;
-    @Mock
-    private Preference mockPref;
-    @Mock
-    private NotificationManager.Policy mPolicy;
-    @Mock
-    private PreferenceScreen mPreferenceScreen;
-    @Mock
-    private Intent testIntent;
-    @Mock
-    private ComponentName mComponentName;
-    private Context mContext;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        ShadowApplication shadowApplication = ShadowApplication.getInstance();
-        shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
-
-        mContext = RuntimeEnvironment.application;
-        when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
-        when(testIntent.resolveActivity(any())).thenReturn(mComponentName);
-
-        mCallsController = new ZenModeStarredContactsPreferenceController(
-                mContext, mock(Lifecycle.class), PRIORITY_CATEGORY_CALLS,
-                "zen_mode_starred_contacts_callers");
-        ReflectionHelpers.setField(mCallsController, "mBackend", mBackend);
-        ReflectionHelpers.setField(mCallsController, "mStarredContactsIntent", testIntent);
-        when(mPreferenceScreen.findPreference(mCallsController.getPreferenceKey()))
-                .thenReturn(mockPref);
-        mCallsController.displayPreference(mPreferenceScreen);
-
-        mMessagesController = new ZenModeStarredContactsPreferenceController(
-                mContext, mock(Lifecycle.class), PRIORITY_CATEGORY_MESSAGES,
-                "zen_mode_starred_contacts_messages");
-        ReflectionHelpers.setField(mMessagesController, "mBackend", mBackend);
-        ReflectionHelpers.setField(mMessagesController, "mStarredContactsIntent", testIntent);
-        when(mPreferenceScreen.findPreference(mMessagesController.getPreferenceKey()))
-                .thenReturn(mockPref);
-        mMessagesController.displayPreference(mPreferenceScreen);
-    }
-
-    @Test
-    public void isAvailable_noCallers() {
-        when(mBackend.isPriorityCategoryEnabled(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS))
-                .thenReturn(false);
-        assertThat(mCallsController.isAvailable()).isFalse();
-    }
-
-    @Test
-    public void isAvailable_anyCallers() {
-        when(mBackend.isPriorityCategoryEnabled(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS))
-                .thenReturn(true);
-        when(mBackend.getPriorityCallSenders())
-                .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_ANY);
-
-        assertThat(mCallsController.isAvailable()).isFalse();
-    }
-
-    @Test
-    public void isAvailable_starredCallers() {
-        when(mBackend.isPriorityCategoryEnabled(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS))
-                .thenReturn(true);
-        when(mBackend.getPriorityCallSenders())
-                .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_STARRED);
-
-        assertThat(mCallsController.isAvailable()).isTrue();
-    }
-
-    @Test
-    public void isAvailable_noMessages() {
-        when(mBackend.isPriorityCategoryEnabled(
-                NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)).thenReturn(false);
-        assertThat(mMessagesController.isAvailable()).isFalse();
-    }
-
-    @Test
-    public void isAvailable_anyMessages() {
-        when(mBackend.isPriorityCategoryEnabled(
-                NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)).thenReturn(true);
-        when(mBackend.getPriorityMessageSenders())
-                .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_ANY);
-
-        assertThat(mMessagesController.isAvailable()).isFalse();
-    }
-
-    @Test
-    public void isAvailable_starredMessageContacts() {
-        when(mBackend.isPriorityCategoryEnabled(
-                NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)).thenReturn(true);
-        when(mBackend.getPriorityMessageSenders())
-                .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_STARRED);
-
-        assertThat(mMessagesController.isAvailable()).isTrue();
-    }
-
-    @Test
-    public void nullPreference_displayPreference() {
-        when(mPreferenceScreen.findPreference(mMessagesController.getPreferenceKey()))
-                .thenReturn(null);
-
-        // should not throw a null pointer
-        mMessagesController.displayPreference(mPreferenceScreen);
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2Test.java b/tests/robotests/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2Test.java
index be5e1af..70b232a 100644
--- a/tests/robotests/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2Test.java
+++ b/tests/robotests/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2Test.java
@@ -46,7 +46,6 @@
 import android.net.IpPrefix;
 import android.net.LinkAddress;
 import android.net.LinkProperties;
-import android.net.MacAddress;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
@@ -81,6 +80,7 @@
 import com.android.settingslib.widget.LayoutPreference;
 import com.android.wifitrackerlib.NetworkDetailsTracker;
 import com.android.wifitrackerlib.WifiEntry;
+import com.android.wifitrackerlib.WifiEntry.ConnectCallback;
 
 import org.junit.Before;
 import org.junit.Ignore;
@@ -109,8 +109,6 @@
 import java.util.stream.Collectors;
 
 // TODO(b/143326832): Should add test cases for connect button.
-// TODO(b/143326832): WifiEntry is not mature, should remove @Ignore after it's constructed.
-@Ignore
 @RunWith(RobolectricTestRunner.class)
 @Config(shadows = {ShadowDevicePolicyManager.class, ShadowEntityHeaderController.class})
 public class WifiDetailPreferenceController2Test {
@@ -123,8 +121,7 @@
     private static final String MAC_ADDRESS = "01:23:45:67:89:ab";
     private static final String RANDOMIZED_MAC_ADDRESS = "RANDOMIZED_MAC_ADDRESS";
     private static final String FACTORY_MAC_ADDRESS = "FACTORY_MAC_ADDRESS";
-    // TODO(b/143326832): Add WifiEntry#getSecurityString
-    //private static final String SECURITY = "None";
+    private static final String SECURITY = "None";
     private static final String FQDN = "fqdn";
 
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
@@ -156,8 +153,6 @@
     private WifiDetailPreferenceController2.IconInjector mMockIconInjector;
     @Mock
     private WifiDetailPreferenceController2.Clock mMockClock;
-    @Mock
-    private MacAddress mMockMacAddress;
 
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private EntityHeaderController mMockHeaderController;
@@ -270,9 +265,9 @@
 
         when(mContext.getPackageManager()).thenReturn(mMockPackageManager);
         when(mMockWifiEntry.getLevel()).thenReturn(LEVEL);
-        // TODO(b/143326832): Add WifiEntry#getSecurityString
-        //when(mMockWifiEntry.getSecurityString(false)).thenReturn(SECURITY);
+        when(mMockWifiEntry.getSecurityString(false /* concise */)).thenReturn(SECURITY);
         when(mMockWifiEntry.getTitle()).thenReturn(SSID);
+        when(mMockWifiEntry.getWifiConfiguration()).thenReturn(mMockWifiConfig);
         when(mMockConnectivityManager.getNetworkInfo(any(Network.class)))
                 .thenReturn(mMockNetworkInfo);
         doNothing().when(mMockConnectivityManager).registerNetworkCallback(
@@ -393,7 +388,6 @@
         assertThat(mController.isAvailable()).isTrue();
     }
 
-    /* TODO(b/143326832): Add WifiEntry#getSecurityString
     @Test
     public void securityPreference_stringShouldBeSet() {
         setUpForConnectedNetwork();
@@ -401,7 +395,6 @@
 
         verify(mMockSecurityPref).setSummary(SECURITY);
     }
-    */
 
     @Test
     public void latestWifiInfo_shouldBeFetchedInDisplayPreferenceForConnectedNetwork() {
@@ -541,6 +534,7 @@
         updateLinkProperties(lp);
     }
 
+    @Ignore
     @Test
     public void entityHeader_shouldShowShortRemainingTime() {
         // Expires in 1h, 2min, 15sec
@@ -557,6 +551,7 @@
         inOrder.verify(mMockHeaderController).setSecondSummary((String) null);
     }
 
+    @Ignore
     @Test
     public void entityHeader_shouldShowExpiryDate() {
         // Expires in 49h, 2min, 15sec
@@ -724,77 +719,68 @@
         verify(mMockRxLinkSpeedPref, never()).setSummary(any(String.class));
     }
 
-    /* TODO(b/143326832): Support Passpoint test cases while WifiTracker2 supports it.
     @Test
-    public void ssidPref_shouldHaveDetailTextSetForPasspointR1() {
+    public void ssidPref_isSubscription_show() {
         setUpForConnectedNetwork();
-        when(mMockAccessPoint.isPasspoint()).thenReturn(true);
-        when(mMockAccessPoint.isOsuProvider()).thenReturn(false);
+        when(mMockWifiEntry.isSubscription()).thenReturn(true);
 
         displayAndResume();
 
-        verify(mMockSsidPref, times(1)).setSummary(SSID);
-        verify(mMockSsidPref, times(1)).setVisible(true);
+        verify(mMockSsidPref).setSummary(SSID);
+        verify(mMockSsidPref).setVisible(true);
     }
 
     @Test
-    public void ssidPref_shouldHaveDetailTextSetForPasspointR2() {
+    public void ssidPref_notSubscription_hide() {
         setUpForConnectedNetwork();
-        when(mMockAccessPoint.isPasspoint()).thenReturn(false);
-        when(mMockAccessPoint.isOsuProvider()).thenReturn(true);
+        when(mMockWifiEntry.isSubscription()).thenReturn(false);
 
         displayAndResume();
 
-        verify(mMockSsidPref, times(1)).setSummary(SSID);
-        verify(mMockSsidPref, times(1)).setVisible(true);
-    }
-
-    @Test
-    public void ssidPref_shouldNotShowIfNotPasspoint() {
-        setUpForConnectedNetwork();
-        when(mMockAccessPoint.isPasspoint()).thenReturn(false);
-        when(mMockAccessPoint.isOsuProvider()).thenReturn(false);
-
-        displayAndResume();
-
+        verify(mMockSsidPref, never()).setSummary(SSID);
         verify(mMockSsidPref).setVisible(false);
     }
-    */
 
     @Test
     public void macAddressPref_shouldVisibleForConnectedNetwork() {
         setUpForConnectedNetwork();
+        when(mMockWifiEntry.isSaved()).thenReturn(true);
+        when(mMockWifiEntry.getPrivacy()).thenReturn(WifiEntry.PRIVACY_DEVICE_MAC);
+        when(mMockWifiEntry.getMacAddress()).thenReturn(MAC_ADDRESS);
 
         displayAndResume();
 
         verify(mMockMacAddressPref).setVisible(true);
         verify(mMockMacAddressPref).setSummary(MAC_ADDRESS);
+        verify(mMockMacAddressPref).setTitle(R.string.wifi_advanced_device_mac_address_title);
     }
 
     @Test
     public void macAddressPref_shouldVisibleAsRandomizedForDisconnectedNetwork() {
         setUpForDisconnectedNetwork();
-        mMockWifiConfig.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT;
-        when(mMockWifiConfig.getRandomizedMacAddress()).thenReturn(mMockMacAddress);
-        when(mMockMacAddress.toString()).thenReturn(RANDOMIZED_MAC_ADDRESS);
+        when(mMockWifiEntry.isSaved()).thenReturn(true);
+        when(mMockWifiEntry.getPrivacy()).thenReturn(WifiEntry.PRIVACY_RANDOMIZED_MAC);
+        when(mMockWifiEntry.getMacAddress()).thenReturn(RANDOMIZED_MAC_ADDRESS);
 
         displayAndResume();
 
         verify(mMockMacAddressPref).setVisible(true);
         verify(mMockMacAddressPref).setSummary(RANDOMIZED_MAC_ADDRESS);
+        verify(mMockMacAddressPref).setTitle(R.string.wifi_advanced_randomized_mac_address_title);
     }
 
     @Test
     public void macAddressPref_shouldVisibleAsFactoryForDisconnectedNetwork() {
         setUpForDisconnectedNetwork();
-        mMockWifiConfig.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE;
-        when(mMockWifiManager.getFactoryMacAddresses())
-                .thenReturn(new String[]{FACTORY_MAC_ADDRESS});
+        when(mMockWifiEntry.isSaved()).thenReturn(true);
+        when(mMockWifiEntry.getPrivacy()).thenReturn(WifiEntry.PRIVACY_DEVICE_MAC);
+        when(mMockWifiEntry.getMacAddress()).thenReturn(FACTORY_MAC_ADDRESS);
 
         displayAndResume();
 
         verify(mMockMacAddressPref).setVisible(true);
         verify(mMockMacAddressPref).setSummary(FACTORY_MAC_ADDRESS);
+        verify(mMockMacAddressPref).setTitle(R.string.wifi_advanced_device_mac_address_title);
     }
 
     @Test
@@ -945,6 +931,7 @@
         inOrder.verify(mMockIpv6AddressesPref).setSummary(text);
     }
 
+    @Ignore
     @Test
     public void onLinkPropertiesChanged_updatesFields() {
         setUpForConnectedNetwork();
@@ -1002,6 +989,7 @@
         inOrder.verify(mMockDnsPref).setVisible(true);
     }
 
+    @Ignore
     @Test
     public void onCapabilitiesChanged_callsRefreshIfNecessary() {
         setUpForConnectedNetwork();
@@ -1073,32 +1061,25 @@
     }
 
     @Test
-    public void canForgetNetwork_ephemeral() {
+    public void onUpdated_canForget_showForgetButton() {
         setUpForConnectedNetwork();
-        when(mMockWifiInfo.isEphemeral()).thenReturn(true);
-        when(mMockWifiEntry.isSaved()).thenReturn(false);
+        when(mMockWifiEntry.canForget()).thenReturn(true);
 
         displayAndResume();
+        mController.onUpdated();
 
-        verify(mMockButtonsPref).setButton1Visible(true);
+        verify(mMockButtonsPref, times(2)).setButton1Visible(true);
     }
 
     @Test
-    public void canForgetNetwork_saved() {
+    public void onUpdated_canNotForget_hideForgetButton() {
         setUpForConnectedNetwork();
-        displayAndResume();
-
-        verify(mMockButtonsPref).setButton1Visible(true);
-    }
-
-    @Test
-    public void canForgetNetwork_lockedDown() {
-        setUpForConnectedNetwork();
-        lockDownNetwork();
+        when(mMockWifiEntry.canForget()).thenReturn(false);
 
         displayAndResume();
+        mController.onUpdated();
 
-        verify(mMockButtonsPref).setButton1Visible(false);
+        verify(mMockButtonsPref, times(2)).setButton1Visible(false);
     }
 
     @Test
@@ -1112,8 +1093,10 @@
     }
 
     @Test
-    public void canModifyNetwork_saved() {
+    public void canModifyNetwork_savedNetwork_returnTrue() {
         setUpForConnectedNetwork();
+        when(mMockWifiEntry.isSaved()).thenReturn(true);
+
         assertThat(mController.canModifyNetwork()).isTrue();
     }
 
@@ -1149,52 +1132,30 @@
     }
 
     @Test
-    public void forgetNetwork_ephemeral() {
+    public void forgetNetwork_standardWifiNetwork_forget() {
         setUpForConnectedNetwork();
-        String ssid = "ssid";
-        when(mMockWifiInfo.isEphemeral()).thenReturn(true);
-        when(mMockWifiInfo.getSSID()).thenReturn(ssid);
-
         displayAndResume();
+
         mForgetClickListener.getValue().onClick(null);
 
-        verify(mMockWifiManager).disableEphemeralNetwork(ssid);
+        verify(mMockWifiEntry).forget(mController);
         verify(mMockMetricsFeatureProvider)
                 .action(mMockActivity, MetricsProto.MetricsEvent.ACTION_WIFI_FORGET);
     }
 
     @Test
-    public void forgetNetwork_saved() {
+    public void forgetNetwork_isSubscription_shouldShowDialog() {
         setUpForConnectedNetwork();
-        mMockWifiConfig.networkId = 5;
-
-        mController.displayPreference(mMockScreen);
-        mForgetClickListener.getValue().onClick(null);
-
-        verify(mMockWifiManager).forget(mMockWifiConfig.networkId, null);
-        verify(mMockMetricsFeatureProvider)
-                .action(mMockActivity, MetricsProto.MetricsEvent.ACTION_WIFI_FORGET);
-    }
-
-    /* TODO(b/143326832): Support Passpoint test cases while WifiTracker2 supports it.
-    @Test
-    public void forgetNetwork_shouldShowDialog() {
-        setUpForConnectedNetwork();
-        final WifiDetailPreferenceController2 spyController = spy(mController);
-
-        mMockWifiConfig.networkId = 5;
-        when(mMockAccessPoint.isPasspoint()).thenReturn(true);
-        when(mMockAccessPoint.getPasspointFqdn()).thenReturn(FQDN);
-        spyController.displayPreference(mMockScreen);
+        when(mMockWifiEntry.isSubscription()).thenReturn(true);
+        displayAndResume();
 
         mForgetClickListener.getValue().onClick(null);
 
-        verify(mMockWifiManager, times(0)).removePasspointConfiguration(FQDN);
-        verify(mMockMetricsFeatureProvider, times(0))
+        verify(mMockWifiEntry, never()).forget(mController);
+        verify(mMockMetricsFeatureProvider, never())
                 .action(mMockActivity, MetricsProto.MetricsEvent.ACTION_WIFI_FORGET);
-        verify(spyController).showConfirmForgetDialog();
+        verify(mController).showConfirmForgetDialog();
     }
-    */
 
     @Test
     public void networkStateChangedIntent_shouldRefetchInfo() {
@@ -1204,55 +1165,19 @@
 
         verify(mMockConnectivityManager, times(1)).getNetworkInfo(any(Network.class));
         verify(mMockWifiManager, times(1)).getConnectionInfo();
-
-        mContext.sendBroadcast(new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION));
-
-        verify(mMockConnectivityManager, times(2)).getNetworkInfo(any(Network.class));
-        verify(mMockWifiManager, times(2)).getConnectionInfo();
     }
 
     @Test
-    public void networkStateChangedIntent_shouldRefetchInfoForConnectedNetwork() {
+    public void onUpdated_shouldUpdateNetworkInfo() {
         setUpForConnectedNetwork();
 
         displayAndResume();
 
-        verify(mMockConnectivityManager, times(1)).getNetworkInfo(any(Network.class));
-        verify(mMockWifiManager, times(1)).getConnectionInfo();
+        verify(mController, times(1)).updateNetworkInfo();
 
-        mContext.sendBroadcast(new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION));
+        mController.onUpdated();
 
-        verify(mMockConnectivityManager, times(2)).getNetworkInfo(any(Network.class));
-        verify(mMockWifiManager, times(2)).getConnectionInfo();
-    }
-
-    @Test
-    public void rssiChangedIntent_shouldRefetchInfo() {
-        setUpForConnectedNetwork();
-
-        displayAndResume();
-
-        verify(mMockConnectivityManager, times(1)).getNetworkInfo(any(Network.class));
-        verify(mMockWifiManager, times(1)).getConnectionInfo();
-
-        mContext.sendBroadcast(new Intent(WifiManager.RSSI_CHANGED_ACTION));
-
-        verify(mMockConnectivityManager, times(2)).getNetworkInfo(any(Network.class));
-        verify(mMockWifiManager, times(2)).getConnectionInfo();
-    }
-
-    @Test
-    public void rssiChangedIntent_shouldRefetchInfoForConnectedNetwork() {
-        setUpForConnectedNetwork();
-        displayAndResume();
-
-        verify(mMockConnectivityManager, times(1)).getNetworkInfo(any(Network.class));
-        verify(mMockWifiManager, times(1)).getConnectionInfo();
-
-        mContext.sendBroadcast(new Intent(WifiManager.RSSI_CHANGED_ACTION));
-
-        verify(mMockConnectivityManager, times(2)).getNetworkInfo(any(Network.class));
-        verify(mMockWifiManager, times(2)).getConnectionInfo();
+        verify(mController, times(2)).updateNetworkInfo();
     }
 
     @Test
@@ -1305,6 +1230,7 @@
         assertThat(mMockIpv6AddressesPref.isSelectable()).isFalse();
     }
 
+    @Ignore
     @Test
     public void captivePortal_shouldShowSignInButton() {
         setUpForConnectedNetwork();
@@ -1330,6 +1256,7 @@
         inOrder.verify(mMockButtonsPref).setButton2Visible(false);
     }
 
+    @Ignore
     @Test
     public void captivePortal_shouldShowVenueInfoButton() {
         setUpForConnectedNetwork();
@@ -1355,6 +1282,7 @@
         inOrder.verify(mMockButtonsPref).setButton2Visible(false);
     }
 
+    @Ignore
     @Test
     public void testSignInButton_shouldStartCaptivePortalApp() {
         setUpForConnectedNetwork();
@@ -1395,22 +1323,24 @@
     public void testDisconnectButton_connectedNetwork_shouldVisible() {
         setUpForConnectedNetwork();
         when(mMockWifiEntry.getLevel()).thenReturn(WifiEntry.WIFI_LEVEL_MAX);
+        when(mMockWifiEntry.canDisconnect()).thenReturn(true);
 
         displayAndResume();
 
         verify(mMockButtonsPref).setButton3Visible(true);
-        verify(mMockButtonsPref).setButton3Text(R.string.wifi_disconnect);
+        verify(mMockButtonsPref, times(2)).setButton3Text(R.string.wifi_disconnect_button_text);
     }
 
     @Test
     public void testConnectButton_disconnectedNetwork_shouldVisibleIfReachable() {
         setUpForDisconnectedNetwork();
         when(mMockWifiEntry.getLevel()).thenReturn(WifiEntry.WIFI_LEVEL_MAX);
+        when(mMockWifiEntry.canConnect()).thenReturn(true);
 
         displayAndResume();
 
         verify(mMockButtonsPref).setButton3Visible(true);
-        verify(mMockButtonsPref).setButton3Text(R.string.wifi_connect);
+        verify(mMockButtonsPref, times(2)).setButton3Text(R.string.wifi_connect);
     }
 
     @Test
@@ -1431,30 +1361,41 @@
     @Test
     public void testConnectButton_clickConnect_displayAsSuccess() {
         setUpForDisconnectedNetwork();
-        when(mMockWifiManager.isWifiEnabled()).thenReturn(true);
-        InOrder inOrder = inOrder(mMockButtonsPref);
-        String label = "title";
+        final ArgumentCaptor<ConnectCallback> connectCallbackCaptor =
+                ArgumentCaptor.forClass(ConnectCallback.class);
+        final InOrder inOrder = inOrder(mMockButtonsPref);
+        when(mMockWifiEntry.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_DISCONNECTED);
+        when(mMockWifiEntry.canConnect()).thenReturn(true);
+        final String label = "title";
         when(mMockWifiEntry.getTitle()).thenReturn(label);
         setUpForToast();
 
         displayAndResume();
 
-        // check connect button enabled
-        verifyConnectBtnSetUpAsEnabled(inOrder);
+        // check connect button displayed
+        inOrder.verify(mMockButtonsPref).setButton3Text(R.string.wifi_connect);
+        inOrder.verify(mMockButtonsPref).setButton3Icon(R.drawable.ic_settings_wireless);
 
         // click connect button
         mController.connectDisconnectNetwork();
+        when(mMockWifiEntry.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_CONNECTING);
+        when(mMockWifiEntry.canConnect()).thenReturn(false);
+        when(mMockWifiEntry.canDisconnect()).thenReturn(false);
+        mController.onUpdated();
 
         // check display button as connecting
-        verify(mMockWifiManager, times(1)).connect(anyInt(), any(WifiManager.ActionListener.class));
-        verifyConnectBtnSetUpAsConnecting(inOrder);
+        verify(mMockWifiEntry, times(1)).connect(connectCallbackCaptor.capture());
+        verifyConnectingBtnAvailable(inOrder);
 
         // update as connected
+        connectCallbackCaptor.getValue().onConnectResult(
+                ConnectCallback.CONNECT_STATUS_SUCCESS);
         when(mMockWifiEntry.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_CONNECTED);
+        when(mMockWifiEntry.canDisconnect()).thenReturn(true);
+        mController.onUpdated();
 
-        // check connect button invisible, be init as default state and toast success message
-        verifyConnectBtnBeInitAsDefault(inOrder);
-        inOrder.verify(mMockButtonsPref).setButton3Enabled(false);
+        // check disconnect button invisible, be init as default state and toast success message
+        verifyDisconnecBtnAvailable(inOrder);
         assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
                 mContext.getString(R.string.wifi_connected_to_message, label));
     }
@@ -1462,70 +1403,61 @@
     @Test
     public void testConnectButton_clickConnectButFailed_displayFailMessage() {
         setUpForDisconnectedNetwork();
-        ArgumentCaptor<WifiManager.ActionListener> connectListenerCaptor =
-                ArgumentCaptor.forClass(WifiManager.ActionListener.class);
-        when(mMockWifiManager.isWifiEnabled()).thenReturn(true);
-        InOrder inOrder = inOrder(mMockButtonsPref);
+        final ArgumentCaptor<ConnectCallback> connectCallbackCaptor =
+                ArgumentCaptor.forClass(ConnectCallback.class);
+        final InOrder inOrder = inOrder(mMockButtonsPref);
+        when(mMockWifiEntry.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_DISCONNECTED);
+        when(mMockWifiEntry.canDisconnect()).thenReturn(true);
         setUpForToast();
 
         displayAndResume();
 
-        // check connect button enabled
-        verifyConnectBtnSetUpAsEnabled(inOrder);
+        // check connect button displayed
+        inOrder.verify(mMockButtonsPref).setButton3Text(R.string.wifi_connect);
+        inOrder.verify(mMockButtonsPref).setButton3Icon(R.drawable.ic_settings_wireless);
 
         // click connect button
         mController.connectDisconnectNetwork();
+        when(mMockWifiEntry.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_CONNECTING);
+        when(mMockWifiEntry.canConnect()).thenReturn(false);
+        when(mMockWifiEntry.canDisconnect()).thenReturn(false);
+        mController.onUpdated();
 
         // check display button as connecting
-        verify(mMockWifiManager, times(1)).connect(anyInt(), connectListenerCaptor.capture());
-        verifyConnectBtnSetUpAsConnecting(inOrder);
+        verify(mMockWifiEntry, times(1)).connect(connectCallbackCaptor.capture());
+        verifyConnectingBtnAvailable(inOrder);
 
         // update as failed
-        connectListenerCaptor.getValue().onFailure(-1);
+        connectCallbackCaptor.getValue().onConnectResult(
+                ConnectCallback.CONNECT_STATUS_FAILURE_UNKNOWN);
+        when(mMockWifiEntry.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_DISCONNECTED);
+        when(mMockWifiEntry.canConnect()).thenReturn(true);
+        mController.onUpdated();
 
-        // check connect button visible, be init as default and toast failed message
-        verifyConnectBtnBeInitAsDefault(inOrder);
-        inOrder.verify(mMockButtonsPref).setButton3Enabled(true);
+        // check connect button available, be init as default and toast failed message
+        verifyConnectBtnAvailable(inOrder);
         assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
                 mContext.getString(R.string.wifi_failed_connect_message));
     }
 
-    private void verifyConnectBtnSetUpAsEnabled(InOrder inOrder) {
+    private void verifyConnectBtnAvailable(InOrder inOrder) {
+        inOrder.verify(mMockButtonsPref).setButton3Visible(true);
+        inOrder.verify(mMockButtonsPref).setButton3Enabled(true);
         inOrder.verify(mMockButtonsPref).setButton3Text(R.string.wifi_connect);
         inOrder.verify(mMockButtonsPref).setButton3Icon(R.drawable.ic_settings_wireless);
-        inOrder.verify(mMockButtonsPref).setButton3Enabled(true);
     }
 
-    private void verifyConnectBtnSetUpAsConnecting(InOrder inOrder) {
-        inOrder.verify(mMockButtonsPref).setButton3Text(R.string.wifi_connecting);
+    private void verifyDisconnecBtnAvailable(InOrder inOrder) {
+        inOrder.verify(mMockButtonsPref).setButton3Visible(true);
+        inOrder.verify(mMockButtonsPref).setButton3Enabled(true);
+        inOrder.verify(mMockButtonsPref).setButton3Text(R.string.wifi_disconnect_button_text);
+        inOrder.verify(mMockButtonsPref).setButton3Icon(R.drawable.ic_settings_close);
+    }
+
+    private void verifyConnectingBtnAvailable(InOrder inOrder) {
+        inOrder.verify(mMockButtonsPref).setButton3Visible(true);
         inOrder.verify(mMockButtonsPref).setButton3Enabled(false);
-    }
-
-    private void verifyConnectBtnBeInitAsDefault(InOrder inOrder) {
-        inOrder.verify(mMockButtonsPref).setButton3Text(R.string.wifi_connect);
-        inOrder.verify(mMockButtonsPref).setButton3Icon(R.drawable.ic_settings_wireless);
-        inOrder.verify(mMockButtonsPref).setButton3Enabled(true);
-    }
-
-    @Test
-    public void testRefreshRssiViews_shouldOnUpdated() {
-        setUpForConnectedNetwork();
-        displayAndResume();
-
-        mContext.sendBroadcast(new Intent(WifiManager.RSSI_CHANGED_ACTION));
-
-        verify(mController).onUpdated();
-    }
-
-    @Test
-    public void testRefreshRssiViews_shouldNotUpdateForNotInRangeNetwork() {
-        setUpForNotInRangeNetwork();
-        displayAndResume();
-
-        when(mMockWifiEntry.getLevel()).thenReturn(0);
-        mContext.sendBroadcast(new Intent(WifiManager.RSSI_CHANGED_ACTION));
-
-        verify(mMockSignalStrengthPref, times(2)).setVisible(false);
+        inOrder.verify(mMockButtonsPref).setButton3Text(R.string.wifi_connecting);
     }
 
     @Test
@@ -1580,46 +1512,17 @@
     }
 
     @Test
-    public void checkMacTitle_whenPrivacyRandomizedMac_shouldBeRandom() {
+    public void entityHeader_expired_shouldHandleExpiration() {
         setUpForDisconnectedNetwork();
-        mMockWifiConfig.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT;
-        when(mMockWifiConfig.getRandomizedMacAddress()).thenReturn(mMockMacAddress);
-        when(mMockMacAddress.toString()).thenReturn(RANDOMIZED_MAC_ADDRESS);
-
-        displayAndResume();
-
-        verify(mMockMacAddressPref).setTitle(R.string.wifi_advanced_randomized_mac_address_title);
-    }
-
-    @Test
-    public void checkMacTitle_whenPrivacyDeviceMac_shouldBeFactory() {
-        setUpForDisconnectedNetwork();
-        mMockWifiConfig.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE;
-        when(mMockWifiConfig.getRandomizedMacAddress()).thenReturn(mMockMacAddress);
-        when(mMockWifiManager.getFactoryMacAddresses())
-                .thenReturn(new String[]{FACTORY_MAC_ADDRESS});
-
-        displayAndResume();
-
-        verify(mMockMacAddressPref).setTitle(R.string.wifi_advanced_device_mac_address_title);
-    }
-
-    /* TODO(b/143326832): Support Passpoint test cases while WifiTracker2 supports it.
-    @Test
-    public void entityHeader_expiredPasspointR1_shouldHandleExpiration() {
-        when(mMockAccessPoint.isPasspoint()).thenReturn(true);
-        when(mMockAccessPoint.isPasspointConfigurationR1()).thenReturn(true);
-        when(mMockAccessPoint.isExpired()).thenReturn(true);
-        setUpForDisconnectedNetwork();
-        String expireSummary = mContext.getResources().getString(
-                com.android.settingslib.R.string.wifi_passpoint_expired);
+        when(mMockWifiEntry.isExpired()).thenReturn(true);
+        final String expired = "Expired";
+        when(mMockWifiEntry.getSummary()).thenReturn(expired);
 
         displayAndResume();
 
         verify(mMockButtonsPref, atLeastOnce()).setButton3Visible(false);
-        verify(mMockHeaderController).setSummary(expireSummary);
+        verify(mMockHeaderController).setSummary(expired);
     }
-    */
 
     private ActionButtonsPreference createMock() {
         final ActionButtonsPreference pref = mock(ActionButtonsPreference.class);