Merge "Fixed Infinite loop method call." into qt-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index c112115..8fd0769 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1276,6 +1276,8 @@
             </intent-filter>
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                        android:value="com.android.settings.privacy.PrivacyDashboardFragment" />
+            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
+                       android:value="true" />
         </activity>
 
         <activity android:name="SetFullBackupPassword"
@@ -1629,6 +1631,7 @@
                        android:resource="@string/suggestion_additional_fingerprints" />
             <meta-data android:name="com.android.settings.summary"
                        android:resource="@string/suggestion_additional_fingerprints_summary" />
+            <meta-data android:name="com.android.settings.icon_tintable" android:value="true" />
         </activity-alias>
 
         <!-- Note this must not be exported since it returns the password in the intent -->
diff --git a/res/drawable-hdpi/ic_live_help.png b/res/drawable-hdpi/ic_live_help.png
deleted file mode 100644
index f3548f6..0000000
--- a/res/drawable-hdpi/ic_live_help.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_live_help.png b/res/drawable-mdpi/ic_live_help.png
deleted file mode 100644
index e958662..0000000
--- a/res/drawable-mdpi/ic_live_help.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_live_help.png b/res/drawable-xhdpi/ic_live_help.png
deleted file mode 100644
index dbbbfed..0000000
--- a/res/drawable-xhdpi/ic_live_help.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_live_help.png b/res/drawable-xxhdpi/ic_live_help.png
deleted file mode 100644
index f2a01fe..0000000
--- a/res/drawable-xxhdpi/ic_live_help.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_live_help.png b/res/drawable-xxxhdpi/ic_live_help.png
deleted file mode 100644
index 00338a0..0000000
--- a/res/drawable-xxxhdpi/ic_live_help.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/ic_feedback_24dp.xml b/res/drawable/ic_feedback_24dp.xml
new file mode 100644
index 0000000..a65f444
--- /dev/null
+++ b/res/drawable/ic_feedback_24dp.xml
@@ -0,0 +1,30 @@
+<!--
+  ~ Copyright (C) 2019 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
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M20,2H4C2.9,2 2.01,2.9 2.01,4L2,22l4,-4h14c1.1,0 2,-0.9 2,-2V4C22,2.9 21.1,2 20,2zM20,16H6H5.17l-0.59,0.59L4,17.17V4h16V16z"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M11,12h2v2h-2z"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M11,6h2v4h-2z"/>
+</vector>
diff --git a/res/layout/face_enroll_accessibility_toggle.xml b/res/layout/face_enroll_accessibility_toggle.xml
index 4dda2a7..d37175b 100644
--- a/res/layout/face_enroll_accessibility_toggle.xml
+++ b/res/layout/face_enroll_accessibility_toggle.xml
@@ -14,33 +14,68 @@
      limitations under the License.
 -->
 
-<LinearLayout
+<RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="horizontal"
+    android:orientation="vertical"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:paddingEnd="16dp"
-    android:paddingStart="16dp">
+    android:layout_height="wrap_content"
+    style="?attr/face_layout_theme">
 
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@+id/title"/>
-
-    <Space
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        android:layout_weight="1"/>
-
+    <!-- Top divider -->
     <View
-        android:layout_width="1dp"
-        android:layout_height="match_parent"
+        android:layout_alignParentTop="true"
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
         android:background="?android:attr/listDivider" />
 
+    <!-- Title -->
+    <com.google.android.setupdesign.view.RichTextView
+        style="@style/SudDescription.Glif"
+        android:id="@+id/title"
+        android:paddingHorizontal="8dp"
+        android:paddingTop="8dp"
+        android:gravity="start"
+        android:layout_alignParentStart="true"
+        android:layout_toLeftOf="@+id/toggle"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <!-- Subtitle -->
+    <TextView
+        android:id="@+id/subtitle"
+        android:paddingHorizontal="8dp"
+        android:paddingBottom="8dp"
+        android:layout_alignParentStart="true"
+        android:layout_toLeftOf="@+id/toggle"
+        android:layout_below="@+id/title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/security_settings_face_enroll_introduction_accessibility_expanded"/>
+
+    <!-- Vertical divider -->
+    <View
+        android:layout_centerVertical="true"
+        android:layout_alignTop="@+id/toggle"
+        android:layout_alignBottom="@+id/toggle"
+        android:layout_toStartOf="@+id/toggle"
+        android:layout_width="1dp"
+        android:layout_height="wrap_content"
+        android:background="?android:attr/listDivider" />
+
+    <!-- Toggle -->
     <Switch
+        android:layout_alignParentEnd="true"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:id="@+id/toggle"
+        android:layout_centerVertical="true"
         android:checked="true"/>
 
-</LinearLayout>
+    <!-- Bottom divider -->
+    <View
+        android:layout_below="@+id/subtitle"
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:background="?android:attr/listDivider" />
+
+</RelativeLayout>
diff --git a/res/layout/face_enroll_button.xml b/res/layout/face_enroll_button.xml
new file mode 100644
index 0000000..2a6d676
--- /dev/null
+++ b/res/layout/face_enroll_button.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 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:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <Button
+        android:id="@+id/security_settings_face_settings_enroll_button"
+        android:layout_marginStart="@dimen/screen_margin_sides"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="start"
+        android:text="@string/security_settings_face_settings_enroll"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/face_enroll_introduction.xml b/res/layout/face_enroll_introduction.xml
index 5107bd8..3115bb4 100644
--- a/res/layout/face_enroll_introduction.xml
+++ b/res/layout/face_enroll_introduction.xml
@@ -77,6 +77,7 @@
             <FrameLayout
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content">
+
                 <Button
                     android:id="@+id/accessibility_button"
                     style="@style/SudGlifButton.Secondary"
@@ -89,7 +90,7 @@
                     android:id="@+id/toggle_diversity"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:visibility="invisible"
+                    android:visibility="gone"
                     FaceEnrollAccessibilitySwitch:messageText="@string/security_settings_face_enroll_introduction_accessibility_diversity"/>
 
             </FrameLayout>
@@ -101,7 +102,7 @@
                 android:orientation="horizontal"
                 android:paddingStart="16dp"
                 android:paddingEnd="16dp"
-                android:layout_marginTop="24dp">
+                android:paddingTop="24dp">
 
                 <ImageView
                     android:layout_width="wrap_content"
diff --git a/res/raw/bubbles.mp4 b/res/raw/bubbles.mp4
new file mode 100644
index 0000000..c68ea57
--- /dev/null
+++ b/res/raw/bubbles.mp4
Binary files differ
diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml
index f6f86f0..b7b30f5 100644
--- a/res/values-night/colors.xml
+++ b/res/values-night/colors.xml
@@ -24,5 +24,7 @@
   <color name="homepage_card_dismissal_background">@*android:color/material_grey_900</color>
   <color name="contextual_card_background">@*android:color/material_grey_900</color>
   <color name="search_bar_background">@*android:color/material_grey_800</color>
+  <!-- Dialog background color -->
+  <color name="dialog_background">@*android:color/material_grey_800</color>
 </resources>
 
diff --git a/res/values-night/themes.xml b/res/values-night/themes.xml
index 2227b88..782f482 100644
--- a/res/values-night/themes.xml
+++ b/res/values-night/themes.xml
@@ -33,6 +33,7 @@
 
     <style name="Theme.AlertDialog.Base" parent="@style/Theme.AppCompat.DayNight.Dialog.Alert">
         <item name="colorAccent">@*android:color/accent_device_default_dark</item>
+        <item name="android:background">@color/dialog_background</item>
     </style>
 
 </resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index d4363b1..1245b37 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -143,4 +143,7 @@
     <!-- Search bar background color -->
     <color name="search_bar_background">@android:color/white</color>
 
+    <!-- Dialog background color -->
+    <color name="dialog_background">@*android:color/background_device_default_light</color>
+
 </resources>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 08d5634..2a29f44 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -890,6 +890,8 @@
     <string name="security_settings_face_preference_title">Face authentication</string>
     <!-- Button shown which shows accessibility toggles for face enrollment when clicked. [CHAR LIMIT=32] -->
     <string name="security_settings_face_enroll_introduction_accessibility">Use accessibility setup</string>
+    <!-- Additional details shown when the accessibility toggle is expanded. [CHAR LIMIT=NONE]-->
+    <string name="security_settings_face_enroll_introduction_accessibility_expanded"></string>
     <!-- Message shown for a toggle which when enabled, allows the user to enroll using a simpler flow for accessibility [CHAR LIMIT=NONE] -->
     <string name="security_settings_face_enroll_introduction_accessibility_diversity"></string>
     <!-- Message shown for a toggle which when enabled, allows the user to enroll using a simpler flow for accessibility [CHAR LIMIT=NONE] -->
@@ -946,6 +948,8 @@
     <string name="security_settings_face_settings_require_confirmation_details">When authenticating in apps, always require confirmation</string>
     <!-- Button text in face settings which removes the user's faces from the device [CHAR LIMIT=20] -->
     <string name="security_settings_face_settings_remove_face_data">Remove face data</string>
+    <!-- Button text in face settings which lets the user enroll their face [CHAR LIMIT=40] -->
+    <string name="security_settings_face_settings_enroll">Set up face authentication</string>
     <!-- Text shown in face settings explaining what your face can be used for. [CHAR LIMIT=NONE] -->
     <string name="security_settings_face_settings_footer">Your face can be used to unlock your device and access apps.
         <annotation id="url">Learn more</annotation></string>
@@ -2203,10 +2207,10 @@
     <string name="wifi_dpp_wifi_password">Wi\u2011Fi password: <xliff:g id="password" example="my password">%1$s</xliff:g></string>
     <!-- Hint for Wi-Fi hotspot password [CHAR LIMIT=50]  -->
     <string name="wifi_dpp_hotspot_password">Hotspot password: <xliff:g id="password" example="my password">%1$s</xliff:g></string>
-    <!-- Label for "Connect to this network using a QR code" [CHAR LIMIT=50]  -->
+    <!-- Label for "Use a QR code to add a device to this network" [CHAR LIMIT=50]  -->
     <string name="wifi_dpp_add_device">Add device</string>
     <!-- Hint for "Add device" [CHAR LIMIT=NONE]  -->
-    <string name="wifi_dpp_connect_network_using_qr_code">Connect to this network using a QR code</string>
+    <string name="wifi_dpp_connect_network_using_qr_code">Use a QR code to add a device to this network</string>
      <!-- Label for the try again button [CHAR LIMIT=20]-->
     <string name="retry">Retry</string>
     <!-- Label for the check box to share a network with other users on the same device -->
@@ -2759,6 +2763,8 @@
     <string name="brightness_summary">Adjust the brightness of the screen</string>
     <!-- Sound & display settings screen, setting option name to enable adaptive brightness [CHAR LIMIT=30] -->
     <string name="auto_brightness_title">Adaptive brightness</string>
+    <!-- Summary about the feature adaptive brightness [CHAR LIMIT=NONE] -->
+    <string name="auto_brightness_summary">Screen brightness adjusts to environment</string>
     <!-- Setting option summary when adaptive brightness is on [CHAR LIMIT=NONE] -->
     <string name="auto_brightness_summary_on">On</string>
     <!-- Setting option summary when adaptive brightness is off [CHAR LIMIT=NONE] -->
@@ -7192,8 +7198,6 @@
     <string name="keywords_wifi">wifi, wi-fi, network connection, internet, wireless, data, wi fi</string>
     <!-- Search keyword for "Open Network Notification" settings. [CHAR_LIMIT=NONE]-->
     <string name="keywords_wifi_notify_open_networks">Wi\u2011Fi notification, wifi notification</string>
-    <!-- Search keyword for "Adaptive brightness" settings. [CHAR_LIMIT=NONE]-->
-    <string name="keywords_auto_brightness">Auto brightness</string>
     <!-- Search keyword for "Vibrate on touch" settings. [CHAR_LIMIT=NONE]-->
     <string name="keywords_vibrate_on_touch">Stop vibration, tap, keyboard</string>
     <!-- Search keyword for "Time format" settings. [CHAR_LIMIT=NONE]-->
@@ -7280,7 +7284,7 @@
     <string name="keywords_fingerprint_settings">fingerprint, add fingerprint</string>
 
     <!-- Search keywords for adaptive brightness setting [CHAR LIMIT=NONE]-->
-    <string name="keywords_display_auto_brightness">dim screen, touchscreen, battery, smart brightness, dynamic brightness</string>
+    <string name="keywords_display_auto_brightness">dim screen, touchscreen, battery, smart brightness, dynamic brightness, Auto brightness</string>
 
     <!-- Search keywords for adaptive sleep setting [CHAR LIMIT=NONE]-->
     <string name="keywords_display_adaptive_sleep">dim screen, sleep, battery, timeout, attention, display, screen, inactivity</string>
@@ -7652,19 +7656,19 @@
     <string name="zen_mode_sound_summary_on">On</string>
 
     <!--  Do not disturb: Summary for zen mode duration setting indicating user will be prompted to set dnd duration whenever dnd is manually toggled on [CHAR LIMIT=NONE]-->
-    <string name="zen_mode_duration_summary_always_prompt">Ask every time (unless turned on automatically)</string>
+    <string name="zen_mode_duration_summary_always_prompt">Ask every time</string>
 
     <!--  Do not disturb: Summary for zen mode duration setting indicating how long dnd will last when dnd is manually toggled on [CHAR LIMIT=NONE] -->
-    <string name="zen_mode_duration_summary_forever">Until you turn off (unless turned on automatically)</string>
+    <string name="zen_mode_duration_summary_forever">Until you turn off</string>
 
     <!--  Do not disturb: Summary for zen mode duration setting indicating how long dnd will last when dnd is manually toggled on [CHAR LIMIT=NONE] -->
     <plurals name="zen_mode_duration_summary_time_hours">
-        <item quantity="one">1 hour (unless turned on automatically)</item>
-        <item quantity="other"><xliff:g id="num_hours" example="3">%d</xliff:g> hours (unless turned on automatically)</item>
+        <item quantity="one">1 hour</item>
+        <item quantity="other"><xliff:g id="num_hours" example="3">%d</xliff:g> hours</item>
     </plurals>
 
     <!--  Do not disturb: Summary for zen mode duration setting indicating how long dnd will last when toggled on -->
-    <string name="zen_mode_duration_summary_time_minutes"><xliff:g id="num_minutes" example="5">%d</xliff:g> minutes (unless turned on automatically)</string>
+    <string name="zen_mode_duration_summary_time_minutes"><xliff:g id="num_minutes" example="5">%d</xliff:g> minutes</string>
 
     <!-- Summary for the Sound Do not Disturb option when at least one automatic rules is enabled. [CHAR LIMIT=NONE]-->
     <plurals name="zen_mode_sound_summary_summary_off_info">
@@ -7806,19 +7810,19 @@
     <string name="asst_capability_prioritizer_title">Automatic Prioritization</string>
 
     <!-- Configure Notifications: setting summary [CHAR LIMIT=200] -->
-    <string name="asst_capability_prioritizer_summary">Automatically de-prioritize less important notifications to the gentle section</string>
+    <string name="asst_capability_prioritizer_summary">Automatically set lower priority notifications to Gentle</string>
 
     <!-- Configure Notifications: setting title [CHAR LIMIT=80] -->
-    <string name="asst_capabilities_actions_replies_title">Smart actions and replies</string>
+    <string name="asst_capabilities_actions_replies_title">Suggested actions and replies</string>
 
     <!-- Configure Notifications: setting summary [CHAR LIMIT=200] -->
-    <string name="asst_capabilities_actions_replies_summary">Automatically add suggested actions and replies to notifications</string>
+    <string name="asst_capabilities_actions_replies_summary">Automatically show suggested actions &amp; replies</string>
 
     <!-- Configure Notifications: setting title [CHAR LIMIT=80] -->
-    <string name="hide_silent_icons_title">Hide silent notification status icons</string>
+    <string name="hide_silent_icons_title">Hide icons from gentle notifications</string>
 
     <!-- Configure Notifications: setting summary [CHAR LIMIT=NONE] -->
-    <string name="hide_silent_icons_summary">Hide icons for silent notifications in the status bar</string>
+    <string name="hide_silent_icons_summary">Icons from gentle notifications aren\'t shown in the status bar</string>
 
     <!-- Configure Notifications: Title for the notification badging option. [CHAR LIMIT=30 BACKUP_MESSAGE_ID=5125022693565388760] -->
     <string name="notification_badging_title">Allow notification dots</string>
@@ -7975,33 +7979,38 @@
     <string name="notification_channel_summary_min">In the pull-down shade, collapse notifications to one line</string>
 
     <!-- [CHAR LIMIT=100] Notification Importance title: low importance level summary -->
-    <string name="notification_channel_summary_low">Gentle notifications will display in pull-down list</string>
+    <string name="notification_channel_summary_low">Always silent. Displays in pull-down shade.</string>
 
     <!-- [CHAR LIMIT=100] Notification Importance title: low importance level summary -->
-    <string name="notification_channel_summary_low_status">Gentle notifications will display in pull-down list &amp; status bar</string>
+    <string name="notification_channel_summary_low_status">Always silent. Displays in pull-down shade &amp; status bar.</string>
 
     <!-- [CHAR LIMIT=100] Notification Importance title: low importance level summary -->
-    <string name="notification_channel_summary_low_lock">Gentle notifications will display in pull-down list &amp; on lock screen</string>
+    <string name="notification_channel_summary_low_lock">Always silent. Displays in pull-down shade &amp; on lock screen.</string>
 
     <!-- [CHAR LIMIT=100] Notification Importance title: low importance level summary -->
-    <string name="notification_channel_summary_low_status_lock">Gentle notifications will display in pull-down list, status bar &amp; on lock screen</string>
+    <string name="notification_channel_summary_low_status_lock">Always silent. Displays in pull-down shade, status bar &amp; on lock screen.</string>
 
     <!-- [CHAR LIMIT=100] Notification Importance title: normal importance level summary -->
-    <string name="notification_channel_summary_default">Prioritized notifications will alert and display in pull-down list, status bar &amp; on lock screen</string>
+    <string name="notification_channel_summary_default">Makes sound and displays in pull-down shade, status bar &amp; on lock screen.</string>
 
     <!-- [CHAR LIMIT=100] Notification Importance title: high importance level summary -->
-    <string name="notification_channel_summary_high">When phone is unlocked, show notifications as a banner across top of screen</string>
+    <string name="notification_channel_summary_high">When device is unlocked, show notifications as a banner across the top of the screen</string>
 
     <!-- [CHAR LIMIT=100] Label for on/off toggle -->
     <string name="notification_switch_label">Show notifications</string>
 
     <!-- Default Apps > Default notification assistant -->
-    <string name="default_notification_assistant">Notification assistant</string>
+    <string name="default_notification_assistant">Adaptive Notifications</string>
 
     <!-- app summary of notification app list screen [CHAR LIMIT=100] -->
-    <string name="notifications_sent_daily">~<xliff:g id="number">%1$s</xliff:g> per day</string>
-    <!-- app summary of notification app list screen [CHAR LIMIT=100] -->
-    <string name="notifications_sent_weekly">~<xliff:g id="number">%1$s</xliff:g> per week</string>
+    <plurals name="notifications_sent_daily">
+        <item quantity="one">~<xliff:g id="number">%d</xliff:g> notification per day</item>
+        <item quantity="other">~<xliff:g id="number">%d</xliff:g> notifications per day</item>
+    </plurals>
+    <plurals name="notifications_sent_weekly">
+        <item quantity="one">~<xliff:g id="number">%d</xliff:g> notification per week</item>
+        <item quantity="other">~<xliff:g id="number">%d</xliff:g> notifications per week</item>
+    </plurals>
     <!-- app summary of notification app list screen [CHAR LIMIT=100] -->
     <string name="notifications_sent_never">Never</string>
 
@@ -8023,10 +8032,10 @@
     </plurals>
 
     <!-- Title for Notification Assistant Picker screen [CHAR LIMIT=30]-->
-    <string name="notification_assistant_title">Notification Assistant</string>
+    <string name="notification_assistant_title">Adaptive Notifications</string>
 
     <!-- Label for no NotificationAssistantService [CHAR_LIMIT=NONE] -->
-    <string name="no_notification_assistant">No assistant</string>
+    <string name="no_notification_assistant">None</string>
 
     <!-- String to show in the list of notification listeners, when none is installed -->
     <string name="no_notification_listeners">No installed apps have requested notification access.</string>
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 5db5f2f..d29d78b 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -117,6 +117,7 @@
 
     <style name="Theme.AlertDialog.Base" parent="@style/Theme.AppCompat.DayNight.Dialog.Alert">
         <item name="colorAccent">@*android:color/accent_device_default_light</item>
+        <item name="android:background">@color/dialog_background</item>
     </style>
 
     <style name="Theme.AlertDialog" parent="Theme.AlertDialog.Base">
diff --git a/res/xml/auto_brightness_detail.xml b/res/xml/auto_brightness_detail.xml
index b10f1ad..abf535f 100644
--- a/res/xml/auto_brightness_detail.xml
+++ b/res/xml/auto_brightness_detail.xml
@@ -32,8 +32,9 @@
     <com.android.settingslib.RestrictedSwitchPreference
         android:key="auto_brightness"
         android:title="@string/auto_brightness_title"
+        android:summary="@string/auto_brightness_summary"
         settings:keywords="@string/keywords_display_auto_brightness"
-        settings:controller="com.android.settings.display.AutoBrightnessPreferenceController"
+        settings:controller="com.android.settings.display.AutoBrightnessDetailPreferenceController"
         settings:useAdminDisabledSummary="true"
         settings:userRestriction="no_config_brightness"
         settings:allowDividerAbove="true" />
diff --git a/res/xml/bubble_notification_settings.xml b/res/xml/bubble_notification_settings.xml
index 20783fa..7fba125 100644
--- a/res/xml/bubble_notification_settings.xml
+++ b/res/xml/bubble_notification_settings.xml
@@ -18,6 +18,14 @@
                   xmlns:settings="http://schemas.android.com/apk/res-auto"
                   android:title="@string/bubbles_app_toggle_title"
                   android:key="bubble_notification_settings">
+
+        <com.android.settings.widget.VideoPreference
+            android:key="bubbles_illustration"
+            android:title="@string/summary_placeholder"
+            settings:animation="@raw/bubbles"
+            settings:controller="com.android.settings.widget.VideoPreferenceController"
+            android:persistent="false" />
+
         <!-- Notification bubbles -->
         <SwitchPreference
             android:key="global_notification_bubbles"
diff --git a/res/xml/display_settings.xml b/res/xml/display_settings.xml
index bcd5100..ad06e95 100644
--- a/res/xml/display_settings.xml
+++ b/res/xml/display_settings.xml
@@ -44,8 +44,7 @@
         android:title="@string/auto_brightness_title"
         android:summary="@string/summary_placeholder"
         android:fragment="com.android.settings.display.AutoBrightnessSettings"
-        settings:controller="com.android.settings.display.AutoBrightnessPreferenceController"
-        settings:keywords="@string/keywords_auto_brightness"/>
+        settings:controller="com.android.settings.display.AutoBrightnessPreferenceController"/>
 
     <com.android.settingslib.RestrictedPreference
         android:key="wallpaper"
diff --git a/res/xml/mobile_network_settings_v2.xml b/res/xml/mobile_network_settings_v2.xml
index 6682437..6890a41 100644
--- a/res/xml/mobile_network_settings_v2.xml
+++ b/res/xml/mobile_network_settings_v2.xml
@@ -24,162 +24,170 @@
         android:layout="@layout/styled_switch_bar"
         settings:controller="com.android.settings.network.telephony.MobileNetworkSwitchController"/>
 
-    <com.android.settings.datausage.DataUsageSummaryPreference
-        android:key="status_header"
-        android:visibility="gone"
-        android:selectable="false" />
-
-    <ListPreference
-        android:key="calls_preference"
-        android:title="@string/calls_preference"
-        settings:controller="com.android.settings.network.telephony.CallsDefaultSubscriptionController"
-        settings:allowDividerAbove="true" />
-
-    <ListPreference
-        android:key="sms_preference"
-        android:title="@string/sms_preference"
-        settings:controller="com.android.settings.network.telephony.SmsDefaultSubscriptionController" />
-
-    <Preference
-        android:key="cdma_lte_data_service_key"
-        android:title="@string/cdma_lte_data_service"
-        settings:controller="com.android.settings.network.telephony.DataServiceSetupPreferenceController"
-        settings:allowDividerAbove="true"
-        settings:allowDividerBelow="false" />
-
-    <SwitchPreference
-        android:key="mobile_data_enable"
-        android:title="@string/mobile_data_settings_title"
-        android:summary="@string/mobile_data_settings_summary"
-        settings:controller="com.android.settings.network.telephony.MobileDataPreferenceController"
-        settings:allowDividerAbove="true"/>
-
-    <com.android.settingslib.RestrictedSwitchPreference
-        android:key="button_roaming_key"
-        android:title="@string/roaming"
-        android:persistent="false"
-        android:summaryOn="@string/roaming_enable"
-        android:summaryOff="@string/roaming_disable"
-        settings:userRestriction="no_data_roaming"
-        settings:controller="com.android.settings.network.telephony.RoamingPreferenceController"/>
-
-    <Preference
-        android:key="data_usage_summary"
-        android:title="@string/mobile_data_usage_title"
-        settings:controller="com.android.settings.network.telephony.DataUsagePreferenceController"/>
-
-    <com.android.settings.datausage.BillingCyclePreference
-        android:key="billing_preference"
-        android:title="@string/billing_cycle"
-        settings:controller="com.android.settings.datausage.BillingCyclePreferenceController" />
-
-    <SwitchPreference
-        android:key="mms_message"
-        android:title="@string/mms_message_title"
-        android:summary="@string/mms_message_summary"
-        settings:controller="com.android.settings.network.telephony.MmsMessagePreferenceController" />
-
-    <SwitchPreference
-        android:key="enhanced_4g_lte"
-        android:title="@string/enhanced_4g_lte_mode_title"
-        android:persistent="false"
-        android:summary="@string/enhanced_4g_lte_mode_summary"
-        settings:controller="com.android.settings.network.telephony.Enhanced4gLtePreferenceController"/>
-
-    <ListPreference
-        android:key="preferred_network_mode_key"
-        android:title="@string/preferred_network_mode_title"
-        android:summary="@string/preferred_network_mode_summary"
-        android:entries="@array/preferred_network_mode_choices"
-        android:entryValues="@array/preferred_network_mode_values"
-        android:dialogTitle="@string/preferred_network_mode_dialogtitle"
-        settings:controller="com.android.settings.network.telephony.PreferredNetworkModePreferenceController"/>
-
-    <ListPreference
-        android:key="enabled_networks_key"
-        android:title="@string/preferred_network_mode_title"
-        android:summary="@string/preferred_network_mode_summary"
-        android:entries="@array/enabled_networks_choices"
-        android:entryValues="@array/enabled_networks_values"
-        android:dialogTitle="@string/preferred_network_mode_dialogtitle"
-        settings:controller="com.android.settings.network.telephony.EnabledNetworkModePreferenceController"/>
-
-    <Preference
-        android:key="carrier_settings_version_key"
-        android:title="@string/carrier_settings_version"
-        settings:controller="com.android.settings.network.telephony.CarrierSettingsVersionPreferenceController"
-        settings:enableCopying="true" />
-
     <PreferenceCategory
-        android:key="calling_category"
-        android:title="@string/call_category">
+        android:key="enabled_state_container"
+        android:title="@string/summary_placeholder"
+        settings:controller="com.android.settings.network.telephony.DisabledSubscriptionController"
+        android:layout="@layout/preference_category_no_label">
 
-        <PreferenceScreen
-            android:key="wifi_calling_key"
-            android:title="@string/wifi_calling_settings_title"
-            settings:controller="com.android.settings.network.telephony.WifiCallingPreferenceController" >
-            <intent android:action="android.intent.action.MAIN"
-                    android:targetPackage="com.android.settings"
-                    android:targetClass="com.android.settings.Settings$WifiCallingSettingsActivity">
-                        <extra android:name="show_drawer_menu" android:value="true" />
-            </intent>
-        </PreferenceScreen>
+        <com.android.settings.datausage.DataUsageSummaryPreference
+            android:key="status_header"
+            android:visibility="gone"
+            android:selectable="false" />
 
-        <SwitchPreference
-            android:key="video_calling_key"
-            android:title="@string/video_calling_settings_title"
-            android:persistent="true"
-            settings:controller="com.android.settings.network.telephony.VideoCallingPreferenceController" />
+        <ListPreference
+            android:key="calls_preference"
+            android:title="@string/calls_preference"
+            settings:controller="com.android.settings.network.telephony.CallsDefaultSubscriptionController"
+            settings:allowDividerAbove="true"/>
 
-    </PreferenceCategory>
-
-    <com.android.settings.network.telephony.cdma.CdmaListPreference
-        android:key="cdma_system_select_key"
-        android:title="@string/cdma_system_select_title"
-        android:summary="@string/cdma_system_select_summary"
-        android:entries="@array/cdma_system_select_choices"
-        android:entryValues="@array/cdma_system_select_values"
-        android:dialogTitle="@string/cdma_system_select_dialogtitle"
-        settings:controller="com.android.settings.network.telephony.cdma.CdmaSystemSelectPreferenceController"/>
-
-    <com.android.settings.network.telephony.cdma.CdmaListPreference
-        android:key="cdma_subscription_key"
-        android:title="@string/cdma_subscription_title"
-        android:summary="@string/cdma_subscription_summary"
-        android:entries="@array/cdma_subscription_choices"
-        android:entryValues="@array/cdma_subscription_values"
-        android:dialogTitle="@string/cdma_subscription_dialogtitle"
-        settings:controller="com.android.settings.network.telephony.cdma.CdmaSubscriptionPreferenceController"/>
-
-    <PreferenceCategory
-        android:key="network_operators_category_key"
-        android:title="@string/network_operator_category"
-        settings:controller="com.android.settings.widget.PreferenceCategoryController">
-
-        <SwitchPreference
-            android:key="auto_select_key"
-            android:title="@string/select_automatically"
-            settings:controller="com.android.settings.network.telephony.gsm.AutoSelectPreferenceController"/>
+        <ListPreference
+            android:key="sms_preference"
+            android:title="@string/sms_preference"
+            settings:controller="com.android.settings.network.telephony.SmsDefaultSubscriptionController"/>
 
         <Preference
-            android:key="choose_network_key"
-            android:title="@string/choose_network_title"
-            android:fragment="com.android.phone.NetworkSelectSetting"
-            settings:controller="com.android.settings.network.telephony.gsm.OpenNetworkSelectPagePreferenceController"/>
+            android:key="cdma_lte_data_service_key"
+            android:title="@string/cdma_lte_data_service"
+            settings:controller="com.android.settings.network.telephony.DataServiceSetupPreferenceController"
+            settings:allowDividerAbove="true"
+            settings:allowDividerBelow="false"/>
+
+        <SwitchPreference
+            android:key="mobile_data_enable"
+            android:title="@string/mobile_data_settings_title"
+            android:summary="@string/mobile_data_settings_summary"
+            settings:controller="com.android.settings.network.telephony.MobileDataPreferenceController"
+            settings:allowDividerAbove="true"/>
+
+        <com.android.settingslib.RestrictedSwitchPreference
+            android:key="button_roaming_key"
+            android:title="@string/roaming"
+            android:persistent="false"
+            android:summaryOn="@string/roaming_enable"
+            android:summaryOff="@string/roaming_disable"
+            settings:userRestriction="no_data_roaming"
+            settings:controller="com.android.settings.network.telephony.RoamingPreferenceController"/>
+
+        <Preference
+            android:key="data_usage_summary"
+            android:title="@string/mobile_data_usage_title"
+            settings:controller="com.android.settings.network.telephony.DataUsagePreferenceController"/>
+
+        <com.android.settings.datausage.BillingCyclePreference
+            android:key="billing_preference"
+            android:title="@string/billing_cycle"
+            settings:controller="com.android.settings.datausage.BillingCyclePreferenceController"/>
+
+        <SwitchPreference
+            android:key="mms_message"
+            android:title="@string/mms_message_title"
+            android:summary="@string/mms_message_summary"
+            settings:controller="com.android.settings.network.telephony.MmsMessagePreferenceController"/>
+
+        <SwitchPreference
+            android:key="enhanced_4g_lte"
+            android:title="@string/enhanced_4g_lte_mode_title"
+            android:persistent="false"
+            android:summary="@string/enhanced_4g_lte_mode_summary"
+            settings:controller="com.android.settings.network.telephony.Enhanced4gLtePreferenceController"/>
+
+        <ListPreference
+            android:key="preferred_network_mode_key"
+            android:title="@string/preferred_network_mode_title"
+            android:summary="@string/preferred_network_mode_summary"
+            android:entries="@array/preferred_network_mode_choices"
+            android:entryValues="@array/preferred_network_mode_values"
+            android:dialogTitle="@string/preferred_network_mode_dialogtitle"
+            settings:controller="com.android.settings.network.telephony.PreferredNetworkModePreferenceController"/>
+
+        <ListPreference
+            android:key="enabled_networks_key"
+            android:title="@string/preferred_network_mode_title"
+            android:summary="@string/preferred_network_mode_summary"
+            android:entries="@array/enabled_networks_choices"
+            android:entryValues="@array/enabled_networks_values"
+            android:dialogTitle="@string/preferred_network_mode_dialogtitle"
+            settings:controller="com.android.settings.network.telephony.EnabledNetworkModePreferenceController"/>
+
+        <Preference
+            android:key="carrier_settings_version_key"
+            android:title="@string/carrier_settings_version"
+            settings:controller="com.android.settings.network.telephony.CarrierSettingsVersionPreferenceController"
+            settings:enableCopying="true"/>
+
+        <PreferenceCategory
+            android:key="calling_category"
+            android:title="@string/call_category">
+
+            <PreferenceScreen
+                android:key="wifi_calling_key"
+                android:title="@string/wifi_calling_settings_title"
+                settings:controller="com.android.settings.network.telephony.WifiCallingPreferenceController">
+                <intent android:action="android.intent.action.MAIN"
+                        android:targetPackage="com.android.settings"
+                        android:targetClass="com.android.settings.Settings$WifiCallingSettingsActivity">
+                    <extra android:name="show_drawer_menu" android:value="true"/>
+                </intent>
+            </PreferenceScreen>
+
+            <SwitchPreference
+                android:key="video_calling_key"
+                android:title="@string/video_calling_settings_title"
+                android:persistent="true"
+                settings:controller="com.android.settings.network.telephony.VideoCallingPreferenceController"/>
+
+        </PreferenceCategory>
+
+        <com.android.settings.network.telephony.cdma.CdmaListPreference
+            android:key="cdma_system_select_key"
+            android:title="@string/cdma_system_select_title"
+            android:summary="@string/cdma_system_select_summary"
+            android:entries="@array/cdma_system_select_choices"
+            android:entryValues="@array/cdma_system_select_values"
+            android:dialogTitle="@string/cdma_system_select_dialogtitle"
+            settings:controller="com.android.settings.network.telephony.cdma.CdmaSystemSelectPreferenceController"/>
+
+        <com.android.settings.network.telephony.cdma.CdmaListPreference
+            android:key="cdma_subscription_key"
+            android:title="@string/cdma_subscription_title"
+            android:summary="@string/cdma_subscription_summary"
+            android:entries="@array/cdma_subscription_choices"
+            android:entryValues="@array/cdma_subscription_values"
+            android:dialogTitle="@string/cdma_subscription_dialogtitle"
+            settings:controller="com.android.settings.network.telephony.cdma.CdmaSubscriptionPreferenceController"/>
+
+        <PreferenceCategory
+            android:key="network_operators_category_key"
+            android:title="@string/network_operator_category"
+            settings:controller="com.android.settings.widget.PreferenceCategoryController">
+
+            <SwitchPreference
+                android:key="auto_select_key"
+                android:title="@string/select_automatically"
+                settings:controller="com.android.settings.network.telephony.gsm.AutoSelectPreferenceController"/>
+
+            <Preference
+                android:key="choose_network_key"
+                android:title="@string/choose_network_title"
+                android:fragment="com.android.phone.NetworkSelectSetting"
+                settings:controller="com.android.settings.network.telephony.gsm.OpenNetworkSelectPagePreferenceController"/>
+        </PreferenceCategory>
+
+        <!--We want separate APN setting from reset of settings because we want user to change it with caution-->
+        <com.android.settingslib.RestrictedPreference
+            android:key="telephony_apn_key"
+            android:persistent="false"
+            android:title="@string/mobile_network_apn_title"
+            settings:allowDividerAbove="true"
+            settings:controller="com.android.settings.network.telephony.ApnPreferenceController"/>
+
+        <Preference
+            android:key="carrier_settings_key"
+            android:title="@string/carrier_settings_title"
+            settings:controller="com.android.settings.network.telephony.CarrierPreferenceController">
+        </Preference>
+
     </PreferenceCategory>
 
-    <!--We want separate APN setting from reset of settings because we want user to change it with caution-->
-    <com.android.settingslib.RestrictedPreference
-        android:key="telephony_apn_key"
-        android:persistent="false"
-        android:title="@string/mobile_network_apn_title"
-        settings:allowDividerAbove="true"
-        settings:controller="com.android.settings.network.telephony.ApnPreferenceController"/>
-
-    <Preference
-        android:key="carrier_settings_key"
-        android:title="@string/carrier_settings_title"
-        settings:controller="com.android.settings.network.telephony.CarrierPreferenceController">
-    </Preference>
-
 </PreferenceScreen>
diff --git a/res/xml/security_settings_face.xml b/res/xml/security_settings_face.xml
index ad37a3e..39bf73b 100644
--- a/res/xml/security_settings_face.xml
+++ b/res/xml/security_settings_face.xml
@@ -61,6 +61,11 @@
             android:key="security_settings_face_delete_faces_container"
             android:selectable="false"
             android:layout="@layout/face_remove_button" />
+
+        <com.android.settingslib.widget.LayoutPreference
+            android:key="security_settings_face_enroll_faces_container"
+            android:selectable="false"
+            android:layout="@layout/face_enroll_button " />
     </PreferenceCategory>
 
     <PreferenceCategory
diff --git a/src/com/android/settings/accounts/RemoveAccountPreferenceController.java b/src/com/android/settings/accounts/RemoveAccountPreferenceController.java
index 938606b..1bc30d0 100644
--- a/src/com/android/settings/accounts/RemoveAccountPreferenceController.java
+++ b/src/com/android/settings/accounts/RemoveAccountPreferenceController.java
@@ -17,8 +17,6 @@
 
 import android.accounts.Account;
 import android.accounts.AccountManager;
-import android.accounts.AccountManagerCallback;
-import android.accounts.AccountManagerFuture;
 import android.accounts.AuthenticatorException;
 import android.accounts.OperationCanceledException;
 import android.app.Activity;
@@ -30,6 +28,7 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.util.Log;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.Button;
@@ -153,28 +152,27 @@
         public void onClick(DialogInterface dialog, int which) {
             Activity activity = getTargetFragment().getActivity();
             AccountManager.get(activity).removeAccountAsUser(mAccount, activity,
-                    new AccountManagerCallback<Bundle>() {
-                        @Override
-                        public void run(AccountManagerFuture<Bundle> future) {
-                            boolean failed = true;
-                            try {
-                                if (future.getResult()
-                                        .getBoolean(AccountManager.KEY_BOOLEAN_RESULT)) {
-                                    failed = false;
-                                }
-                            } catch (OperationCanceledException e) {
-                                // handled below
-                            } catch (IOException e) {
-                                // handled below
-                            } catch (AuthenticatorException e) {
-                                // handled below
+                    future -> {
+                        final Activity targetActivity = getTargetFragment().getActivity();
+                        if (targetActivity == null || targetActivity.isFinishing()) {
+                            Log.w(TAG, "Activity is no longer alive, skipping results");
+                            return;
+                        }
+                        boolean failed = true;
+                        try {
+                            if (future.getResult()
+                                    .getBoolean(AccountManager.KEY_BOOLEAN_RESULT)) {
+                                failed = false;
                             }
-                            final Activity activity = getTargetFragment().getActivity();
-                            if (failed && activity != null && !activity.isFinishing()) {
-                                RemoveAccountFailureDialog.show(getTargetFragment());
-                            } else {
-                                activity.finish();
-                            }
+                        } catch (OperationCanceledException
+                                | IOException
+                                | AuthenticatorException e) {
+                            // handled below
+                        }
+                        if (failed) {
+                            RemoveAccountFailureDialog.show(getTargetFragment());
+                        } else {
+                            targetActivity.finish();
                         }
                     }, null, mUserHandle);
         }
diff --git a/src/com/android/settings/applications/AppStateNotificationBridge.java b/src/com/android/settings/applications/AppStateNotificationBridge.java
index 86f265e..d179642 100644
--- a/src/com/android/settings/applications/AppStateNotificationBridge.java
+++ b/src/com/android/settings/applications/AppStateNotificationBridge.java
@@ -108,10 +108,12 @@
             return StringUtil.formatRelativeTime(
                     context, System.currentTimeMillis() - state.lastSent, true);
         } else if (sortOrder == R.id.sort_order_frequent_notification) {
-            if (state.avgSentWeekly > 0) {
-                return context.getString(R.string.notifications_sent_weekly, state.avgSentWeekly);
+            if (state.avgSentDaily > 0) {
+                return context.getResources().getQuantityString(
+                        R.plurals.notifications_sent_daily, state.avgSentDaily, state.avgSentDaily);
             }
-            return context.getString(R.string.notifications_sent_daily, state.avgSentDaily);
+            return context.getResources().getQuantityString(R.plurals.notifications_sent_weekly,
+                    state.avgSentWeekly, state.avgSentWeekly);
         } else {
             return "";
         }
diff --git a/src/com/android/settings/biometrics/BiometricEnrollBase.java b/src/com/android/settings/biometrics/BiometricEnrollBase.java
index a961921..52eaa17 100644
--- a/src/com/android/settings/biometrics/BiometricEnrollBase.java
+++ b/src/com/android/settings/biometrics/BiometricEnrollBase.java
@@ -76,7 +76,7 @@
     public static final int BIOMETRIC_FIND_SENSOR_REQUEST = 2;
     public static final int LEARN_MORE_REQUEST = 3;
     public static final int CONFIRM_REQUEST = 4;
-    public static final int ENROLLING = 5;
+    public static final int ENROLL_REQUEST = 5;
 
     protected boolean mLaunchedConfirmLock;
     protected byte[] mToken;
diff --git a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
index d923e55..6887d51 100644
--- a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
@@ -72,12 +72,10 @@
 
         mFaceManager = Utils.getFaceManagerOrNull(this);
         final Button accessibilityButton = findViewById(R.id.accessibility_button);
-        final View footerView = findViewById(R.id.footer_layout);
         accessibilityButton.setOnClickListener(view -> {
             mSwitchDiversity.setChecked(true);
             accessibilityButton.setVisibility(View.GONE);
             mSwitchDiversity.setVisibility(View.VISIBLE);
-            footerView.setVisibility(View.GONE);
         });
 
         mSwitchDiversity = findViewById(R.id.toggle_diversity);
diff --git a/src/com/android/settings/biometrics/face/FaceSettings.java b/src/com/android/settings/biometrics/face/FaceSettings.java
index b65a31d..48370d9 100644
--- a/src/com/android/settings/biometrics/face/FaceSettings.java
+++ b/src/com/android/settings/biometrics/face/FaceSettings.java
@@ -31,6 +31,8 @@
 import android.provider.SearchIndexableResource;
 import android.util.Log;
 
+import androidx.preference.Preference;
+
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.Utils;
@@ -52,7 +54,7 @@
 public class FaceSettings extends DashboardFragment {
 
     private static final String TAG = "FaceSettings";
-    private static final String KEY_TOKEN = "key_token";
+    private static final String KEY_TOKEN = "hw_auth_token";
 
     private UserManager mUserManager;
     private FaceManager mFaceManager;
@@ -60,12 +62,23 @@
     private byte[] mToken;
     private FaceSettingsAttentionPreferenceController mAttentionController;
     private FaceSettingsRemoveButtonPreferenceController mRemoveController;
+    private FaceSettingsEnrollButtonPreferenceController mEnrollController;
     private List<AbstractPreferenceController> mControllers;
 
+    private List<Preference> mTogglePreferences;
+    private Preference mRemoveButton;
+    private Preference mEnrollButton;
+
     private final FaceSettingsRemoveButtonPreferenceController.Listener mRemovalListener = () -> {
-        if (getActivity() != null) {
-            getActivity().finish();
+
+        // Disable the toggles until the user re-enrolls
+        for (Preference preference : mTogglePreferences) {
+            preference.setEnabled(false);
         }
+
+        // Hide the "remove" button and show the "set up face authentication" button.
+        mRemoveButton.setVisible(false);
+        mEnrollButton.setVisible(true);
     };
 
     public static boolean isAvailable(Context context) {
@@ -98,15 +111,28 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        mToken = getIntent().getByteArrayExtra(KEY_TOKEN);
         mUserManager = getPrefContext().getSystemService(UserManager.class);
         mFaceManager = getPrefContext().getSystemService(FaceManager.class);
         mUserId = getActivity().getIntent().getIntExtra(
                 Intent.EXTRA_USER_ID, UserHandle.myUserId());
 
+        Preference keyguardPref = findPreference(FaceSettingsKeyguardPreferenceController.KEY);
+        Preference appPref = findPreference(FaceSettingsAppPreferenceController.KEY);
+        Preference attentionPref = findPreference(FaceSettingsAttentionPreferenceController.KEY);
+        Preference confirmPref = findPreference(FaceSettingsConfirmPreferenceController.KEY);
+        mTogglePreferences = new ArrayList<>(
+                Arrays.asList(keyguardPref, appPref, attentionPref, confirmPref));
+
+        mRemoveButton = findPreference(FaceSettingsRemoveButtonPreferenceController.KEY);
+        mEnrollButton = findPreference(FaceSettingsEnrollButtonPreferenceController.KEY);
+
         // There is no better way to do this :/
         for (AbstractPreferenceController controller : mControllers) {
             if (controller instanceof  FaceSettingsPreferenceController) {
                 ((FaceSettingsPreferenceController) controller).setUserId(mUserId);
+            } else if (controller instanceof FaceSettingsEnrollButtonPreferenceController) {
+                ((FaceSettingsEnrollButtonPreferenceController) controller).setUserId(mUserId);
             }
         }
         mRemoveController.setUserId(mUserId);
@@ -137,7 +163,12 @@
         super.onResume();
         if (mToken != null) {
             mAttentionController.setToken(mToken);
+            mEnrollController.setToken(mToken);
         }
+
+        final boolean hasEnrolled = mFaceManager.hasEnrolledTemplates(mUserId);
+        mEnrollButton.setVisible(!hasEnrolled);
+        mRemoveButton.setVisible(hasEnrolled);
     }
 
     @Override
@@ -152,6 +183,7 @@
                             ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
                     if (mToken != null) {
                         mAttentionController.setToken(mToken);
+                        mEnrollController.setToken(mToken);
                     }
                 }
             }
@@ -188,6 +220,9 @@
                 mRemoveController = (FaceSettingsRemoveButtonPreferenceController) controller;
                 mRemoveController.setListener(mRemovalListener);
                 mRemoveController.setActivity((SettingsActivity) getActivity());
+            } else if (controller instanceof FaceSettingsEnrollButtonPreferenceController) {
+                mEnrollController = (FaceSettingsEnrollButtonPreferenceController) controller;
+                mEnrollController.setActivity((SettingsActivity) getActivity());
             }
         }
 
@@ -204,6 +239,7 @@
         controllers.add(new FaceSettingsRemoveButtonPreferenceController(context));
         controllers.add(new FaceSettingsFooterPreferenceController(context));
         controllers.add(new FaceSettingsConfirmPreferenceController(context));
+        controllers.add(new FaceSettingsEnrollButtonPreferenceController(context));
         return controllers;
     }
 
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsAppPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsAppPreferenceController.java
index 78389b6..1ffcb4c 100644
--- a/src/com/android/settings/biometrics/face/FaceSettingsAppPreferenceController.java
+++ b/src/com/android/settings/biometrics/face/FaceSettingsAppPreferenceController.java
@@ -19,22 +19,28 @@
 import static android.provider.Settings.Secure.FACE_UNLOCK_APP_ENABLED;
 
 import android.content.Context;
+import android.hardware.face.FaceManager;
 import android.provider.Settings;
 
+import androidx.preference.Preference;
+
 /**
  * Preference controller for Face settings page controlling the ability to use
  * Face authentication in apps (through BiometricPrompt).
  */
 public class FaceSettingsAppPreferenceController extends FaceSettingsPreferenceController {
 
-    private static final String KEY = "security_settings_face_app";
+    static final String KEY = "security_settings_face_app";
 
     private static final int ON = 1;
     private static final int OFF = 0;
     private static final int DEFAULT = ON;  // face unlock is enabled for BiometricPrompt by default
 
+    private FaceManager mFaceManager;
+
     public FaceSettingsAppPreferenceController(Context context, String preferenceKey) {
         super(context, preferenceKey);
+        mFaceManager = context.getSystemService(FaceManager.class);
     }
 
     public FaceSettingsAppPreferenceController(Context context) {
@@ -57,6 +63,18 @@
     }
 
     @Override
+    public void updateState(Preference preference) {
+        super.updateState(preference);
+        if (!FaceSettings.isAvailable(mContext)) {
+            preference.setEnabled(false);
+        } else if (!mFaceManager.hasEnrolledTemplates(getUserId())) {
+            preference.setEnabled(false);
+        } else {
+            preference.setEnabled(true);
+        }
+    }
+
+    @Override
     public int getAvailabilityStatus() {
         return AVAILABLE;
     }
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceController.java
index 9e4fd38..ef90b1e 100644
--- a/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceController.java
+++ b/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceController.java
@@ -60,8 +60,12 @@
         @Override
         public void onCompleted(boolean success, int feature, boolean value) {
             if (feature == FaceManager.FEATURE_REQUIRE_ATTENTION && success) {
-                mPreference.setEnabled(true);
-                mPreference.setChecked(value);
+                if (!mFaceManager.hasEnrolledTemplates(getUserId())) {
+                    mPreference.setEnabled(false);
+                } else {
+                    mPreference.setEnabled(true);
+                    mPreference.setChecked(value);
+                }
             }
         }
     };
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsConfirmPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsConfirmPreferenceController.java
index b721072..7dbe557 100644
--- a/src/com/android/settings/biometrics/face/FaceSettingsConfirmPreferenceController.java
+++ b/src/com/android/settings/biometrics/face/FaceSettingsConfirmPreferenceController.java
@@ -19,8 +19,11 @@
 import static android.provider.Settings.Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION;
 
 import android.content.Context;
+import android.hardware.face.FaceManager;
 import android.provider.Settings;
 
+import androidx.preference.Preference;
+
 import com.android.settings.core.TogglePreferenceController;
 
 /**
@@ -28,12 +31,14 @@
  */
 public class FaceSettingsConfirmPreferenceController extends FaceSettingsPreferenceController {
 
-    private static final String KEY = "security_settings_face_require_confirmation";
+    static final String KEY = "security_settings_face_require_confirmation";
 
     private static final int ON = 1;
     private static final int OFF = 0;
     private static final int DEFAULT = OFF;
 
+    private FaceManager mFaceManager;
+
     public FaceSettingsConfirmPreferenceController(Context context) {
         this(context, KEY);
     }
@@ -41,6 +46,7 @@
     public FaceSettingsConfirmPreferenceController(Context context,
             String preferenceKey) {
         super(context, preferenceKey);
+        mFaceManager = context.getSystemService(FaceManager.class);
     }
 
     @Override
@@ -56,6 +62,18 @@
     }
 
     @Override
+    public void updateState(Preference preference) {
+        super.updateState(preference);
+        if (!FaceSettings.isAvailable(mContext)) {
+            preference.setEnabled(false);
+        } else if (!mFaceManager.hasEnrolledTemplates(getUserId())) {
+            preference.setEnabled(false);
+        } else {
+            preference.setEnabled(true);
+        }
+    }
+
+    @Override
     public int getAvailabilityStatus() {
         return AVAILABLE;
     }
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsEnrollButtonPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsEnrollButtonPreferenceController.java
new file mode 100644
index 0000000..ec7b194
--- /dev/null
+++ b/src/com/android/settings/biometrics/face/FaceSettingsEnrollButtonPreferenceController.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2019 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.biometrics.face;
+
+import android.content.Context;
+import android.content.Intent;
+import android.view.View;
+import android.widget.Button;
+
+import androidx.preference.Preference;
+
+import com.android.settings.R;
+import com.android.settings.SettingsActivity;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.password.ChooseLockSettingsHelper;
+import com.android.settingslib.widget.LayoutPreference;
+
+/**
+ * Preference controller that allows a user to enroll their face.
+ */
+public class FaceSettingsEnrollButtonPreferenceController extends BasePreferenceController
+        implements View.OnClickListener {
+
+    private static final String TAG = "FaceSettings/Remove";
+    static final String KEY = "security_settings_face_enroll_faces_container";
+
+    private int mUserId;
+    private byte[] mToken;
+    private SettingsActivity mActivity;
+    private Button mButton;
+
+    public FaceSettingsEnrollButtonPreferenceController(Context context) {
+        this(context, KEY);
+    }
+
+    public FaceSettingsEnrollButtonPreferenceController(Context context,
+            String preferenceKey) {
+        super(context, preferenceKey);
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        super.updateState(preference);
+
+        mButton = ((LayoutPreference) preference)
+                .findViewById(R.id.security_settings_face_settings_enroll_button);
+        mButton.setOnClickListener(this);
+    }
+
+    @Override
+    public void onClick(View v) {
+        final Intent intent = new Intent();
+        intent.setClassName("com.android.settings", FaceEnrollIntroduction.class.getName());
+        intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
+        intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken);
+        mContext.startActivity(intent);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+
+    public void setUserId(int userId) {
+        mUserId = userId;
+    }
+
+    public void setToken(byte[] token) {
+        mToken = token;
+    }
+
+    public void setActivity(SettingsActivity activity) {
+        mActivity = activity;
+    }
+}
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsKeyguardPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsKeyguardPreferenceController.java
index 3a7865d..92eab85 100644
--- a/src/com/android/settings/biometrics/face/FaceSettingsKeyguardPreferenceController.java
+++ b/src/com/android/settings/biometrics/face/FaceSettingsKeyguardPreferenceController.java
@@ -20,6 +20,7 @@
 
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
+import android.hardware.face.FaceManager;
 import android.os.UserHandle;
 import android.provider.Settings;
 
@@ -39,8 +40,11 @@
     private static final int OFF = 0;
     private static final int DEFAULT = ON;  // face unlock is enabled on keyguard by default
 
+    private FaceManager mFaceManager;
+
     public FaceSettingsKeyguardPreferenceController(Context context, String preferenceKey) {
         super(context, preferenceKey);
+        mFaceManager = context.getSystemService(FaceManager.class);
     }
 
     public FaceSettingsKeyguardPreferenceController(Context context) {
@@ -76,6 +80,8 @@
             preference.setEnabled(false);
         } else if (adminDisabled()) {
             preference.setEnabled(false);
+        } else if (!mFaceManager.hasEnrolledTemplates(getUserId())) {
+            preference.setEnabled(false);
         } else {
             preference.setEnabled(true);
         }
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java
index 600ea37..68ca259 100644
--- a/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java
+++ b/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java
@@ -24,7 +24,6 @@
 import android.hardware.face.Face;
 import android.hardware.face.FaceManager;
 import android.os.Bundle;
-import android.os.UserHandle;
 import android.util.Log;
 import android.view.View;
 import android.widget.Button;
@@ -48,7 +47,7 @@
         implements View.OnClickListener {
 
     private static final String TAG = "FaceSettings/Remove";
-    private static final String KEY = "security_settings_face_delete_faces_container";
+    static final String KEY = "security_settings_face_delete_faces_container";
 
     public static class ConfirmRemoveDialog extends InstrumentedDialogFragment {
 
@@ -85,6 +84,7 @@
     private Listener mListener;
     private SettingsActivity mActivity;
     private int mUserId;
+    private boolean mRemoving;
 
     private final Context mContext;
     private final FaceManager mFaceManager;
@@ -103,6 +103,7 @@
                 if (!faces.isEmpty()) {
                     mButton.setEnabled(true);
                 } else {
+                    mRemoving = false;
                     mListener.onRemoved();
                 }
             } else {
@@ -154,6 +155,12 @@
         mButton = ((LayoutPreference) preference)
                 .findViewById(R.id.security_settings_face_settings_remove_button);
         mButton.setOnClickListener(this);
+
+        if (!FaceSettings.isAvailable(mContext)) {
+            mButton.setEnabled(false);
+        } else {
+            mButton.setEnabled(!mRemoving);
+        }
     }
 
     @Override
@@ -169,6 +176,7 @@
     @Override
     public void onClick(View v) {
         if (v == mButton) {
+            mRemoving = true;
             mButton.setEnabled(false);
             ConfirmRemoveDialog dialog = new ConfirmRemoveDialog();
             dialog.setOnClickListener(mOnClickListener);
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java
index 5589592..733fb3f 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java
@@ -147,7 +147,7 @@
             getSupportFragmentManager().beginTransaction().remove(mSidecar).
                     commitAllowingStateLoss();
             mSidecar = null;
-            startActivityForResult(getFingerprintEnrollingIntent(), ENROLLING);
+            startActivityForResult(getFingerprintEnrollingIntent(), ENROLL_REQUEST);
         }
     }
 
@@ -162,7 +162,7 @@
             } else {
                 finish();
             }
-        } else if (requestCode == ENROLLING) {
+        } else if (requestCode == ENROLL_REQUEST) {
             if (resultCode == RESULT_FINISHED) {
                 setResult(RESULT_FINISHED);
                 finish();
diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java
index 0e935c0..31055cc 100644
--- a/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java
@@ -109,6 +109,10 @@
      * Force to update the list of bluetooth devices
      */
     public void forceUpdate() {
+        if (mLocalManager == null) {
+            Log.e(TAG, "forceUpdate() Bluetooth is not supported on this device");
+            return;
+        }
         if (BluetoothAdapter.getDefaultAdapter().isEnabled()) {
             final Collection<CachedBluetoothDevice> cachedDevices =
                     mLocalManager.getCachedDeviceManager().getCachedDevicesCopy();
@@ -121,6 +125,10 @@
     }
 
     public void removeAllDevicesFromPreference() {
+        if (mLocalManager == null) {
+            Log.e(TAG, "removeAllDevicesFromPreference() BT is not supported on this device");
+            return;
+        }
         final Collection<CachedBluetoothDevice> cachedDevices =
                 mLocalManager.getCachedDeviceManager().getCachedDevicesCopy();
         for (CachedBluetoothDevice cachedBluetoothDevice : cachedDevices) {
diff --git a/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupController.java b/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupController.java
index be82284..cac46b0 100644
--- a/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupController.java
+++ b/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupController.java
@@ -83,9 +83,11 @@
     @Override
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
+
+        mPreferenceGroup = screen.findPreference(KEY);
+        mPreferenceGroup.setVisible(false);
+
         if (isAvailable()) {
-            mPreferenceGroup = screen.findPreference(KEY);
-            mPreferenceGroup.setVisible(false);
             updateTitle();
             mBluetoothDeviceUpdater.setPrefContext(screen.getContext());
             mBluetoothDeviceUpdater.forceUpdate();
diff --git a/src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java b/src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java
index aa83e67..957737a 100644
--- a/src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java
+++ b/src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java
@@ -73,10 +73,11 @@
     @Override
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
-        if (isAvailable()) {
-            mPreferenceGroup = screen.findPreference(KEY);
-            mPreferenceGroup.setVisible(false);
 
+        mPreferenceGroup = screen.findPreference(KEY);
+        mPreferenceGroup.setVisible(false);
+
+        if (isAvailable()) {
             final Context context = screen.getContext();
             mBluetoothDeviceUpdater.setPrefContext(context);
             mBluetoothDeviceUpdater.forceUpdate();
@@ -88,7 +89,11 @@
 
     @Override
     public int getAvailabilityStatus() {
-        return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)
+        final PackageManager packageManager = mContext.getPackageManager();
+        return (packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)
+                || packageManager.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY)
+                || packageManager.hasSystemFeature(PackageManager.FEATURE_USB_HOST)
+                || mConnectedDockUpdater != null)
                 ? AVAILABLE_UNSEARCHABLE
                 : UNSUPPORTED_ON_DEVICE;
     }
diff --git a/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java b/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java
index 45f128d..5b23d69 100644
--- a/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java
+++ b/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java
@@ -52,7 +52,8 @@
 
     @Override
     public int getAvailabilityStatus() {
-        return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)
+        return (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)
+                || mSavedDockUpdater != null)
                 ? AVAILABLE
                 : CONDITIONALLY_UNAVAILABLE;
     }
diff --git a/src/com/android/settings/connecteddevice/SavedDeviceGroupController.java b/src/com/android/settings/connecteddevice/SavedDeviceGroupController.java
index e1dc750..062fa2d 100644
--- a/src/com/android/settings/connecteddevice/SavedDeviceGroupController.java
+++ b/src/com/android/settings/connecteddevice/SavedDeviceGroupController.java
@@ -73,10 +73,10 @@
 
     @Override
     public void displayPreference(PreferenceScreen screen) {
-        if (isAvailable()) {
-            mPreferenceGroup = screen.findPreference(KEY);
-            mPreferenceGroup.setVisible(false);
+        mPreferenceGroup = screen.findPreference(KEY);
+        mPreferenceGroup.setVisible(false);
 
+        if (isAvailable()) {
             final Context context = screen.getContext();
             mBluetoothDeviceUpdater.setPrefContext(context);
             mBluetoothDeviceUpdater.forceUpdate();
@@ -87,7 +87,8 @@
 
     @Override
     public int getAvailabilityStatus() {
-        return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)
+        return (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)
+                || mSavedDockUpdater != null)
                 ? AVAILABLE
                 : UNSUPPORTED_ON_DEVICE;
     }
diff --git a/src/com/android/settings/development/SystemServerHeapDumpPreferenceController.java b/src/com/android/settings/development/SystemServerHeapDumpPreferenceController.java
index 599162e..e6701ce 100644
--- a/src/com/android/settings/development/SystemServerHeapDumpPreferenceController.java
+++ b/src/com/android/settings/development/SystemServerHeapDumpPreferenceController.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.os.Build;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.RemoteException;
 import android.os.UserManager;
 import android.util.Log;
@@ -47,7 +48,7 @@
         super(context);
 
         mUserManager = context.getSystemService(UserManager.class);
-        mHandler = new Handler();
+        mHandler = new Handler(Looper.getMainLooper());
     }
 
     @Override
diff --git a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
index a014c29..95f913e 100644
--- a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
+++ b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
@@ -406,13 +406,7 @@
     }
 
     private SubscriptionInfo getPhoneSubscriptionInfo(int slotId) {
-        final List<SubscriptionInfo> subscriptionInfoList = SubscriptionManager.from(
-                mContext).getActiveSubscriptionInfoList(true);
-        if (subscriptionInfoList != null && subscriptionInfoList.size() > slotId) {
-            return subscriptionInfoList.get(slotId);
-        } else {
-            return null;
-        }
+        return SubscriptionManager.from(mContext).getActiveSubscriptionInfoForSimSlotIndex(slotId);
     }
 
     @VisibleForTesting
diff --git a/src/com/android/settings/display/AutoBrightnessDetailPreferenceController.java b/src/com/android/settings/display/AutoBrightnessDetailPreferenceController.java
new file mode 100644
index 0000000..a04ddbf
--- /dev/null
+++ b/src/com/android/settings/display/AutoBrightnessDetailPreferenceController.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 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.display;
+
+import android.content.Context;
+
+public class AutoBrightnessDetailPreferenceController extends AutoBrightnessPreferenceController {
+
+    public AutoBrightnessDetailPreferenceController(Context context, String key) {
+        super(context, key);
+    }
+
+    @Override
+    @AvailabilityStatus
+    public int getAvailabilityStatus() {
+        return mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_automatic_brightness_available)
+                ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+    }
+
+    @Override
+    public boolean isSliceable() {
+        return true;
+    }
+}
diff --git a/src/com/android/settings/display/AutoBrightnessPreferenceController.java b/src/com/android/settings/display/AutoBrightnessPreferenceController.java
index 3b53fa8..0018d84 100644
--- a/src/com/android/settings/display/AutoBrightnessPreferenceController.java
+++ b/src/com/android/settings/display/AutoBrightnessPreferenceController.java
@@ -19,7 +19,6 @@
 
 import android.content.Context;
 import android.provider.Settings;
-import android.text.TextUtils;
 
 import com.android.settings.R;
 import com.android.settings.core.TogglePreferenceController;
@@ -52,16 +51,11 @@
     public int getAvailabilityStatus() {
         return mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_automatic_brightness_available)
-                ? AVAILABLE
+                ? AVAILABLE_UNSEARCHABLE
                 : UNSUPPORTED_ON_DEVICE;
     }
 
     @Override
-    public boolean isSliceable() {
-        return TextUtils.equals(getPreferenceKey(), "auto_brightness");
-    }
-
-    @Override
     public CharSequence getSummary() {
         return mContext.getText(isChecked()
                 ? R.string.auto_brightness_summary_on
diff --git a/src/com/android/settings/gestures/SystemNavigationPreferenceController.java b/src/com/android/settings/gestures/SystemNavigationPreferenceController.java
index 5f58fcf..f2c8252 100644
--- a/src/com/android/settings/gestures/SystemNavigationPreferenceController.java
+++ b/src/com/android/settings/gestures/SystemNavigationPreferenceController.java
@@ -139,12 +139,11 @@
      * Enables the specified overlay package.
      */
     static void setNavBarInteractionMode(IOverlayManager overlayManager, String overlayPackage) {
-        setOverlayEnabled(overlayManager, NAV_BAR_MODE_3BUTTON_OVERLAY,
-                overlayPackage == NAV_BAR_MODE_3BUTTON_OVERLAY);
-        setOverlayEnabled(overlayManager, NAV_BAR_MODE_2BUTTON_OVERLAY,
-                overlayPackage == NAV_BAR_MODE_2BUTTON_OVERLAY);
-        setOverlayEnabled(overlayManager, NAV_BAR_MODE_GESTURAL_OVERLAY,
-                overlayPackage == NAV_BAR_MODE_GESTURAL_OVERLAY);
+        try {
+            overlayManager.setEnabledExclusiveInCategory(overlayPackage, USER_CURRENT);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
     }
 
     static boolean isSwipeUpEnabled(Context context) {
@@ -159,12 +158,4 @@
         return NAV_BAR_MODE_GESTURAL == context.getResources().getInteger(
                 com.android.internal.R.integer.config_navBarInteractionMode);
     }
-
-    static void setOverlayEnabled(IOverlayManager overlayManager, String pkg, boolean enabled) {
-        try {
-            overlayManager.setEnabled(pkg, enabled, USER_CURRENT);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
 }
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCard.java b/src/com/android/settings/homepage/contextualcards/ContextualCard.java
index ede12fb..ccfb22d 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCard.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCard.java
@@ -72,6 +72,7 @@
     @LayoutRes
     private final int mViewType;
     private final boolean mIsPendingDismiss;
+    private final boolean mHasInlineAction;
 
     public String getName() {
         return mName;
@@ -161,6 +162,10 @@
         return mIsPendingDismiss;
     }
 
+    public boolean hasInlineAction() {
+        return mHasInlineAction;
+    }
+
     public Builder mutate() {
         return mBuilder;
     }
@@ -187,6 +192,7 @@
         mIsLargeCard = builder.mIsLargeCard;
         mViewType = builder.mViewType;
         mIsPendingDismiss = builder.mIsPendingDismiss;
+        mHasInlineAction = builder.mHasInlineAction;
     }
 
     ContextualCard(Cursor c) {
@@ -234,6 +240,8 @@
         mBuilder.setViewType(mViewType);
         mIsPendingDismiss = false;
         mBuilder.setIsPendingDismiss(mIsPendingDismiss);
+        mHasInlineAction = false;
+        mBuilder.setHasInlineAction(mHasInlineAction);
     }
 
     @Override
@@ -286,6 +294,7 @@
         @LayoutRes
         private int mViewType;
         private boolean mIsPendingDismiss;
+        private boolean mHasInlineAction;
 
         public Builder setName(String name) {
             mName = name;
@@ -387,6 +396,11 @@
             return this;
         }
 
+        public Builder setHasInlineAction(boolean hasInlineAction) {
+            mHasInlineAction = hasInlineAction;
+            return this;
+        }
+
         public ContextualCard build() {
             return new ContextualCard(this);
         }
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardsDiffCallback.java b/src/com/android/settings/homepage/contextualcards/ContextualCardsDiffCallback.java
index d1623cd..58d6a41 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardsDiffCallback.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardsDiffCallback.java
@@ -20,7 +20,6 @@
 
 import java.util.List;
 
-//TODO(b/117816826): add test cases for DiffUtil.
 /**
  * A DiffCallback to calculate the difference between old and new {@link ContextualCard} List.
  */
@@ -53,6 +52,11 @@
 
     @Override
     public boolean areContentsTheSame(int oldCardPosition, int newCardPosition) {
+        // Slices with toggles needs to be updated continuously, which means their contents may
+        // change. So here we assume the content will always be different to force view rebinding.
+        if (mNewCards.get(newCardPosition).hasInlineAction()) {
+            return false;
+        }
         return mOldCards.get(oldCardPosition).equals(mNewCards.get(newCardPosition));
     }
 }
\ No newline at end of file
diff --git a/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java b/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java
index 811aaa2..8558ee7 100644
--- a/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java
+++ b/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java
@@ -26,11 +26,14 @@
 
 import androidx.annotation.VisibleForTesting;
 import androidx.slice.Slice;
+import androidx.slice.SliceMetadata;
 import androidx.slice.SliceViewManager;
+import androidx.slice.core.SliceAction;
 
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
+import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -41,7 +44,9 @@
     private static final long LATCH_TIMEOUT_MS = 200;
 
     private final Context mContext;
-    private final ContextualCard mCard;
+
+    @VisibleForTesting
+    ContextualCard mCard;
 
     EligibleCardChecker(Context context, ContextualCard card) {
         mContext = context;
@@ -93,6 +98,11 @@
         }
 
         final Slice slice = bindSlice(uri);
+
+        if (isSliceToggleable(slice)) {
+            mCard = card.mutate().setHasInlineAction(true).build();
+        }
+
         if (slice == null || slice.hasHint(HINT_ERROR)) {
             Log.w(TAG, "Failed to bind slice, not eligible for display " + uri);
             return false;
@@ -133,4 +143,12 @@
         }
         return returnSlice[0];
     }
+
+    @VisibleForTesting
+    boolean isSliceToggleable(Slice slice) {
+        final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
+        final List<SliceAction> toggles = metadata.getToggles();
+
+        return !toggles.isEmpty();
+    }
 }
diff --git a/src/com/android/settings/network/MobileNetworkListController.java b/src/com/android/settings/network/MobileNetworkListController.java
index a2e4116..d0e14ce 100644
--- a/src/com/android/settings/network/MobileNetworkListController.java
+++ b/src/com/android/settings/network/MobileNetworkListController.java
@@ -98,7 +98,7 @@
         mPreferences = new ArrayMap<>();
 
         final List<SubscriptionInfo> subscriptions = SubscriptionUtil.getAvailableSubscriptions(
-                mSubscriptionManager);
+                mContext);
         for (SubscriptionInfo info : subscriptions) {
             final int subId = info.getSubscriptionId();
             Preference pref = existingPreferences.remove(subId);
diff --git a/src/com/android/settings/network/MobileNetworkSummaryController.java b/src/com/android/settings/network/MobileNetworkSummaryController.java
index ae115eb..9498c4e 100644
--- a/src/com/android/settings/network/MobileNetworkSummaryController.java
+++ b/src/com/android/settings/network/MobileNetworkSummaryController.java
@@ -22,6 +22,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.UserManager;
+import android.provider.Settings;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.euicc.EuiccManager;
@@ -99,7 +100,7 @@
     @Override
     public CharSequence getSummary() {
         final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(
-                mSubscriptionManager);
+                mContext);
         if (subs.isEmpty()) {
             if (MobileNetworkUtils.showEuiccSettings(mContext)) {
                 return mContext.getResources().getString(
@@ -132,7 +133,7 @@
         mPreference.setEnabled(!mChangeListener.isAirplaneModeOn());
 
         final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(
-                mSubscriptionManager);
+                mContext);
 
         if (subs.isEmpty()) {
             if (MobileNetworkUtils.showEuiccSettings(mContext)) {
@@ -154,6 +155,7 @@
             if (subs.size() == 1) {
                 mPreference.setOnPreferenceClickListener((Preference pref) -> {
                     final Intent intent = new Intent(mContext, MobileNetworkActivity.class);
+                    intent.putExtra(Settings.EXTRA_SUB_ID, subs.get(0).getSubscriptionId());
                     mContext.startActivity(intent);
                     return true;
                 });
diff --git a/src/com/android/settings/network/SubscriptionUtil.java b/src/com/android/settings/network/SubscriptionUtil.java
index 5f1beca..86655d4 100644
--- a/src/com/android/settings/network/SubscriptionUtil.java
+++ b/src/com/android/settings/network/SubscriptionUtil.java
@@ -16,8 +16,15 @@
 
 package com.android.settings.network;
 
+import static android.telephony.UiccSlotInfo.CARD_STATE_INFO_PRESENT;
+
+import static com.android.internal.util.CollectionUtils.emptyIfNull;
+
+import android.content.Context;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.telephony.UiccSlotInfo;
 import android.text.TextUtils;
 
 import androidx.annotation.VisibleForTesting;
@@ -27,6 +34,7 @@
 import java.util.List;
 
 public class SubscriptionUtil {
+    private static final String TAG = "SubscriptionUtil";
     private static List<SubscriptionInfo> sAvailableResultsForTesting;
     private static List<SubscriptionInfo> sActiveResultsForTesting;
 
@@ -44,21 +52,56 @@
         if (sActiveResultsForTesting != null) {
             return sActiveResultsForTesting;
         }
-        List<SubscriptionInfo> subscriptions = manager.getActiveSubscriptionInfoList(true);
+        final List<SubscriptionInfo> subscriptions = manager.getActiveSubscriptionInfoList(true);
         if (subscriptions == null) {
             return new ArrayList<>();
         }
         return subscriptions;
     }
 
-    public static List<SubscriptionInfo> getAvailableSubscriptions(SubscriptionManager manager) {
+    private static boolean isInactiveInsertedPSim(UiccSlotInfo slotInfo) {
+        return !slotInfo.getIsEuicc() && !slotInfo.getIsActive() &&
+                slotInfo.getCardStateInfo() == CARD_STATE_INFO_PRESENT;
+    }
+
+    public static List<SubscriptionInfo> getAvailableSubscriptions(Context context) {
         if (sAvailableResultsForTesting != null) {
             return sAvailableResultsForTesting;
         }
-        List<SubscriptionInfo> subscriptions = manager.getSelectableSubscriptionInfoList();
-        if (subscriptions == null) {
-            subscriptions = new ArrayList<>();
+        final SubscriptionManager subMgr = context.getSystemService(SubscriptionManager.class);
+        final TelephonyManager telMgr = context.getSystemService(TelephonyManager.class);
+
+        List<SubscriptionInfo> subscriptions =
+                new ArrayList<>(emptyIfNull(subMgr.getSelectableSubscriptionInfoList()));
+
+        // Look for inactive but present physical SIMs that are missing from the selectable list.
+        final List<UiccSlotInfo> missing = new ArrayList<>();
+        UiccSlotInfo[] slotsInfo =  telMgr.getUiccSlotsInfo();
+        for (int i = 0; slotsInfo != null && i < slotsInfo.length; i++) {
+            final UiccSlotInfo slotInfo = slotsInfo[i];
+            if (isInactiveInsertedPSim(slotInfo)) {
+                final int index = slotInfo.getLogicalSlotIdx();
+                final String cardId = slotInfo.getCardId();
+
+                final boolean found = subscriptions.stream().anyMatch(info ->
+                        index == info.getSimSlotIndex() && cardId.equals(info.getCardString()));
+                if (!found) {
+                    missing.add(slotInfo);
+                }
+            }
         }
+        if (!missing.isEmpty()) {
+            for (SubscriptionInfo info : subMgr.getAllSubscriptionInfoList()) {
+                for (UiccSlotInfo slotInfo : missing) {
+                    if (info.getSimSlotIndex() == slotInfo.getLogicalSlotIdx() &&
+                    info.getCardString().equals(slotInfo.getCardId())) {
+                        subscriptions.add(info);
+                        break;
+                    }
+                }
+            }
+        }
+
         // With some carriers such as Google Fi which provide a sort of virtual service that spans
         // across multiple underlying networks, we end up with subscription entries for the
         // underlying networks that need to be hidden from the user in the UI.
diff --git a/src/com/android/settings/network/telephony/DisabledSubscriptionController.java b/src/com/android/settings/network/telephony/DisabledSubscriptionController.java
new file mode 100644
index 0000000..22cbb13
--- /dev/null
+++ b/src/com/android/settings/network/telephony/DisabledSubscriptionController.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2019 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.network.telephony;
+
+import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE;
+import static androidx.lifecycle.Lifecycle.Event.ON_RESUME;
+
+import android.content.Context;
+import android.telephony.SubscriptionManager;
+
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.network.SubscriptionsChangeListener;
+
+public class DisabledSubscriptionController extends BasePreferenceController implements
+        SubscriptionsChangeListener.SubscriptionsChangeListenerClient, LifecycleObserver {
+    private PreferenceCategory mCategory;
+    private int mSubId;
+    private SubscriptionsChangeListener mChangeListener;
+    private SubscriptionManager mSubscriptionManager;
+
+    public DisabledSubscriptionController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+        mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+        mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class);
+        mChangeListener = new SubscriptionsChangeListener(context, this);
+    }
+
+    public void init(Lifecycle lifecycle, int subId) {
+        lifecycle.addObserver(this);
+        mSubId = subId;
+    }
+
+    @OnLifecycleEvent(ON_RESUME)
+    public void onResume() {
+        mChangeListener.start();
+        update();
+    }
+
+    @OnLifecycleEvent(ON_PAUSE)
+    public void onPause() {
+        mChangeListener.stop();
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mCategory = screen.findPreference(getPreferenceKey());
+        update();
+    }
+
+    private void update() {
+        if (mCategory == null || mSubId ==  SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            return;
+        }
+        mCategory.setVisible(mSubscriptionManager.isSubscriptionEnabled(mSubId));
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE_UNSEARCHABLE;
+    }
+
+    @Override
+    public void onAirplaneModeChanged(boolean airplaneModeEnabled) {
+    }
+
+    @Override
+    public void onSubscriptionsChanged() {
+        update();
+    }
+}
diff --git a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
index a0e50fc..0a39bfd 100644
--- a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
+++ b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
@@ -17,27 +17,24 @@
 package com.android.settings.network.telephony;
 
 import android.content.Context;
-import android.database.ContentObserver;
-import android.net.Uri;
 import android.os.Handler;
 import android.os.Looper;
-import android.provider.Settings;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 
-import com.android.settings.network.MobileDataContentObserver;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnStart;
-import com.android.settingslib.core.lifecycle.events.OnStop;
-
 import androidx.annotation.VisibleForTesting;
 import androidx.fragment.app.FragmentManager;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 import androidx.preference.SwitchPreference;
 
+import com.android.settings.network.MobileDataContentObserver;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+
 /**
  * Preference controller for "Mobile data"
  */
@@ -60,7 +57,7 @@
         super(context, key);
         mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
         mDataContentObserver = new MobileDataContentObserver(new Handler(Looper.getMainLooper()));
-        mDataContentObserver.setOnMobileDataChangedListener(()-> updateState(mPreference));
+        mDataContentObserver.setOnMobileDataChangedListener(() -> updateState(mPreference));
     }
 
     @Override
@@ -144,18 +141,10 @@
         final int defaultSubId = mSubscriptionManager.getDefaultDataSubscriptionId();
         final boolean needToDisableOthers = mSubscriptionManager
                 .isActiveSubscriptionId(defaultSubId) && defaultSubId != mSubId;
-        if (enableData) {
-            if (isMultiSim && needToDisableOthers) {
-                mDialogType = MobileDataDialogFragment.TYPE_MULTI_SIM_DIALOG;
-                return true;
-            }
-        } else {
-            if (!isMultiSim) {
-                mDialogType = MobileDataDialogFragment.TYPE_DISABLE_DIALOG;
-                return true;
-            }
+        if (enableData && isMultiSim && needToDisableOthers) {
+            mDialogType = MobileDataDialogFragment.TYPE_MULTI_SIM_DIALOG;
+            return true;
         }
-
         return false;
     }
 
diff --git a/src/com/android/settings/network/telephony/MobileNetworkActivity.java b/src/com/android/settings/network/telephony/MobileNetworkActivity.java
index 47eb66b..b8ed31f 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkActivity.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkActivity.java
@@ -40,6 +40,7 @@
 import com.android.settings.core.FeatureFlags;
 import com.android.settings.core.SettingsBaseActivity;
 import com.android.settings.development.featureflags.FeatureFlagPersistent;
+import com.android.settings.network.SubscriptionUtil;
 
 import com.google.android.material.bottomnavigation.BottomNavigationView;
 
@@ -165,7 +166,7 @@
             final int subId = intent.getIntExtra(Settings.EXTRA_SUB_ID, SUB_ID_NULL);
             if (subId != SUB_ID_NULL) {
                 for (SubscriptionInfo subscription :
-                        mSubscriptionManager.getSelectableSubscriptionInfoList()) {
+                        SubscriptionUtil.getAvailableSubscriptions(this)) {
                     if (subscription.getSubscriptionId() == subId) {
                         return subscription;
                     }
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
index db99258..eb00b9f 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -131,12 +131,13 @@
         super.onAttach(context);
 
         if (FeatureFlagPersistent.isEnabled(getContext(), FeatureFlags.NETWORK_INTERNET_V2)) {
-          use(CallsDefaultSubscriptionController.class).init(getLifecycle());
-          use(SmsDefaultSubscriptionController.class).init(getLifecycle());
-          use(MobileNetworkSwitchController.class).init(getLifecycle(), mSubId);
-          use(CarrierSettingsVersionPreferenceController.class).init(mSubId);
-          use(BillingCyclePreferenceController.class).init(mSubId);
-          use(MmsMessagePreferenceController.class).init(mSubId);
+            use(CallsDefaultSubscriptionController.class).init(getLifecycle());
+            use(SmsDefaultSubscriptionController.class).init(getLifecycle());
+            use(MobileNetworkSwitchController.class).init(getLifecycle(), mSubId);
+            use(CarrierSettingsVersionPreferenceController.class).init(mSubId);
+            use(BillingCyclePreferenceController.class).init(mSubId);
+            use(MmsMessagePreferenceController.class).init(mSubId);
+            use(DisabledSubscriptionController.class).init(getLifecycle(), mSubId);
         }
         use(MobileDataPreferenceController.class).init(getFragmentManager(), mSubId);
         use(RoamingPreferenceController.class).init(getFragmentManager(), mSubId);
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSwitchController.java b/src/com/android/settings/network/telephony/MobileNetworkSwitchController.java
index fd296ec..2037adc 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSwitchController.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSwitchController.java
@@ -94,8 +94,9 @@
             return;
         }
         final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(
-                mSubscriptionManager);
-        if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID || subs.size() < 2) {
+                mContext);
+        if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID ||
+                mSubscriptionManager.isSubscriptionEnabled(mSubId) && subs.size() < 2) {
             mSwitchBar.hide();
             return;
         }
diff --git a/src/com/android/settings/notification/ConfigureNotificationSettings.java b/src/com/android/settings/notification/ConfigureNotificationSettings.java
index 73f6e06..d9d2b9b 100644
--- a/src/com/android/settings/notification/ConfigureNotificationSettings.java
+++ b/src/com/android/settings/notification/ConfigureNotificationSettings.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.notification;
 
+import static com.android.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY;
+
 import android.app.Activity;
 import android.app.Application;
 import android.app.settings.SettingsEnums;
@@ -24,10 +26,13 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.provider.SearchIndexableResource;
+import android.text.TextUtils;
 
 import androidx.annotation.VisibleForTesting;
 import androidx.fragment.app.Fragment;
 import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
 import com.android.settings.RingtonePreference;
@@ -62,10 +67,11 @@
     static final String KEY_NOTIFICATION_ASSISTANT = "notification_assistant";
 
     private static final String KEY_NOTI_DEFAULT_RINGTONE = "notification_default_ringtone";
-
-    private RingtonePreference mRequestPreference;
     private static final int REQUEST_CODE = 200;
     private static final String SELECTED_PREFERENCE_KEY = "selected_preference";
+    private static final String KEY_ADVANCED_CATEGORY = "configure_notifications_advanced";
+
+    private RingtonePreference mRequestPreference;
 
     @Override
     public int getMetricsCategory() {
@@ -119,6 +125,27 @@
     }
 
     @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        final PreferenceScreen screen = getPreferenceScreen();
+        final Bundle arguments = getArguments();
+
+        if (screen == null) {
+            return;
+        }
+        if (arguments != null) {
+            final String highlightKey = arguments.getString(EXTRA_FRAGMENT_ARG_KEY);
+            if (!TextUtils.isEmpty(highlightKey)) {
+                final PreferenceCategory advancedCategory =
+                        screen.findPreference(KEY_ADVANCED_CATEGORY);
+                // Has highlight row - expand everything
+                advancedCategory.setInitialExpandedChildrenCount(Integer.MAX_VALUE);
+                scrollToPreference(advancedCategory);
+            }
+        }
+    }
+
+    @Override
     public boolean onPreferenceTreeClick(Preference preference) {
         if (preference instanceof RingtonePreference) {
             mRequestPreference = (RingtonePreference) preference;
diff --git a/src/com/android/settings/notification/ImportancePreference.java b/src/com/android/settings/notification/ImportancePreference.java
index 5572b12..687782b 100644
--- a/src/com/android/settings/notification/ImportancePreference.java
+++ b/src/com/android/settings/notification/ImportancePreference.java
@@ -91,6 +91,7 @@
     @Override
     public void onBindViewHolder(PreferenceViewHolder holder) {
         super.onBindViewHolder(holder);
+        holder.itemView.setClickable(false);
 
         TextView textView = (TextView) holder.findViewById(R.id.description);
         mSilenceButton = (Button) holder.findViewById(R.id.silence);
diff --git a/src/com/android/settings/notification/NotificationBackend.java b/src/com/android/settings/notification/NotificationBackend.java
index f27f979..def820c 100644
--- a/src/com/android/settings/notification/NotificationBackend.java
+++ b/src/com/android/settings/notification/NotificationBackend.java
@@ -425,10 +425,12 @@
             return StringUtil.formatRelativeTime(
                     context, System.currentTimeMillis() - state.lastSent, true);
         } else {
-            if (state.avgSentWeekly > 0) {
-                return context.getString(R.string.notifications_sent_weekly, state.avgSentWeekly);
+            if (state.avgSentDaily > 0) {
+                return context.getResources().getQuantityString(R.plurals.notifications_sent_daily,
+                        state.avgSentDaily, state.avgSentDaily);
             }
-            return context.getString(R.string.notifications_sent_daily, state.avgSentDaily);
+            return context.getResources().getQuantityString(R.plurals.notifications_sent_weekly,
+                    state.avgSentWeekly, state.avgSentWeekly);
         }
     }
 
diff --git a/src/com/android/settings/panel/PanelSlicesAdapter.java b/src/com/android/settings/panel/PanelSlicesAdapter.java
index dcd878e..0f525cc 100644
--- a/src/com/android/settings/panel/PanelSlicesAdapter.java
+++ b/src/com/android/settings/panel/PanelSlicesAdapter.java
@@ -33,6 +33,7 @@
 
 import com.android.settings.R;
 import com.android.settings.overlay.FeatureFactory;
+
 import com.google.android.setupdesign.DividerItemDecoration;
 
 import java.util.ArrayList;
@@ -128,7 +129,8 @@
                                 .action(0 /* attribution */,
                                         SettingsEnums.ACTION_PANEL_INTERACTION,
                                         mMetricsCategory,
-                                        sliceLiveData.toString() /* log key */,
+                                        sliceLiveData.getValue().getUri().getLastPathSegment()
+                                        /* log key */,
                                         eventInfo.actionType /* value */);
                     })
             );
diff --git a/src/com/android/settings/sim/SimListDialogFragment.java b/src/com/android/settings/sim/SimListDialogFragment.java
index 1802d65..3b78927 100644
--- a/src/com/android/settings/sim/SimListDialogFragment.java
+++ b/src/com/android/settings/sim/SimListDialogFragment.java
@@ -174,7 +174,7 @@
             if (sub == null) {
                 title.setText(R.string.sim_calls_ask_first_prefs_title);
                 summary.setText("");
-                icon.setImageDrawable(mContext.getDrawable(R.drawable.ic_help));
+                icon.setImageDrawable(mContext.getDrawable(R.drawable.ic_feedback_24dp));
                 icon.setImageTintList(
                         Utils.getColorAttr(mContext, android.R.attr.textColorSecondary));
             } else {
diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
index eaf3678..dfb59d1 100644
--- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
@@ -885,13 +885,19 @@
     /**
      * Show QR code to share the network represented by this preference.
      */
-    public void launchWifiDppConfiguratorActivity() {
+    private void launchWifiDppConfiguratorActivity() {
         final Intent intent = WifiDppUtils.getConfiguratorQrCodeGeneratorIntentOrNull(mContext,
                 mWifiManager, mAccessPoint);
 
         if (intent == null) {
             Log.e(TAG, "Launch Wi-Fi DPP QR code generator with a wrong Wi-Fi network!");
         } else {
+            mMetricsFeatureProvider.action(SettingsEnums.PAGE_UNKNOWN,
+                    SettingsEnums.ACTION_SETTINGS_SHARE_WIFI_QR_CODE,
+                    SettingsEnums.SETTINGS_WIFI_DPP_CONFIGURATOR,
+                    /* key */ null,
+                    /* value */ Integer.MIN_VALUE);
+
             mContext.startActivity(intent);
         }
     }
@@ -1103,6 +1109,10 @@
             }
             @Override
             public void onFinish() {
+                if (mFragment == null || mFragment.getActivity() == null) {
+                    Log.d(TAG, "Ignore timeout since activity not exist!");
+                    return;
+                }
                 Log.e(TAG, "Timeout for state:" + mConnectingState);
                 if (mConnectingState == STATE_ENABLE_WIFI) {
                     updateConnectingState(STATE_ENABLE_WIFI_FAILED);
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
index d0322b7..0cd7f09 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
@@ -193,6 +193,13 @@
                         return;
                     }
 
+                    mMetricsFeatureProvider.action(
+                            mMetricsFeatureProvider.getAttribution(getActivity()),
+                            SettingsEnums.ACTION_SETTINGS_ENROLL_WIFI_QR_CODE,
+                            SettingsEnums.SETTINGS_WIFI_DPP_ENROLLEE,
+                            /* key */ null,
+                            /* value */ Integer.MIN_VALUE);
+
                     notifyUserForQrCodeRecognition();
                     break;
 
diff --git a/src/com/android/settings/wifi/slice/ConnectToWifiHandler.java b/src/com/android/settings/wifi/slice/ConnectToWifiHandler.java
index ee15820..f1b0b6f 100644
--- a/src/com/android/settings/wifi/slice/ConnectToWifiHandler.java
+++ b/src/com/android/settings/wifi/slice/ConnectToWifiHandler.java
@@ -43,17 +43,21 @@
                 WifiDialogActivity.KEY_ACCESS_POINT_STATE);
 
         if (network != null) {
+            WifiScanWorker.clearClickedWifi();
             final ConnectivityManager cm = getSystemService(ConnectivityManager.class);
             // start captive portal app to sign in to network
             cm.startCaptivePortalApp(network);
         } else if (accessPointState != null) {
             connect(new AccessPoint(this, accessPointState));
         }
+
         finish();
     }
 
     @VisibleForTesting
     void connect(AccessPoint accessPoint) {
+        WifiScanWorker.saveClickedWifi(accessPoint);
+
         final WifiConnectListener connectListener = new WifiConnectListener(this);
         switch (WifiUtils.getConnectingType(accessPoint)) {
             case WifiUtils.CONNECT_TYPE_OSU_PROVISION:
diff --git a/src/com/android/settings/wifi/slice/WifiScanWorker.java b/src/com/android/settings/wifi/slice/WifiScanWorker.java
index b846228..e438443 100644
--- a/src/com/android/settings/wifi/slice/WifiScanWorker.java
+++ b/src/com/android/settings/wifi/slice/WifiScanWorker.java
@@ -20,6 +20,7 @@
 import static com.android.settings.wifi.slice.WifiSlice.DEFAULT_EXPANDED_ROW_COUNT;
 
 import android.content.Context;
+import android.content.Intent;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
 import android.net.Network;
@@ -27,9 +28,12 @@
 import android.net.NetworkInfo;
 import android.net.NetworkRequest;
 import android.net.Uri;
+import android.net.wifi.WifiInfo;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.UserHandle;
+import android.text.TextUtils;
 import android.util.Log;
 
 import androidx.annotation.VisibleForTesting;
@@ -55,22 +59,21 @@
     CaptivePortalNetworkCallback mCaptivePortalNetworkCallback;
 
     private final Context mContext;
+    private final ConnectivityManager mConnectivityManager;
+    private final WifiTracker mWifiTracker;
 
-    private WifiTracker mWifiTracker;
-    private ConnectivityManager mConnectivityManager;
+    private static String sClickedWifiSsid;
 
     public WifiScanWorker(Context context, Uri uri) {
         super(context, uri);
         mContext = context;
         mConnectivityManager = context.getSystemService(ConnectivityManager.class);
+        mWifiTracker = new WifiTracker(mContext, this /* wifiListener */,
+                true /* includeSaved */, true /* includeScans */);
     }
 
     @Override
     protected void onSlicePinned() {
-        if (mWifiTracker == null) {
-            mWifiTracker = new WifiTracker(mContext, this /* wifiListener */,
-                    true /* includeSaved */, true /* includeScans */);
-        }
         mWifiTracker.onStart();
         onAccessPointsChanged();
     }
@@ -79,6 +82,7 @@
     protected void onSliceUnpinned() {
         mWifiTracker.onStop();
         unregisterCaptivePortalNetworkCallback();
+        clearClickedWifi();
     }
 
     @Override
@@ -146,6 +150,19 @@
         return null;
     }
 
+    static void saveClickedWifi(AccessPoint accessPoint) {
+        sClickedWifiSsid = accessPoint.getSsidStr();
+    }
+
+    static void clearClickedWifi() {
+        sClickedWifiSsid = null;
+    }
+
+    static boolean isWifiClicked(WifiInfo info) {
+        final String ssid = WifiInfo.removeDoubleQuotes(info.getSSID());
+        return !TextUtils.isEmpty(ssid) && TextUtils.equals(ssid, sClickedWifiSsid);
+    }
+
     public void registerCaptivePortalNetworkCallback(Network wifiNetwork) {
         if (wifiNetwork == null) {
             return;
@@ -191,7 +208,7 @@
         @Override
         public void onCapabilitiesChanged(Network network,
                 NetworkCapabilities networkCapabilities) {
-            if (!mNetwork.equals(network)) {
+            if (!isSameNetwork(network)) {
                 return;
             }
 
@@ -202,6 +219,19 @@
 
             mIsCaptivePortal = isCaptivePortal;
             notifySliceChange();
+
+            // Automatically start captive portal
+            if (mIsCaptivePortal) {
+                if (!isWifiClicked(mWifiTracker.getManager().getConnectionInfo())) {
+                    return;
+                }
+
+                final Intent intent = new Intent(mContext, ConnectToWifiHandler.class)
+                        .putExtra(ConnectivityManager.EXTRA_NETWORK, network)
+                        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                // Starting activity in the system process needs to specify a user
+                mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+            }
         }
 
         /**
diff --git a/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java b/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java
index b7ddcae..1197db4 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.wifi.tether;
 
+import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.Intent;
 import android.net.wifi.WifiConfiguration;
@@ -27,9 +28,12 @@
 import androidx.preference.Preference;
 
 import com.android.settings.R;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.widget.ValidatedEditTextPreference;
 import com.android.settings.wifi.dpp.WifiDppUtils;
 
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+
 public class WifiTetherSSIDPreferenceController extends WifiTetherBasePreferenceController
         implements ValidatedEditTextPreference.Validator {
 
@@ -41,10 +45,14 @@
     private String mSSID;
     private WifiDeviceNameTextValidator mWifiDeviceNameTextValidator;
 
+    private final MetricsFeatureProvider mMetricsFeatureProvider;
+
     public WifiTetherSSIDPreferenceController(Context context,
             OnTetherConfigUpdateListener listener) {
         super(context, listener);
+
         mWifiDeviceNameTextValidator = new WifiDeviceNameTextValidator();
+        mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
     }
 
     @Override
@@ -104,7 +112,15 @@
     }
 
     private void shareHotspotNetwork(Intent intent) {
-        WifiDppUtils.showLockScreen(mContext, () -> mContext.startActivity(intent));
+        WifiDppUtils.showLockScreen(mContext, () -> {
+            mMetricsFeatureProvider.action(SettingsEnums.PAGE_UNKNOWN,
+                    SettingsEnums.ACTION_SETTINGS_SHARE_WIFI_HOTSPOT_QR_CODE,
+                    SettingsEnums.SETTINGS_WIFI_DPP_CONFIGURATOR,
+                    /* key */ null,
+                    /* value */ Integer.MIN_VALUE);
+
+            mContext.startActivity(intent);
+        });
     }
 
     @VisibleForTesting
diff --git a/tests/robotests/res/values/overlayable_icons_test.xml b/tests/robotests/res/values/overlayable_icons_test.xml
new file mode 100644
index 0000000..575f798
--- /dev/null
+++ b/tests/robotests/res/values/overlayable_icons_test.xml
@@ -0,0 +1,88 @@
+<!--
+   Copyright (C) 2019 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.
+-->
+<resources>
+  <!-- overlayable_icons references all of the drawables in this package
+       that are being overlayed by resource overlays. If you remove/rename
+       any of these resources, you must also change the resource overlay icons.-->
+  <array name="overlayable_icons">
+    <item>@drawable/drag_handle</item>
+    <item>@drawable/ic_add_24dp</item>
+    <item>@drawable/ic_airplanemode_active</item>
+    <item>@drawable/ic_android</item>
+    <item>@drawable/ic_apps</item>
+    <item>@drawable/ic_arrow_back</item>
+    <item>@drawable/ic_battery_charging_full</item>
+    <item>@drawable/ic_battery_saver_accent_24dp</item>
+    <item>@drawable/ic_battery_status_bad_24dp</item>
+    <item>@drawable/ic_battery_status_good_24dp</item>
+    <item>@drawable/ic_battery_status_maybe_24dp</item>
+    <item>@drawable/ic_call_24dp</item>
+    <item>@drawable/ic_cancel</item>
+    <item>@drawable/ic_cast_24dp</item>
+    <item>@drawable/ic_cellular_off</item>
+    <item>@drawable/ic_content_copy_grey600_24dp</item>
+    <item>@drawable/ic_data_saver</item>
+    <item>@drawable/ic_delete</item>
+    <item>@drawable/ic_delete_accent</item>
+    <item>@drawable/ic_devices_other</item>
+    <item>@drawable/ic_devices_other_opaque_black</item>
+    <item>@drawable/ic_do_not_disturb_on_24dp</item>
+    <item>@drawable/ic_eject_24dp</item>
+    <item>@drawable/ic_expand_less</item>
+    <item>@drawable/ic_expand_more_inverse</item>
+    <item>@drawable/ic_folder_vd_theme_24</item>
+    <item>@drawable/ic_friction_lock_closed</item>
+    <item>@drawable/ic_gray_scale_24dp</item>
+    <item>@drawable/ic_headset_24dp</item>
+    <item>@drawable/ic_help</item>
+    <item>@drawable/ic_homepage_search</item>
+    <item>@drawable/ic_local_movies</item>
+    <item>@drawable/ic_local_phone_24_lib</item>
+    <item>@drawable/ic_lock</item>
+    <item>@drawable/ic_media_stream</item>
+    <item>@drawable/ic_media_stream_off</item>
+    <item>@drawable/ic_network_cell</item>
+    <item>@drawable/ic_notifications</item>
+    <item>@drawable/ic_notifications_off_24dp</item>
+    <item>@drawable/ic_phone_info</item>
+    <item>@drawable/ic_photo_library</item>
+    <item>@drawable/ic_settings_accessibility</item>
+    <item>@drawable/ic_settings_accounts</item>
+    <item>@drawable/ic_settings_battery_white</item>
+    <item>@drawable/ic_settings_data_usage</item>
+    <item>@drawable/ic_settings_date_time</item>
+    <item>@drawable/ic_settings_delete</item>
+    <item>@drawable/ic_settings_display_white</item>
+    <item>@drawable/ic_settings_home</item>
+    <item>@drawable/ic_settings_location</item>
+    <item>@drawable/ic_settings_night_display</item>
+    <item>@drawable/ic_settings_open</item>
+    <item>@drawable/ic_settings_print</item>
+    <item>@drawable/ic_settings_privacy</item>
+    <item>@drawable/ic_settings_security_white</item>
+    <item>@drawable/ic_settings_sim</item>
+    <item>@drawable/ic_settings_system_dashboard_white</item>
+    <item>@drawable/ic_settings_wireless</item>
+    <item>@drawable/ic_settings_wireless_white</item>
+    <item>@drawable/ic_storage_white</item>
+    <item>@drawable/ic_suggestion_night_display</item>
+    <item>@drawable/ic_videogame_vd_theme_24</item>
+    <item>@drawable/ic_volume_ringer_vibrate</item>
+    <item>@drawable/ic_volume_up_24dp</item>
+    <item>@drawable/ic_vpn_key</item>
+    <item>@drawable/ic_wifi_tethering</item>
+  </array>
+</resources>
diff --git a/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java
index cf4cb7c..d98d30a 100644
--- a/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java
@@ -144,7 +144,7 @@
     }
 
     @Test
-    public void onClick_shouldNotStartConfirmDialogWhenModifyAccountsIsDisallowed() {
+    public void onClick_modifyAccountsIsDisallowed_shouldNotStartConfirmDialog() {
         when(mFragment.isAdded()).thenReturn(true);
 
         final int userId = UserHandle.myUserId();
@@ -195,7 +195,41 @@
         Bundle resultBundle = new Bundle();
         resultBundle.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
         when(future.getResult()).thenReturn(resultBundle);
+
         callback.run(future);
         verify(activity).finish();
     }
+
+    @Test
+    @Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class})
+    public void confirmRemove_activityGone_shouldSilentlyRemoveAccount()
+            throws AuthenticatorException, OperationCanceledException, IOException {
+        final Account account = new Account("Account11", "com.acct1");
+        final UserHandle userHandle = new UserHandle(10);
+        final FragmentActivity activity = mock(FragmentActivity.class);
+        when(mFragment.isAdded()).thenReturn(true);
+        when(activity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
+        when(mFragment.getActivity()).thenReturn(activity).thenReturn(null);
+
+        final RemoveAccountPreferenceController.ConfirmRemoveAccountDialog dialog =
+                RemoveAccountPreferenceController.ConfirmRemoveAccountDialog.show(
+                        mFragment, account, userHandle);
+        dialog.onCreate(new Bundle());
+        dialog.onClick(null, 0);
+
+        ArgumentCaptor<AccountManagerCallback<Bundle>> callbackCaptor = ArgumentCaptor.forClass(
+                AccountManagerCallback.class);
+        verify(mAccountManager).removeAccountAsUser(eq(account), nullable(Activity.class),
+                callbackCaptor.capture(), nullable(Handler.class), eq(userHandle));
+
+        AccountManagerCallback<Bundle> callback = callbackCaptor.getValue();
+        assertThat(callback).isNotNull();
+        AccountManagerFuture<Bundle> future = mock(AccountManagerFuture.class);
+        Bundle resultBundle = new Bundle();
+        resultBundle.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
+        when(future.getResult()).thenReturn(resultBundle);
+
+        callback.run(future);
+        verify(activity, never()).finish();
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/applications/AppStateNotificationBridgeTest.java b/tests/robotests/src/com/android/settings/applications/AppStateNotificationBridgeTest.java
index 10f3706..24cb10d 100644
--- a/tests/robotests/src/com/android/settings/applications/AppStateNotificationBridgeTest.java
+++ b/tests/robotests/src/com/android/settings/applications/AppStateNotificationBridgeTest.java
@@ -398,8 +398,20 @@
                 mContext, sentRarely, R.id.sort_order_frequent_notification).toString())
                 .contains("1");
         assertThat(AppStateNotificationBridge.getSummary(
+                mContext, sentRarely, R.id.sort_order_frequent_notification).toString())
+                .contains("notification ");
+        assertThat(AppStateNotificationBridge.getSummary(
+                mContext, sentRarely, R.id.sort_order_frequent_notification).toString())
+                .contains("week");
+        assertThat(AppStateNotificationBridge.getSummary(
                 mContext, sentOften, R.id.sort_order_frequent_notification).toString())
                 .contains("8");
+        assertThat(AppStateNotificationBridge.getSummary(
+                mContext, sentOften, R.id.sort_order_frequent_notification).toString())
+                .contains("notifications");
+        assertThat(AppStateNotificationBridge.getSummary(
+                mContext, sentOften, R.id.sort_order_frequent_notification).toString())
+                .contains("day");
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceGroupControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceGroupControllerTest.java
index 23754a0..946d639 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceGroupControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceGroupControllerTest.java
@@ -88,6 +88,7 @@
         mPreferenceGroup = spy(new PreferenceScreen(mContext, null));
         when(mPreferenceGroup.getPreferenceManager()).thenReturn(mPreferenceManager);
         doReturn(mContext).when(mDashboardFragment).getContext();
+        mPackageManager.setSystemFeature(PackageManager.FEATURE_BLUETOOTH, true);
 
         mConnectedDeviceGroupController = new ConnectedDeviceGroupController(mContext);
         mConnectedDeviceGroupController.init(mConnectedBluetoothDeviceUpdater,
@@ -153,8 +154,12 @@
     }
 
     @Test
-    public void getAvailabilityStatus_noBluetoothFeature_returnUnSupported() {
+    public void getAvailabilityStatus_noBluetoothUsbDockFeature_returnUnSupported() {
         mPackageManager.setSystemFeature(PackageManager.FEATURE_BLUETOOTH, false);
+        mPackageManager.setSystemFeature(PackageManager.FEATURE_USB_ACCESSORY, false);
+        mPackageManager.setSystemFeature(PackageManager.FEATURE_USB_HOST, false);
+        mConnectedDeviceGroupController.init(mConnectedBluetoothDeviceUpdater,
+                mConnectedUsbDeviceUpdater, null);
 
         assertThat(mConnectedDeviceGroupController.getAvailabilityStatus()).isEqualTo(
                 UNSUPPORTED_ON_DEVICE);
@@ -163,8 +168,37 @@
     @Test
     public void getAvailabilityStatus_BluetoothFeature_returnSupported() {
         mPackageManager.setSystemFeature(PackageManager.FEATURE_BLUETOOTH, true);
+        mPackageManager.setSystemFeature(PackageManager.FEATURE_USB_ACCESSORY, false);
+        mPackageManager.setSystemFeature(PackageManager.FEATURE_USB_HOST, false);
+        mConnectedDeviceGroupController.init(mConnectedBluetoothDeviceUpdater,
+                mConnectedUsbDeviceUpdater, null);
 
         assertThat(mConnectedDeviceGroupController.getAvailabilityStatus()).isEqualTo(
                 AVAILABLE_UNSEARCHABLE);
     }
+
+    @Test
+    public void getAvailabilityStatus_haveUsbFeature_returnSupported() {
+        mPackageManager.setSystemFeature(PackageManager.FEATURE_BLUETOOTH, false);
+        mPackageManager.setSystemFeature(PackageManager.FEATURE_USB_ACCESSORY, false);
+        mPackageManager.setSystemFeature(PackageManager.FEATURE_USB_HOST, true);
+        mConnectedDeviceGroupController.init(mConnectedBluetoothDeviceUpdater,
+                mConnectedUsbDeviceUpdater, null);
+
+        assertThat(mConnectedDeviceGroupController.getAvailabilityStatus()).isEqualTo(
+                AVAILABLE_UNSEARCHABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_haveDockFeature_returnSupported() {
+        mPackageManager.setSystemFeature(PackageManager.FEATURE_BLUETOOTH, false);
+        mPackageManager.setSystemFeature(PackageManager.FEATURE_USB_ACCESSORY, false);
+        mPackageManager.setSystemFeature(PackageManager.FEATURE_USB_HOST, false);
+        mConnectedDeviceGroupController.init(mConnectedBluetoothDeviceUpdater,
+                mConnectedUsbDeviceUpdater, mConnectedDockUpdater);
+
+        assertThat(mConnectedDeviceGroupController.getAvailabilityStatus()).isEqualTo(
+                AVAILABLE_UNSEARCHABLE);
+    }
+
 }
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java
index 48f734d..90cbea9 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java
@@ -95,19 +95,32 @@
     }
 
     @Test
-    public void getAvailabilityStatus_noBluetoothFeature_returnUnSupported() {
+    public void getAvailabilityStatus_noBluetoothDockFeature_returnUnSupported() {
         doReturn(false).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
+        mPreConnectedDeviceController.setSavedDockUpdater(null);
+
         assertThat(mPreConnectedDeviceController.getAvailabilityStatus()).isEqualTo(
                 CONDITIONALLY_UNAVAILABLE);
     }
+
     @Test
     public void getAvailabilityStatus_hasBluetoothFeature_returnSupported() {
         doReturn(true).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
+        mPreConnectedDeviceController.setSavedDockUpdater(null);
+
         assertThat(mPreConnectedDeviceController.getAvailabilityStatus()).isEqualTo(
                 AVAILABLE);
     }
 
     @Test
+    public void getAvailabilityStatus_haveDockFeature_returnSupported() {
+        doReturn(false).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
+
+        assertThat(mPreConnectedDeviceController.getAvailabilityStatus()).isEqualTo(
+            AVAILABLE);
+    }
+
+    @Test
     public void onDeviceAdded_addDevicePreference_displayIt() {
         mPreConnectedDeviceController.onDeviceAdded(new Preference(mContext));
 
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/SavedDeviceGroupControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/SavedDeviceGroupControllerTest.java
index c386719..6c6cf47 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/SavedDeviceGroupControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/SavedDeviceGroupControllerTest.java
@@ -23,6 +23,7 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -81,6 +82,7 @@
         verify(mBluetoothDeviceUpdater).registerCallback();
         verify(mSavedDockUpdater).registerCallback();
     }
+
     @Test
     public void testUnregister() {
         // unregister the callback in onStop()
@@ -88,16 +90,30 @@
         verify(mBluetoothDeviceUpdater).unregisterCallback();
         verify(mSavedDockUpdater).unregisterCallback();
     }
+
     @Test
-    public void testGetAvailabilityStatus_noBluetoothFeature_returnUnSupported() {
+    public void testGetAvailabilityStatus_noBluetoothDockFeature_returnUnSupported() {
         doReturn(false).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
+        mSavedDeviceGroupController.setSavedDockUpdater(null);
+
         assertThat(mSavedDeviceGroupController.getAvailabilityStatus()).isEqualTo(
                 UNSUPPORTED_ON_DEVICE);
     }
+
     @Test
     public void testGetAvailabilityStatus_BluetoothFeature_returnSupported() {
         doReturn(true).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
+        mSavedDeviceGroupController.setSavedDockUpdater(null);
+
         assertThat(mSavedDeviceGroupController.getAvailabilityStatus()).isEqualTo(
                 AVAILABLE);
     }
+
+    @Test
+    public void getAvailabilityStatus_haveDockFeature_returnSupported() {
+        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)).thenReturn(false);
+
+        assertThat(mSavedDeviceGroupController.getAvailabilityStatus()).isEqualTo(
+            AVAILABLE);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/display/AutoBrightnessDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AutoBrightnessDetailPreferenceControllerTest.java
new file mode 100644
index 0000000..e76cff6
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/display/AutoBrightnessDetailPreferenceControllerTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2019 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.display;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.android.settings.testutils.shadow.SettingsShadowResources;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {SettingsShadowResources.class})
+public class AutoBrightnessDetailPreferenceControllerTest {
+
+    private AutoBrightnessDetailPreferenceController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mController = new AutoBrightnessDetailPreferenceController(
+                RuntimeEnvironment.application, "test_key");
+    }
+
+    @Test
+    public void isSliceable_returnTrue() {
+        mController.onPreferenceChange(null, true);
+
+        assertThat(mController.isSliceable()).isTrue();
+    }
+
+    @Test
+    public void getAvailabilityStatus_configTrueSet_shouldReturnAvailable() {
+        SettingsShadowResources.overrideResource(
+                com.android.internal.R.bool.config_automatic_brightness_available, true);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_configFalseSet_shouldReturnUnsupportedOnDevice() {
+        SettingsShadowResources.overrideResource(
+                com.android.internal.R.bool.config_automatic_brightness_available, false);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java
index a8edc44..0229173 100644
--- a/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java
@@ -20,6 +20,9 @@
 import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
 import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
 
+import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import android.content.ContentResolver;
@@ -27,6 +30,7 @@
 import android.provider.Settings;
 
 import com.android.settings.R;
+import com.android.settings.testutils.shadow.SettingsShadowResources;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -34,8 +38,10 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
 
 @RunWith(RobolectricTestRunner.class)
+@Config(shadows = {SettingsShadowResources.class})
 public class AutoBrightnessPreferenceControllerTest {
 
     private static final String PREFERENCE_KEY = "auto_brightness";
@@ -115,17 +121,18 @@
     }
 
     @Test
-    public void isSliceable_correctKey_returnsTrue() {
-        final AutoBrightnessPreferenceController controller =
-                new AutoBrightnessPreferenceController(mContext,
-                        "auto_brightness");
-        assertThat(controller.isSliceable()).isTrue();
+    public void getAvailabilityStatus_configTrueSet_shouldReturnAvailableUnsearchable() {
+        SettingsShadowResources.overrideResource(
+                com.android.internal.R.bool.config_automatic_brightness_available, true);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
     }
 
     @Test
-    public void isSliceable_incorrectKey_returnsFalse() {
-        final AutoBrightnessPreferenceController controller =
-                new AutoBrightnessPreferenceController(mContext, "bad_key");
-        assertThat(controller.isSliceable()).isFalse();
+    public void getAvailabilityStatus_configFalseSet_shouldReturnUnsupportedOnDevice() {
+        SettingsShadowResources.overrideResource(
+                com.android.internal.R.bool.config_automatic_brightness_available, false);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
     }
 }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java
index f025ee8..c2a3aa9 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java
@@ -16,8 +16,6 @@
 
 package com.android.settings.homepage.contextualcards;
 
-import static android.app.slice.Slice.HINT_ERROR;
-
 import static com.android.settings.homepage.contextualcards.ContextualCardLoader.DEFAULT_CARD_COUNT;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -34,8 +32,6 @@
 import android.content.Context;
 import android.net.Uri;
 
-import androidx.slice.Slice;
-
 import com.android.settings.R;
 import com.android.settings.slices.CustomSliceRegistry;
 import com.android.settings.testutils.FakeFeatureFactory;
@@ -53,74 +49,18 @@
 @RunWith(RobolectricTestRunner.class)
 public class ContextualCardLoaderTest {
 
-    private static final String TEST_SLICE_URI = "content://test/test";
-
     private Context mContext;
     private ContextualCardLoader mContextualCardLoader;
-    private EligibleCardChecker mEligibleCardChecker;
     private FakeFeatureFactory mFakeFeatureFactory;
 
     @Before
     public void setUp() {
         mContext = RuntimeEnvironment.application;
         mContextualCardLoader = spy(new ContextualCardLoader(mContext));
-        mEligibleCardChecker =
-                spy(new EligibleCardChecker(mContext, getContextualCard(TEST_SLICE_URI)));
         mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
     }
 
     @Test
-    public void isCardEligibleToDisplay_customCard_returnTrue() {
-        final ContextualCard customCard = new ContextualCard.Builder()
-                .setName("custom_card")
-                .setCardType(ContextualCard.CardType.DEFAULT)
-                .setTitleText("custom_title")
-                .setSummaryText("custom_summary")
-                .build();
-
-        assertThat(mEligibleCardChecker.isCardEligibleToDisplay(customCard)).isTrue();
-    }
-
-    @Test
-    public void isCardEligibleToDisplay_invalidScheme_returnFalse() {
-        final String sliceUri = "contet://com.android.settings.slices/action/flashlight";
-
-        assertThat(mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(sliceUri)))
-                .isFalse();
-    }
-
-    @Test
-    public void isCardEligibleToDisplay_invalidRankingScore_returnFalse() {
-        final ContextualCard card = new ContextualCard.Builder()
-                .setName("test_card")
-                .setCardType(ContextualCard.CardType.SLICE)
-                .setSliceUri(CustomSliceRegistry.FLASHLIGHT_SLICE_URI)
-                .setRankingScore(-1)
-                .build();
-
-        assertThat(mEligibleCardChecker.isCardEligibleToDisplay(card))
-                .isFalse();
-    }
-
-    @Test
-    public void isCardEligibleToDisplay_nullSlice_returnFalse() {
-        doReturn(null).when(mEligibleCardChecker).bindSlice(Uri.parse(TEST_SLICE_URI));
-
-        assertThat(mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(TEST_SLICE_URI)))
-                .isFalse();
-    }
-
-    @Test
-    public void isCardEligibleToDisplay_errorSlice_returnFalse() {
-        final Slice slice = new Slice.Builder(Uri.parse(TEST_SLICE_URI))
-                .addHints(HINT_ERROR).build();
-        doReturn(slice).when(mEligibleCardChecker).bindSlice(Uri.parse(TEST_SLICE_URI));
-
-        assertThat(mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(TEST_SLICE_URI)))
-                .isFalse();
-    }
-
-    @Test
     public void getDisplayableCards_twoEligibleCards_shouldShowAll() {
         final List<ContextualCard> cards = getContextualCardList().stream().limit(2)
                 .collect(Collectors.toList());
@@ -201,15 +141,6 @@
                 eq(SettingsEnums.ACTION_CONTEXTUAL_CARD_SHOW), any(String.class));
     }
 
-    private ContextualCard getContextualCard(String sliceUri) {
-        return new ContextualCard.Builder()
-                .setName("test_card")
-                .setRankingScore(0.5)
-                .setCardType(ContextualCard.CardType.SLICE)
-                .setSliceUri(Uri.parse(sliceUri))
-                .build();
-    }
-
     private List<ContextualCard> getContextualCardList() {
         final List<ContextualCard> cards = new ArrayList<>();
         cards.add(new ContextualCard.Builder()
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardsDiffCallbackTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardsDiffCallbackTest.java
new file mode 100644
index 0000000..eb95f71
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardsDiffCallbackTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2019 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.homepage.contextualcards;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.net.Uri;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+public class ContextualCardsDiffCallbackTest {
+
+    private static final Uri TEST_SLICE_URI = Uri.parse("content://test/test");
+
+    private ContextualCardsDiffCallback mDiffCallback;
+    private List<ContextualCard> mOldCards;
+    private List<ContextualCard> mNewCards;
+
+    @Before
+    public void setUp() {
+        mOldCards = new ArrayList<>();
+        mNewCards = new ArrayList<>();
+        mOldCards.add(getContextualCard("test1"));
+        mNewCards.add(getContextualCard("test1"));
+        mNewCards.add(getContextualCard("test2"));
+        mDiffCallback = new ContextualCardsDiffCallback(mOldCards, mNewCards);
+    }
+
+    @Test
+    public void getOldListSize_oneCard_returnOne() {
+        assertThat(mDiffCallback.getOldListSize()).isEqualTo(1);
+    }
+
+    @Test
+    public void getNewListSize_twoCards_returnTwo() {
+        assertThat(mDiffCallback.getNewListSize()).isEqualTo(2);
+    }
+
+    @Test
+    public void areItemsTheSame_sameItems_returnTrue() {
+        assertThat(mDiffCallback.areItemsTheSame(0, 0)).isTrue();
+    }
+
+    @Test
+    public void areItemsTheSame_differentItems_returnFalse() {
+        mOldCards.add(getContextualCard("test3"));
+
+        assertThat(mDiffCallback.areItemsTheSame(1, 1)).isFalse();
+    }
+
+    @Test
+    public void areContentsTheSame_sameContents_returnTrue() {
+        assertThat(mDiffCallback.areContentsTheSame(0, 0)).isTrue();
+    }
+
+    @Test
+    public void areContentsTheSame_sliceWithToggle_returnFalse() {
+        final ContextualCard card = getContextualCard("test1").mutate()
+                .setHasInlineAction(true).build();
+        mNewCards.add(0, card);
+
+        assertThat(mDiffCallback.areContentsTheSame(0, 0)).isFalse();
+    }
+
+    private ContextualCard getContextualCard(String name) {
+        return new ContextualCard.Builder()
+                .setName(name)
+                .setRankingScore(0.5)
+                .setCardType(ContextualCard.CardType.SLICE)
+                .setSliceUri(TEST_SLICE_URI)
+                .build();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java
new file mode 100644
index 0000000..7b70dad
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2019 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.homepage.contextualcards;
+
+import static android.app.slice.Slice.HINT_ERROR;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.net.Uri;
+
+import androidx.slice.Slice;
+import androidx.slice.SliceProvider;
+import androidx.slice.widget.SliceLiveData;
+
+import com.android.settings.homepage.contextualcards.deviceinfo.EmergencyInfoSlice;
+import com.android.settings.slices.CustomSliceRegistry;
+import com.android.settings.wifi.slice.ContextualWifiSlice;
+
+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 EligibleCardCheckerTest {
+
+    private static final Uri TEST_SLICE_URI = Uri.parse("content://test/test");
+
+    private Context mContext;
+    private EligibleCardChecker mEligibleCardChecker;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mEligibleCardChecker =
+                spy(new EligibleCardChecker(mContext, getContextualCard(TEST_SLICE_URI)));
+        SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
+    }
+
+    @Test
+    public void isSliceToggleable_cardWithToggle_returnTrue() {
+        final ContextualWifiSlice wifiSlice = new ContextualWifiSlice(mContext);
+        final Slice slice = wifiSlice.getSlice();
+
+        assertThat(mEligibleCardChecker.isSliceToggleable(slice)).isTrue();
+    }
+
+    @Test
+    public void isSliceToggleable_cardWithoutToggle_returnFalse() {
+        final EmergencyInfoSlice emergencyInfoSlice = new EmergencyInfoSlice(mContext);
+        final Slice slice = emergencyInfoSlice.getSlice();
+
+        assertThat(mEligibleCardChecker.isSliceToggleable(slice)).isFalse();
+    }
+
+    @Test
+    public void isCardEligibleToDisplay_toggleSlice_hasInlineActionShouldBeTrue() {
+        final ContextualWifiSlice wifiSlice = new ContextualWifiSlice(mContext);
+        final Slice slice = wifiSlice.getSlice();
+        doReturn(slice).when(mEligibleCardChecker).bindSlice(any(Uri.class));
+
+        mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(TEST_SLICE_URI));
+
+        assertThat(mEligibleCardChecker.mCard.hasInlineAction()).isTrue();
+    }
+
+    @Test
+    public void isCardEligibleToDisplay_notToggleSlice_hasInlineActionShouldBeFalse() {
+        final EmergencyInfoSlice emergencyInfoSlice = new EmergencyInfoSlice(mContext);
+        final Slice slice = emergencyInfoSlice.getSlice();
+        doReturn(slice).when(mEligibleCardChecker).bindSlice(any(Uri.class));
+
+        mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(TEST_SLICE_URI));
+
+        assertThat(mEligibleCardChecker.mCard.hasInlineAction()).isFalse();
+    }
+
+    @Test
+    public void isCardEligibleToDisplay_customCard_returnTrue() {
+        final ContextualCard customCard = new ContextualCard.Builder()
+                .setName("custom_card")
+                .setCardType(ContextualCard.CardType.DEFAULT)
+                .setTitleText("custom_title")
+                .setSummaryText("custom_summary")
+                .build();
+
+        assertThat(mEligibleCardChecker.isCardEligibleToDisplay(customCard)).isTrue();
+    }
+
+    @Test
+    public void isCardEligibleToDisplay_invalidScheme_returnFalse() {
+        final Uri sliceUri = Uri.parse("contet://com.android.settings.slices/action/flashlight");
+
+        assertThat(mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(sliceUri)))
+                .isFalse();
+    }
+
+    @Test
+    public void isCardEligibleToDisplay_invalidRankingScore_returnFalse() {
+        final ContextualCard card = new ContextualCard.Builder()
+                .setName("test_card")
+                .setCardType(ContextualCard.CardType.SLICE)
+                .setSliceUri(CustomSliceRegistry.FLASHLIGHT_SLICE_URI)
+                .setRankingScore(-1)
+                .build();
+
+        assertThat(mEligibleCardChecker.isCardEligibleToDisplay(card))
+                .isFalse();
+    }
+
+    @Test
+    public void isCardEligibleToDisplay_nullSlice_returnFalse() {
+        doReturn(null).when(mEligibleCardChecker).bindSlice(any(Uri.class));
+
+        assertThat(mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(TEST_SLICE_URI)))
+                .isFalse();
+    }
+
+    @Test
+    public void isCardEligibleToDisplay_errorSlice_returnFalse() {
+        final Slice slice = new Slice.Builder(TEST_SLICE_URI)
+                .addHints(HINT_ERROR).build();
+        doReturn(slice).when(mEligibleCardChecker).bindSlice(any(Uri.class));
+
+        assertThat(mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(TEST_SLICE_URI)))
+                .isFalse();
+    }
+
+    private ContextualCard getContextualCard(Uri sliceUri) {
+        return new ContextualCard.Builder()
+                .setName("test_card")
+                .setRankingScore(0.5)
+                .setCardType(ContextualCard.CardType.SLICE)
+                .setSliceUri(sliceUri)
+                .build();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSliceTest.java
index 81f5797..6c020f8 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSliceTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSliceTest.java
@@ -151,7 +151,8 @@
         for (int i = 0; i < rowItems.size(); i++) {
             // Assert the summary text is the same as expectation.
             assertThat(getSummaryFromSliceItem(rowItems.get(i))).isEqualTo(
-                    mContext.getString(R.string.notifications_sent_weekly, CHANNEL_COUNT - i));
+                    mContext.getResources().getQuantityString(R.plurals.notifications_sent_weekly,
+                            CHANNEL_COUNT - i, CHANNEL_COUNT - i));
         }
     }
 
diff --git a/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
index b8ba63c..a623850 100644
--- a/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
@@ -34,6 +34,7 @@
 import android.os.UserManager;
 import android.provider.Settings;
 import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.euicc.EuiccManager;
 import android.text.TextUtils;
@@ -151,8 +152,11 @@
         mPreference.getOnPreferenceClickListener().onPreferenceClick(mPreference);
         final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
         verify(mContext).startActivity(intentCaptor.capture());
-        assertThat(intentCaptor.getValue().getComponent().getClassName()).isEqualTo(
+        Intent intent = intentCaptor.getValue();
+        assertThat(intent.getComponent().getClassName()).isEqualTo(
                 MobileNetworkActivity.class.getName());
+        assertThat(intent.getIntExtra(Settings.EXTRA_SUB_ID,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID)).isEqualTo(sub1.getSubscriptionId());
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/network/SubscriptionUtilTest.java b/tests/robotests/src/com/android/settings/network/SubscriptionUtilTest.java
index c074466..28a390d 100644
--- a/tests/robotests/src/com/android/settings/network/SubscriptionUtilTest.java
+++ b/tests/robotests/src/com/android/settings/network/SubscriptionUtilTest.java
@@ -16,14 +16,21 @@
 
 package com.android.settings.network;
 
+import static android.telephony.UiccSlotInfo.CARD_STATE_INFO_ABSENT;
+import static android.telephony.UiccSlotInfo.CARD_STATE_INFO_PRESENT;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import android.content.Context;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.telephony.UiccSlotInfo;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -39,17 +46,25 @@
 @RunWith(RobolectricTestRunner.class)
 public class SubscriptionUtilTest {
     @Mock
-    private SubscriptionManager mManager;
+    private Context mContext;
+    @Mock
+    private SubscriptionManager mSubMgr;
+    @Mock
+    private TelephonyManager mTelMgr;
+
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        doReturn(mSubMgr).when(mContext).getSystemService(SubscriptionManager.class);
+        doReturn(mTelMgr).when(mContext).getSystemService(TelephonyManager.class);
+        when(mTelMgr.getUiccSlotsInfo()).thenReturn(null);
     }
 
     @Test
     public void getAvailableSubscriptions_nullInfoFromSubscriptionManager_nonNullResult() {
-        when(mManager.getSelectableSubscriptionInfoList()).thenReturn(null);
-        final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mManager);
+        when(mSubMgr.getSelectableSubscriptionInfoList()).thenReturn(null);
+        final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mContext);
         assertThat(subs).isNotNull();
         assertThat(subs).isEmpty();
     }
@@ -58,8 +73,8 @@
     public void getAvailableSubscriptions_oneSubscription_oneResult() {
         final SubscriptionInfo info = mock(SubscriptionInfo.class);
         when(info.getMncString()).thenReturn("fake1234");
-        when(mManager.getSelectableSubscriptionInfoList()).thenReturn(Arrays.asList(info));
-        final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mManager);
+        when(mSubMgr.getSelectableSubscriptionInfoList()).thenReturn(Arrays.asList(info));
+        final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mContext);
         assertThat(subs).isNotNull();
         assertThat(subs).hasSize(1);
     }
@@ -70,8 +85,8 @@
         final SubscriptionInfo info2 = mock(SubscriptionInfo.class);
         when(info1.getMncString()).thenReturn("fake1234");
         when(info2.getMncString()).thenReturn("fake5678");
-        when(mManager.getSelectableSubscriptionInfoList()).thenReturn(Arrays.asList(info1, info2));
-        final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mManager);
+        when(mSubMgr.getSelectableSubscriptionInfoList()).thenReturn(Arrays.asList(info1, info2));
+        final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mContext);
         assertThat(subs).isNotNull();
         assertThat(subs).hasSize(2);
     }
@@ -83,9 +98,9 @@
         final SubscriptionInfo info3 = mock(SubscriptionInfo.class);
         when(info1.getSubscriptionId()).thenReturn(1);
         when(info1.getMncString()).thenReturn("fake1234");
-        when(mManager.getSelectableSubscriptionInfoList()).thenReturn(
+        when(mSubMgr.getSelectableSubscriptionInfoList()).thenReturn(
                 new ArrayList<>(Arrays.asList(info1, info2, info3)));
-        final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mManager);
+        final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mContext);
         assertThat(subs).isNotNull();
         assertThat(subs).hasSize(1);
         assertThat(subs.get(0).getSubscriptionId()).isEqualTo(1);
@@ -101,9 +116,9 @@
         when(info1.getMncString()).thenReturn("fake1234");
         when(info4.getSubscriptionId()).thenReturn(4);
         when(info4.getMncString()).thenReturn("fake5678");
-        when(mManager.getSelectableSubscriptionInfoList()).thenReturn(new ArrayList<>(
+        when(mSubMgr.getSelectableSubscriptionInfoList()).thenReturn(new ArrayList<>(
                 Arrays.asList(info1, info2, info3, info4)));
-        final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mManager);
+        final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mContext);
         assertThat(subs).isNotNull();
         assertThat(subs).hasSize(2);
         assertThat(subs.get(0).getSubscriptionId()).isEqualTo(1);
@@ -111,9 +126,86 @@
     }
 
     @Test
+    public void getAvailableSubscriptions_oneSelectableOneDisabledPSim_twoResults() {
+        final SubscriptionInfo info1 = mock(SubscriptionInfo.class);
+        final SubscriptionInfo info2 = mock(SubscriptionInfo.class);
+
+        when(info1.getSubscriptionId()).thenReturn(111);
+        when(info1.getMncString()).thenReturn("fake111");
+        when(info1.getSimSlotIndex()).thenReturn(-1);
+        when(info1.getCardString()).thenReturn("info1_cardid");
+
+        when(info2.getSubscriptionId()).thenReturn(222);
+        when(info2.getMncString()).thenReturn("fake222");
+        when(info2.getSimSlotIndex()).thenReturn(0);
+        when(info2.getCardString()).thenReturn("info2_cardid");
+
+        when(mSubMgr.getSelectableSubscriptionInfoList()).thenReturn(Arrays.asList(info1));
+        when(mSubMgr.getAllSubscriptionInfoList()).thenReturn(Arrays.asList(info1, info2));
+
+        final UiccSlotInfo info2slot = mock(UiccSlotInfo.class);
+        when(info2slot.getCardStateInfo()).thenReturn(CARD_STATE_INFO_PRESENT);
+        when(info2slot.getLogicalSlotIdx()).thenReturn(0);
+        when(info2slot.getCardId()).thenReturn("info2_cardid");
+
+        final UiccSlotInfo[] slotInfos = {info2slot};
+        when(mTelMgr.getUiccSlotsInfo()).thenReturn(slotInfos);
+
+        final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mContext);
+        assertThat(subs).hasSize(2);
+        assertThat(subs.get(0).getSubscriptionId()).isEqualTo(111);
+        assertThat(subs.get(1).getSubscriptionId()).isEqualTo(222);
+    }
+
+
+    @Test
+    public void getAvailableSubscriptions_oneSelectableTwoDisabledPSimsOneAbsent_twoResults() {
+        final SubscriptionInfo info1 = mock(SubscriptionInfo.class);
+        final SubscriptionInfo info2 = mock(SubscriptionInfo.class);
+        final SubscriptionInfo info3 = mock(SubscriptionInfo.class);
+
+        when(info1.getSubscriptionId()).thenReturn(111);
+        when(info1.getMncString()).thenReturn("fake111");
+        when(info1.getSimSlotIndex()).thenReturn(-1);
+        when(info1.getCardString()).thenReturn("info1_cardid");
+
+        when(info2.getSubscriptionId()).thenReturn(222);
+        when(info2.getMncString()).thenReturn("fake222");
+        when(info2.getSimSlotIndex()).thenReturn(-1);
+        when(info2.getCardString()).thenReturn("info2_cardid");
+
+        when(info3.getSubscriptionId()).thenReturn(333);
+        when(info3.getMncString()).thenReturn("fake333");
+        when(info3.getSimSlotIndex()).thenReturn(0);
+        when(info3.getCardString()).thenReturn("info3_cardid");
+
+        when(mSubMgr.getSelectableSubscriptionInfoList()).thenReturn(Arrays.asList(info1));
+        when(mSubMgr.getAllSubscriptionInfoList()).thenReturn(Arrays.asList(info1, info2, info3));
+
+        final UiccSlotInfo info2slot = mock(UiccSlotInfo.class);
+        final UiccSlotInfo info3slot = mock(UiccSlotInfo.class);
+
+        when(info2slot.getLogicalSlotIdx()).thenReturn(-1);
+        when(info2slot.getCardStateInfo()).thenReturn(CARD_STATE_INFO_ABSENT);
+        when(info2slot.getCardId()).thenReturn("info2_cardid");
+
+        when(info3slot.getLogicalSlotIdx()).thenReturn(0);
+        when(info3slot.getCardStateInfo()).thenReturn(CARD_STATE_INFO_PRESENT);
+        when(info3slot.getCardId()).thenReturn("info3_cardid");
+
+        final UiccSlotInfo[] slotInfos = {info2slot, info3slot};
+        when(mTelMgr.getUiccSlotsInfo()).thenReturn(slotInfos);
+
+        final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mContext);
+        assertThat(subs).hasSize(2);
+        assertThat(subs.get(0).getSubscriptionId()).isEqualTo(111);
+        assertThat(subs.get(1).getSubscriptionId()).isEqualTo(333);
+    }
+
+    @Test
     public void getActiveSubscriptions_nullInfoFromSubscriptionManager_nonNullResult() {
-        when(mManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(null);
-        final List<SubscriptionInfo> subs = SubscriptionUtil.getActiveSubscriptions(mManager);
+        when(mSubMgr.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(null);
+        final List<SubscriptionInfo> subs = SubscriptionUtil.getActiveSubscriptions(mSubMgr);
         assertThat(subs).isNotNull();
         assertThat(subs).isEmpty();
     }
@@ -121,8 +213,8 @@
     @Test
     public void getActiveSubscriptions_oneSubscription_oneResult() {
         final SubscriptionInfo info = mock(SubscriptionInfo.class);
-        when(mManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(Arrays.asList(info));
-        final List<SubscriptionInfo> subs = SubscriptionUtil.getActiveSubscriptions(mManager);
+        when(mSubMgr.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(Arrays.asList(info));
+        final List<SubscriptionInfo> subs = SubscriptionUtil.getActiveSubscriptions(mSubMgr);
         assertThat(subs).isNotNull();
         assertThat(subs).hasSize(1);
     }
@@ -131,9 +223,9 @@
     public void getActiveSubscriptions_twoSubscriptions_twoResults() {
         final SubscriptionInfo info1 = mock(SubscriptionInfo.class);
         final SubscriptionInfo info2 = mock(SubscriptionInfo.class);
-        when(mManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(
+        when(mSubMgr.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(
                 Arrays.asList(info1, info2));
-        final List<SubscriptionInfo> subs = SubscriptionUtil.getActiveSubscriptions(mManager);
+        final List<SubscriptionInfo> subs = SubscriptionUtil.getActiveSubscriptions(mSubMgr);
         assertThat(subs).isNotNull();
         assertThat(subs).hasSize(2);
     }
diff --git a/tests/robotests/src/com/android/settings/network/telephony/DisabledSubscriptionControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/DisabledSubscriptionControllerTest.java
new file mode 100644
index 0000000..c1004fa
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/telephony/DisabledSubscriptionControllerTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2019 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.network.telephony;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.telephony.SubscriptionManager;
+
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceScreen;
+
+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;
+
+@RunWith(RobolectricTestRunner.class)
+public class DisabledSubscriptionControllerTest {
+
+    private static final String KEY = "disabled_subscription_category";
+    private static final int SUB_ID = 111;
+
+    @Mock
+    private SubscriptionManager mSubscriptionManager;
+    @Mock
+    private PreferenceScreen mScreen;
+
+    private PreferenceCategory mCategory;
+    private Context mContext;
+    private Lifecycle mLifecycle;
+    private DisabledSubscriptionController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        LifecycleOwner lifecycleOwner = () -> mLifecycle;
+        mLifecycle = new Lifecycle(lifecycleOwner);
+        doReturn(mSubscriptionManager).when(mContext).getSystemService(SubscriptionManager.class);
+        mCategory = new PreferenceCategory(mContext);
+        doReturn(mCategory).when(mScreen).findPreference(KEY);
+        mController = new DisabledSubscriptionController(mContext, KEY);
+        mController.init(mLifecycle, SUB_ID);
+    }
+
+    @Test
+    public void displayPreference_subscriptionEnabled_categoryIsVisible() {
+        doReturn(true).when(mSubscriptionManager).isSubscriptionEnabled(SUB_ID);
+        mController.displayPreference(mScreen);
+        assertThat(mCategory.isVisible()).isTrue();
+    }
+
+    @Test
+    public void displayPreference_subscriptionDisabled_categoryIsNotVisible() {
+        doReturn(false).when(mSubscriptionManager).isSubscriptionEnabled(SUB_ID);
+        mController.displayPreference(mScreen);
+        assertThat(mCategory.isVisible()).isFalse();
+    }
+
+    @Test
+    public void onSubscriptionsChanged_subscriptionBecomesDisabled_categoryIsNotVisible() {
+        doReturn(true).when(mSubscriptionManager).isSubscriptionEnabled(SUB_ID);
+        mController.displayPreference(mScreen);
+        doReturn(false).when(mSubscriptionManager).isSubscriptionEnabled(SUB_ID);
+        mController.onSubscriptionsChanged();
+        assertThat(mCategory.isVisible()).isFalse();
+    }
+
+    @Test
+    public void onSubscriptionsChanged_subscriptionBecomesEnabled_categoryIsVisible() {
+        doReturn(false).when(mSubscriptionManager).isSubscriptionEnabled(SUB_ID);
+        mController.displayPreference(mScreen);
+        doReturn(true).when(mSubscriptionManager).isSubscriptionEnabled(SUB_ID);
+        mController.onSubscriptionsChanged();
+        assertThat(mCategory.isVisible()).isTrue();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
index 1b7b4b4..e853c47 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
@@ -21,7 +21,6 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
@@ -30,6 +29,10 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+import androidx.preference.SwitchPreference;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -40,10 +43,6 @@
 import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowSubscriptionManager;
 
-import androidx.fragment.app.FragmentManager;
-import androidx.fragment.app.FragmentTransaction;
-import androidx.preference.SwitchPreference;
-
 @RunWith(RobolectricTestRunner.class)
 @Config(shadows = ShadowSubscriptionManager.class)
 public class MobileDataPreferenceControllerTest {
@@ -94,14 +93,13 @@
     }
 
     @Test
-    public void isDialogNeeded_disableSingleSim_returnTrue() {
+    public void isDialogNeeded_disableSingleSim_returnFalse() {
         doReturn(true).when(mTelephonyManager).isDataEnabled();
         doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID);
         doReturn(mSubscriptionInfo).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
         doReturn(1).when(mTelephonyManager).getSimCount();
 
-        assertThat(mController.isDialogNeeded()).isTrue();
-        assertThat(mController.mDialogType).isEqualTo(MobileDataDialogFragment.TYPE_DISABLE_DIALOG);
+        assertThat(mController.isDialogNeeded()).isFalse();
     }
 
     @Test
@@ -127,7 +125,7 @@
     }
 
     @Test
-    public void onPreferenceChange_needDialog_doNothing() {
+    public void onPreferenceChange_singleSim_On_shouldEnableData() {
         doReturn(true).when(mTelephonyManager).isDataEnabled();
         doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID);
         doReturn(mSubscriptionInfo).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
@@ -135,11 +133,11 @@
 
         mController.onPreferenceChange(mPreference, true);
 
-        verify(mTelephonyManager, never()).setDataEnabled(true);
+        verify(mTelephonyManager).setDataEnabled(true);
     }
 
     @Test
-    public void onPreferenceChange_notNeedDialog_update() {
+    public void onPreferenceChange_multiSim_On_shouldEnableData() {
         doReturn(true).when(mTelephonyManager).isDataEnabled();
         doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID);
         doReturn(mSubscriptionInfo).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
diff --git a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkActivityTest.java b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkActivityTest.java
index 68f8c91..f38f2a2 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkActivityTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkActivityTest.java
@@ -33,15 +33,18 @@
 import android.provider.Settings;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
 import android.view.Menu;
 import android.view.View;
 
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.view.menu.ContextMenuBuilder;
 import com.android.settings.R;
+import com.android.settings.network.SubscriptionUtil;
 
 import com.google.android.material.bottomnavigation.BottomNavigationView;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -52,6 +55,7 @@
 import org.robolectric.RuntimeEnvironment;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 import androidx.fragment.app.Fragment;
@@ -73,6 +77,8 @@
     @Mock
     private SubscriptionManager mSubscriptionManager;
     @Mock
+    private TelephonyManager mTelephonyManager;
+    @Mock
     private SubscriptionInfo mSubscriptionInfo;
     @Mock
     private SubscriptionInfo mSubscriptionInfo2;
@@ -99,6 +105,8 @@
 
         doReturn(mSubscriptionManager).when(mMobileNetworkActivity).getSystemService(
                 SubscriptionManager.class);
+        doReturn(mTelephonyManager).when(mMobileNetworkActivity).getSystemService(
+                TelephonyManager.class);
         doReturn(mBottomNavigationView).when(mMobileNetworkActivity).findViewById(R.id.bottom_nav);
         doReturn(mFragmentManager).when(mMobileNetworkActivity).getSupportFragmentManager();
         doReturn(mFragmentTransaction).when(mFragmentManager).beginTransaction();
@@ -108,6 +116,11 @@
                 MOBILE_SETTINGS_TAG + CURRENT_SUB_ID);
     }
 
+    @After
+    public void tearDown() {
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(null);
+    }
+
     @Test
     public void updateBottomNavigationView_oneSubscription_shouldBeGone() {
         mSubscriptionInfos.add(mSubscriptionInfo);
@@ -169,7 +182,7 @@
         doReturn(intent).when(mMobileNetworkActivity).getIntent();
         mSubscriptionInfos.add(mSubscriptionInfo);
         mSubscriptionInfos.add(mSubscriptionInfo2);
-        doReturn(mSubscriptionInfos).when(mSubscriptionManager).getSelectableSubscriptionInfoList();
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(mSubscriptionInfos);
         doReturn(true).when(mSubscriptionManager).isActiveSubscriptionId(CURRENT_SUB_ID);
 
         assertThat(mMobileNetworkActivity.getSubscriptionId()).isEqualTo(CURRENT_SUB_ID);
diff --git a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSwitchControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSwitchControllerTest.java
index 6d85826..a10227f 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSwitchControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSwitchControllerTest.java
@@ -20,6 +20,7 @@
 
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
@@ -99,13 +100,22 @@
     }
 
     @Test
-    public void displayPreference_onlyOneSubscription_switchBarHidden() {
+    public void displayPreference_oneEnabledSubscription_switchBarHidden() {
+        doReturn(true).when(mSubscriptionManager).isSubscriptionEnabled(mSubId);
         SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(mSubscription));
         mController.displayPreference(mScreen);
         assertThat(mSwitchBar.isShowing()).isFalse();
     }
 
     @Test
+    public void displayPreference_oneDisabledSubscription_switchBarNotHidden() {
+        doReturn(false).when(mSubscriptionManager).isSubscriptionEnabled(mSubId);
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(mSubscription));
+        mController.displayPreference(mScreen);
+        assertThat(mSwitchBar.isShowing()).isTrue();
+    }
+
+    @Test
     public void displayPreference_subscriptionEnabled_switchIsOn() {
         when(mSubscriptionManager.isSubscriptionEnabled(mSubId)).thenReturn(true);
         mController.displayPreference(mScreen);
diff --git a/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java b/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java
index 793b44d..44dc3bc 100644
--- a/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java
@@ -36,20 +36,19 @@
 import com.android.settings.testutils.FakeFeatureFactory;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
-import org.robolectric.android.controller.ActivityController;
 
 @RunWith(RobolectricTestRunner.class)
 public class PanelFragmentTest {
 
     private Context mContext;
     private PanelFragment mPanelFragment;
+    private FakeSettingsPanelActivity mActivity;
     private FakeFeatureFactory mFakeFeatureFactory;
     private PanelFeatureProvider mPanelFeatureProvider;
     private FakePanelContent mFakePanelContent;
@@ -66,16 +65,12 @@
         mFakePanelContent = new FakePanelContent();
         doReturn(mFakePanelContent).when(mPanelFeatureProvider).getPanel(any(), any(), any());
 
-        ActivityController<FakeSettingsPanelActivity> activityController =
-                Robolectric.buildActivity(FakeSettingsPanelActivity.class);
-        activityController.setup();
+        mActivity = spy(Robolectric.buildActivity(FakeSettingsPanelActivity.class).setup().get());
 
         mPanelFragment =
                 spy((PanelFragment)
-                        activityController
-                                .get()
-                                .getSupportFragmentManager()
-                                .findFragmentById(R.id.main_content));
+                        mActivity.getSupportFragmentManager().findFragmentById(R.id.main_content));
+        doReturn(mActivity).when(mPanelFragment).getActivity();
 
         final Bundle bundle = new Bundle();
         bundle.putString(SettingsPanelActivity.KEY_PANEL_TYPE_ARGUMENT, FAKE_EXTRA);
@@ -106,23 +101,23 @@
     }
 
     @Test
-    @Ignore("b/130896218")
     public void onDestroy_logCloseEvent() {
-        mPanelFragment.onDestroy();
+        mPanelFragment.onDestroyView();
         verify(mFakeFeatureFactory.metricsFeatureProvider).action(
                 0,
-                SettingsEnums.PAGE_VISIBLE,
+                SettingsEnums.PAGE_HIDE,
                 mFakePanelContent.getMetricsCategory(),
-                any(String.class),
-                0);    }
+                PanelLoggingContract.PanelClosedKeys.KEY_OTHERS,
+                0);
+    }
 
     @Test
-    @Ignore("b/130896218")
     public void panelSeeMoreClick_logsCloseEvent() {
         final View.OnClickListener listener = mPanelFragment.getSeeMoreListener();
-
         listener.onClick(null);
+        verify(mActivity).finish();
 
+        mPanelFragment.onDestroyView();
         verify(mFakeFeatureFactory.metricsFeatureProvider).action(
                 0,
                 SettingsEnums.PAGE_HIDE,
@@ -133,12 +128,12 @@
     }
 
     @Test
-    @Ignore("b/130896218")
     public void panelDoneClick_logsCloseEvent() {
         final View.OnClickListener listener = mPanelFragment.getCloseListener();
-
         listener.onClick(null);
+        verify(mActivity).finish();
 
+        mPanelFragment.onDestroyView();
         verify(mFakeFeatureFactory.metricsFeatureProvider).action(
                 0,
                 SettingsEnums.PAGE_HIDE,
diff --git a/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java b/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
index 4ca6395..8ad2156 100644
--- a/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
+++ b/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
@@ -35,7 +35,6 @@
 import com.android.settings.testutils.FakeFeatureFactory;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.Robolectric;
@@ -52,8 +51,8 @@
     @Before
     public void setUp() {
         mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
-        mSettingsPanelActivity = Robolectric.buildActivity(FakeSettingsPanelActivity.class)
-                .create().get();
+        mSettingsPanelActivity = spy(
+                Robolectric.buildActivity(FakeSettingsPanelActivity.class).create().get());
         mPanelFeatureProvider = spy(new PanelFeatureProviderImpl());
         mFakeFeatureFactory.panelFeatureProvider = mPanelFeatureProvider;
         mFakePanelContent = new FakePanelContent();
@@ -88,21 +87,4 @@
         assertThat(activity.mBundle.getString(KEY_PANEL_TYPE_ARGUMENT))
                 .isEqualTo("com.android.settings.panel.action.MEDIA_OUTPUT");
     }
-
-    @Test
-    @Ignore("b/130896218")
-    public void onTouchEvent_outsideAction_logsPanelClosed() {
-        final MotionEvent event = mock(MotionEvent.class);
-        when(event.getAction()).thenReturn(MotionEvent.ACTION_OUTSIDE);
-
-        mSettingsPanelActivity.onTouchEvent(event);
-
-        verify(mFakeFeatureFactory.metricsFeatureProvider).action(
-                0,
-                SettingsEnums.PAGE_HIDE,
-                SettingsEnums.TESTING,
-                PanelLoggingContract.PanelClosedKeys.KEY_OTHERS,
-                0
-        );
-    }
 }
diff --git a/tests/robotests/src/com/android/settings/panel/VolumePanelTest.java b/tests/robotests/src/com/android/settings/panel/VolumePanelTest.java
index 154428d..8dd04ce 100644
--- a/tests/robotests/src/com/android/settings/panel/VolumePanelTest.java
+++ b/tests/robotests/src/com/android/settings/panel/VolumePanelTest.java
@@ -18,32 +18,71 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.media.session.ISessionController;
+import android.media.session.MediaController;
+import android.media.session.MediaSession;
+import android.media.session.MediaSessionManager;
 import android.net.Uri;
 
+import com.android.settings.notification.RemoteVolumePreferenceController;
 import com.android.settings.slices.CustomSliceRegistry;
 
 import org.junit.Before;
-import org.junit.Ignore;
 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 java.util.ArrayList;
 import java.util.List;
 
 @RunWith(RobolectricTestRunner.class)
 public class VolumePanelTest {
 
+    @Mock
+    private MediaSessionManager mMediaSessionManager;
+    @Mock
+    private MediaController mMediaController;
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private ISessionController mStub;
+
+
     private VolumePanel mPanel;
+    private Context mContext;
+
 
     @Before
     public void setUp() {
-        mPanel = VolumePanel.create(RuntimeEnvironment.application);
+        MockitoAnnotations.initMocks(this);
+
+        mContext = spy(RuntimeEnvironment.application);
+
+        when(mContext.getApplicationContext()).thenReturn(mContext);
+        when(mContext.getSystemService(MediaSessionManager.class)).thenReturn(mMediaSessionManager);
+
+        mPanel = VolumePanel.create(mContext);
     }
 
     @Test
-    @Ignore("b/130896218")
-    public void getSlices_containsNecessarySlices() {
+    public void getSlices_hasActiveRemoteToken_containsRemoteMediaUri() {
+        List<MediaController> activeSessions = new ArrayList<>();
+        MediaSession.Token token = new MediaSession.Token(mStub);
+        activeSessions.add(mMediaController);
+
+        when(mMediaSessionManager.getActiveSessions(null)).thenReturn(
+                activeSessions);
+        when(mMediaController.getPlaybackInfo()).thenReturn(new MediaController.PlaybackInfo(
+                MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE, 0, 10, 5, null));
+        when(mMediaController.getSessionToken()).thenReturn(new MediaSession.Token(mStub));
+        when(RemoteVolumePreferenceController.getActiveRemoteToken(mContext)).thenReturn(token);
+
         final List<Uri> uris = mPanel.getSlices();
 
         assertThat(uris).containsExactly(
@@ -56,6 +95,22 @@
     }
 
     @Test
+    public void getSlices_doesNotHaveActiveRemoteToken_doesNotcontainRemoteMediaUri() {
+        final List<Uri> uris = mPanel.getSlices();
+
+        when(RemoteVolumePreferenceController.getActiveRemoteToken(mContext))
+            .thenReturn(null);
+
+        assertThat(uris).doesNotContain(CustomSliceRegistry.VOLUME_REMOTE_MEDIA_URI);
+        assertThat(uris).containsExactly(
+            CustomSliceRegistry.VOLUME_CALL_URI,
+            CustomSliceRegistry.VOLUME_MEDIA_URI,
+            CustomSliceRegistry.MEDIA_OUTPUT_INDICATOR_SLICE_URI,
+            CustomSliceRegistry.VOLUME_RINGER_URI,
+            CustomSliceRegistry.VOLUME_ALARM_URI);
+    }
+
+    @Test
     public void getSeeMoreIntent_notNull() {
         assertThat(mPanel.getSeeMoreIntent()).isNotNull();
     }
diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
index 904fdd8..3ffe61a 100644
--- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
@@ -1624,6 +1624,39 @@
     }
 
     @Test
+    public void testConnectButton_clickConnectAndBackKey_ignoreTimeoutEvent() {
+        setUpForDisconnectedNetwork();
+        when(mockWifiManager.isWifiEnabled()).thenReturn(true);
+        InOrder inOrder = inOrder(mockButtonsPref);
+        setUpForToast();
+
+        displayAndResume();
+
+        // check connect button exist
+        verifyConnectBtnSetUpAsVisible(inOrder);
+
+        // click connect button
+        mController.connectNetwork();
+
+        // check display button as connecting
+        verify(mockWifiManager, times(1)).connect(anyInt(), any(WifiManager.ActionListener.class));
+        verifyConnectBtnSetUpAsConnecting(inOrder);
+
+        // leave detail page
+        when(mockFragment.getActivity()).thenReturn(null);
+
+        // timeout happened
+        mController.mTimer.onFinish();
+
+        // check connect button visible, be init as default and toast failed message
+        inOrder.verify(mockButtonsPref, never()).setButton3Text(R.string.wifi_connect);
+        inOrder.verify(mockButtonsPref, never()).setButton3Icon(R.drawable.ic_settings_wireless);
+        inOrder.verify(mockButtonsPref, never()).setButton3Enabled(true);
+        inOrder.verify(mockButtonsPref, never()).setButton3Visible(true);
+        assertThat(ShadowToast.shownToastCount()).isEqualTo(0);
+    }
+
+    @Test
     public void updateAccessPoint_returnFalseForNothingChanged() {
         setUpForDisconnectedNetwork();
 
@@ -1653,7 +1686,7 @@
         displayAndResume();
 
         // change as not in range
-        when(mockAccessPoint.matches(any(WifiConfiguration.class))).thenReturn(false);
+        when(mockAccessPoint.matches(any(AccessPoint.class))).thenReturn(false);
         boolean changed = mController.updateAccessPoint();
 
         assertThat(changed).isTrue();
@@ -1666,7 +1699,7 @@
         displayAndResume();
 
         // change as in range
-        when(mockAccessPoint.matches(any(WifiConfiguration.class))).thenReturn(true);
+        when(mockAccessPoint.matches(any(AccessPoint.class))).thenReturn(true);
         boolean changed = mController.updateAccessPoint();
 
         assertThat(changed).isTrue();
diff --git a/tests/robotests/src/com/android/settings/wifi/slice/ConnectToWifiHandlerTest.java b/tests/robotests/src/com/android/settings/wifi/slice/ConnectToWifiHandlerTest.java
index b18102d..cea8365 100644
--- a/tests/robotests/src/com/android/settings/wifi/slice/ConnectToWifiHandlerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/slice/ConnectToWifiHandlerTest.java
@@ -27,7 +27,6 @@
 import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
 import android.net.wifi.WifiManager;
 
-import com.android.settings.testutils.shadow.ShadowConnectivityManager;
 import com.android.settings.testutils.shadow.ShadowWifiManager;
 import com.android.settingslib.wifi.AccessPoint;
 
@@ -41,13 +40,10 @@
 import org.robolectric.annotation.Config;
 
 @RunWith(RobolectricTestRunner.class)
-@Config(shadows = {
-        ShadowConnectivityManager.class,
-        ShadowWifiManager.class,
-})
+@Config(shadows = ShadowWifiManager.class)
 public class ConnectToWifiHandlerTest {
 
-    private static final String AP1_SSID = "\"ap1\"";
+    private static final String AP_SSID = "\"ap\"";
     private ConnectToWifiHandler mHandler;
     private WifiConfiguration mWifiConfig;
     @Mock
@@ -59,7 +55,7 @@
 
         mHandler = Robolectric.setupActivity(ConnectToWifiHandler.class);
         mWifiConfig = new WifiConfiguration();
-        mWifiConfig.SSID = AP1_SSID;
+        mWifiConfig.SSID = AP_SSID;
         doReturn(mWifiConfig).when(mAccessPoint).getConfig();
     }
 
@@ -70,7 +66,7 @@
 
         mHandler.connect(mAccessPoint);
 
-        assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP1_SSID);
+        assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP_SSID);
     }
 
     @Test
@@ -91,7 +87,7 @@
 
         mHandler.connect(mAccessPoint);
 
-        assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP1_SSID);
+        assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP_SSID);
     }
 
     @Test
@@ -104,7 +100,7 @@
 
         mHandler.connect(mAccessPoint);
 
-        assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP1_SSID);
+        assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP_SSID);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java b/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java
index 30e289b..19d3e40 100644
--- a/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java
@@ -20,36 +20,54 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.Intent;
 import android.net.ConnectivityManager;
 import android.net.Network;
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.State;
+import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
+import android.net.wifi.WifiSsid;
 import android.os.Bundle;
+import android.os.UserHandle;
 
 import androidx.slice.SliceProvider;
 import androidx.slice.widget.SliceLiveData;
 
+import com.android.settings.testutils.shadow.ShadowWifiManager;
 import com.android.settingslib.wifi.AccessPoint;
+import com.android.settingslib.wifi.WifiTracker;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
 
 @RunWith(RobolectricTestRunner.class)
+@Config(shadows = {
+        ShadowWifiManager.class,
+        WifiScanWorkerTest.ShadowWifiTracker.class,
+})
 public class WifiScanWorkerTest {
 
     private static final String AP_NAME = "ap";
@@ -59,6 +77,7 @@
     private WifiManager mWifiManager;
     private ConnectivityManager mConnectivityManager;
     private WifiScanWorker mWifiScanWorker;
+    private ConnectToWifiHandler mConnectToWifiHandler;
 
     @Before
     public void setUp() {
@@ -73,6 +92,12 @@
 
         mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
         mWifiScanWorker = new WifiScanWorker(mContext, WIFI_SLICE_URI);
+        mConnectToWifiHandler = Robolectric.setupActivity(ConnectToWifiHandler.class);
+    }
+
+    @After
+    public void tearDown() {
+        mWifiScanWorker.clearClickedWifi();
     }
 
     @Test
@@ -131,4 +156,82 @@
 
         verify(mResolver).notifyChange(WIFI_SLICE_URI, null);
     }
+
+    private AccessPoint createAccessPoint(String ssid) {
+        final AccessPoint accessPoint = mock(AccessPoint.class);
+        doReturn(ssid).when(accessPoint).getSsidStr();
+        return accessPoint;
+    }
+
+    private void setConnectionInfoSSID(String ssid) {
+        final WifiInfo wifiInfo = new WifiInfo();
+        wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(ssid));
+        ShadowWifiManager.get().setConnectionInfo(wifiInfo);
+    }
+
+    @Test
+    public void NetworkCallback_onCapabilitiesChanged_isClickedWifi_shouldStartActivity() {
+        final AccessPoint accessPoint = createAccessPoint("ap1");
+        setConnectionInfoSSID("ap1");
+        final Network network = mConnectivityManager.getActiveNetwork();
+        mWifiScanWorker.registerCaptivePortalNetworkCallback(network);
+
+        mConnectToWifiHandler.connect(accessPoint);
+        mWifiScanWorker.mCaptivePortalNetworkCallback.onCapabilitiesChanged(network,
+                WifiSliceTest.makeCaptivePortalNetworkCapabilities());
+
+        verify(mContext).startActivityAsUser(any(Intent.class), eq(UserHandle.CURRENT));
+    }
+
+    @Test
+    public void NetworkCallback_onCapabilitiesChanged_isNotClickedWifi_shouldNotStartActivity() {
+        final AccessPoint accessPoint = createAccessPoint("ap1");
+        setConnectionInfoSSID("ap2");
+        final Network network = mConnectivityManager.getActiveNetwork();
+        mWifiScanWorker.registerCaptivePortalNetworkCallback(network);
+
+        mConnectToWifiHandler.connect(accessPoint);
+        mWifiScanWorker.mCaptivePortalNetworkCallback.onCapabilitiesChanged(network,
+                WifiSliceTest.makeCaptivePortalNetworkCapabilities());
+
+        verify(mContext, never()).startActivityAsUser(any(Intent.class), eq(UserHandle.CURRENT));
+    }
+
+    @Test
+    public void NetworkCallback_onCapabilitiesChanged_neverClickWifi_shouldNotStartActivity() {
+        setConnectionInfoSSID("ap1");
+        final Network network = mConnectivityManager.getActiveNetwork();
+        mWifiScanWorker.registerCaptivePortalNetworkCallback(network);
+
+        mWifiScanWorker.mCaptivePortalNetworkCallback.onCapabilitiesChanged(network,
+                WifiSliceTest.makeCaptivePortalNetworkCapabilities());
+
+        verify(mContext, never()).startActivityAsUser(any(Intent.class), eq(UserHandle.CURRENT));
+    }
+
+    @Test
+    public void NetworkCallback_onCapabilitiesChanged_sliceIsUnpinned_shouldNotStartActivity() {
+        final AccessPoint accessPoint = createAccessPoint("ap1");
+        setConnectionInfoSSID("ap1");
+        final Network network = mConnectivityManager.getActiveNetwork();
+        mWifiScanWorker.registerCaptivePortalNetworkCallback(network);
+        final WifiScanWorker.CaptivePortalNetworkCallback callback =
+                mWifiScanWorker.mCaptivePortalNetworkCallback;
+
+        mWifiScanWorker.onSlicePinned();
+        mConnectToWifiHandler.connect(accessPoint);
+        mWifiScanWorker.onSliceUnpinned();
+        callback.onCapabilitiesChanged(network,
+                WifiSliceTest.makeCaptivePortalNetworkCapabilities());
+
+        verify(mContext, never()).startActivityAsUser(any(Intent.class), eq(UserHandle.CURRENT));
+    }
+
+    @Implements(WifiTracker.class)
+    public static class ShadowWifiTracker {
+        @Implementation
+        public void onStart() {
+            // do nothing
+        }
+    }
 }