Merge "Remove On/Off string from Night light slice" into qt-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index dfbc02c..c112115 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1562,6 +1562,11 @@
             android:exported="false"
             android:screenOrientation="portrait"/>
 
+        <!-- Must not be exported -->
+        <activity android:name=".biometrics.BiometricEnrollActivity$InternalActivity"
+            android:exported="false"
+            android:theme="@style/GlifTheme.Light"/>
+
         <activity android:name=".biometrics.BiometricEnrollActivity"
             android:exported="true"
             android:theme="@style/GlifTheme.Light">
@@ -2687,10 +2692,12 @@
             android:excludeFromRecents="true"
             android:exported="false" />
 
-        <activity android:name=".sim.SimDialogActivity"
-                android:theme="@style/Theme.AlertDialog"
-                android:label="@string/sim_settings_title"
-                android:excludeFromRecents="true">
+        <activity
+            android:name=".sim.SimDialogActivity"
+            android:theme="@style/Theme.AlertDialog"
+            android:label="@string/sim_settings_title"
+            android:launchMode="singleTop"
+            android:excludeFromRecents="true">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
             </intent-filter>
@@ -2902,7 +2909,7 @@
             android:launchMode="singleInstance"
             android:theme="@android:style/Theme.NoDisplay">
             <intent-filter>
-                <action android:name="android.settings.VIEW_ADVANCED_POWER_USAGE_DETAIL" />
+                <action android:name="android.settings.APP_BATTERY_SETTINGS" />
                 <category android:name="android.intent.category.DEFAULT" />
                 <data android:scheme="package" />
             </intent-filter>
diff --git a/res/drawable/dark_theme.xml b/res/drawable/dark_theme.xml
new file mode 100644
index 0000000..3425002
--- /dev/null
+++ b/res/drawable/dark_theme.xml
@@ -0,0 +1,26 @@
+<?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
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="48dp"
+        android:height="48dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/colorAccent">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M12,22C17.52,22 22,17.52 22,12 22,6.48 17.52,2 12,2 6.48,2 2,6.48 2,12 2,17.52 6.48,22 12,22ZM12,3.915c3.889,0 8,4.005 8,8.085 0,4.08 -3.927,7.992 -7.928,7.992z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_battery_saver_accent_24dp.xml b/res/drawable/ic_battery_saver_accent_24dp.xml
index 764402d..31eb193 100644
--- a/res/drawable/ic_battery_saver_accent_24dp.xml
+++ b/res/drawable/ic_battery_saver_accent_24dp.xml
@@ -13,17 +13,7 @@
   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.0"
-        android:viewportHeight="24.0"
-        android:tint="?android:attr/colorAccent">
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="M16.67,4H14.5V2h-5v2H7.33C6.6,4 6,4.6 6,5.33V15v5.67C6,21.4 6.6,22 7.33,22h9.33C17.4,22 18,21.4 18,20.67V15V5.33C18,4.6 17.4,4 16.67,4zM16,15v5H8v-5V6h8V15z"/>
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="M15,12l-2,0l0,-2l-2,0l0,2l-2,0l0,2l2,0l0,2l2,0l0,-2l2,0z"/>
-</vector>
+<com.android.settings.widget.TintDrawable
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_battery_status_bad_24dp"
+    android:tint="?android:attr/colorAccent" />
diff --git a/res/drawable/ic_delete_accent.xml b/res/drawable/ic_delete_accent.xml
index 86a9cca..2f087e8 100644
--- a/res/drawable/ic_delete_accent.xml
+++ b/res/drawable/ic_delete_accent.xml
@@ -13,19 +13,7 @@
   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="24.0dp"
-        android:height="24.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"
-        android:tint="?android:attr/colorAccent">
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="M15,4V3H9v1H4v2h1v13c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V6h1V4H15zM17,19H7V6h10V19z"/>
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="M9,8h2v9h-2z"/>
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="M13,8h2v9h-2z"/>
-</vector>
+<com.android.settings.widget.TintDrawable
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_delete"
+    android:tint="?android:attr/colorAccent" />
diff --git a/res/drawable/ic_settings_wireless_white.xml b/res/drawable/ic_settings_wireless_white.xml
index 3271b8b..63be43b 100644
--- a/res/drawable/ic_settings_wireless_white.xml
+++ b/res/drawable/ic_settings_wireless_white.xml
@@ -13,12 +13,7 @@
   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="24.0dp"
-        android:height="24.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M1,9l2,2c4.97,-4.97 13.03,-4.97 18,0l2,-2C16.93,2.93 7.08,2.93 1,9zM9,17l3,3l3,-3C13.35,15.34 10.66,15.34 9,17zM5,13l2,2c2.76,-2.76 7.24,-2.76 10,0l2,-2C15.14,9.14 8.87,9.14 5,13z"/>
-</vector>
+<com.android.settings.widget.TintDrawable
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_settings_wireless"
+    android:tint="@android:color/white" />
\ No newline at end of file
diff --git a/res/drawable/ic_wifi_signal_0.xml b/res/drawable/ic_wifi_signal_0.xml
index 55faf64..4a3567a 100644
--- a/res/drawable/ic_wifi_signal_0.xml
+++ b/res/drawable/ic_wifi_signal_0.xml
@@ -14,13 +14,7 @@
     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="26dp"
-  android:height="24dp"
-  android:viewportWidth="26"
-  android:viewportHeight="24">
-  <path
-    android:fillAlpha="0.3"
-    android:fillColor="?attr/wifi_signal_color"
-    android:pathData="M13.0,22.0L25.6,6.5C25.1,6.1 20.3,2.1 13.0,2.1S0.9,6.1 0.4,6.5L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0z"/>
-</vector>
\ No newline at end of file
+<com.android.settings.widget.TintDrawable
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@*android:drawable/ic_wifi_signal_0"
+    android:tint="?attr/wifi_signal_color" />
\ No newline at end of file
diff --git a/res/drawable/ic_wifi_signal_1.xml b/res/drawable/ic_wifi_signal_1.xml
index e0a2072..88a9468 100644
--- a/res/drawable/ic_wifi_signal_1.xml
+++ b/res/drawable/ic_wifi_signal_1.xml
@@ -14,16 +14,7 @@
     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="26dp"
-    android:height="24dp"
-    android:viewportWidth="26"
-    android:viewportHeight="24">
-    <path
-        android:fillAlpha="0.3"
-        android:fillColor="?attr/wifi_signal_color"
-        android:pathData="M13.1,22.0L25.6,6.5C25.1,6.1 20.3,2.1 13.0,2.1S0.9,6.1 0.5,6.5L13.1,22.0L13.1,22.0L13.1,22.0L13.1,22.0L13.1,22.0z"/>
-    <path
-        android:fillColor="?attr/wifi_signal_color"
-        android:pathData="M13.1,22.0l5.5,-6.8c-0.2,-0.2 -2.3,-1.9 -5.5,-1.9s-5.3,1.8 -5.5,1.9L13.1,22.0L13.1,22.0L13.1,22.0L13.1,22.0L13.1,22.0z"/>
-</vector>
+<com.android.settings.widget.TintDrawable
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@*android:drawable/ic_wifi_signal_1"
+    android:tint="?attr/wifi_signal_color" />
\ No newline at end of file
diff --git a/res/drawable/ic_wifi_signal_2.xml b/res/drawable/ic_wifi_signal_2.xml
index d0daa60..b1c2859d 100644
--- a/res/drawable/ic_wifi_signal_2.xml
+++ b/res/drawable/ic_wifi_signal_2.xml
@@ -14,16 +14,7 @@
     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="26dp"
-    android:height="24dp"
-    android:viewportWidth="26"
-    android:viewportHeight="24">
-    <path
-        android:fillAlpha="0.3"
-        android:fillColor="?attr/wifi_signal_color"
-        android:pathData="M13.0,22.0L25.6,6.5C25.1,6.1 20.3,2.1 13.0,2.1S0.9,6.1 0.4,6.5L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0z"/>
-    <path
-        android:fillColor="?attr/wifi_signal_color"
-        android:pathData="M13.0,22.0l7.6,-9.4C20.3,12.4 17.4,10.0 13.0,10.0s-7.3,2.4 -7.6,2.7L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0z"/>
-</vector>
+<com.android.settings.widget.TintDrawable
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@*android:drawable/ic_wifi_signal_2"
+    android:tint="?attr/wifi_signal_color" />
diff --git a/res/drawable/ic_wifi_signal_3.xml b/res/drawable/ic_wifi_signal_3.xml
index c542c69..b058eba 100644
--- a/res/drawable/ic_wifi_signal_3.xml
+++ b/res/drawable/ic_wifi_signal_3.xml
@@ -14,16 +14,7 @@
     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="26dp"
-    android:height="24dp"
-    android:viewportWidth="26"
-    android:viewportHeight="24">
-    <path
-        android:fillAlpha="0.3"
-        android:fillColor="?attr/wifi_signal_color"
-        android:pathData="M13.0,22.0L25.6,6.5C25.1,6.1 20.3,2.1 13.0,2.1S0.9,6.1 0.4,6.5L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0z"/>
-    <path
-        android:fillColor="?attr/wifi_signal_color"
-        android:pathData="M13.0,22.0l9.2,-11.4c-0.4,-0.3 -3.9,-3.2 -9.2,-3.2s-8.9,3.0 -9.2,3.2L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0z"/>
-</vector>
+<com.android.settings.widget.TintDrawable
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@*android:drawable/ic_wifi_signal_3"
+    android:tint="?attr/wifi_signal_color" />
\ No newline at end of file
diff --git a/res/drawable/ic_wifi_signal_4.xml b/res/drawable/ic_wifi_signal_4.xml
index bb7dbd0..e84066a 100644
--- a/res/drawable/ic_wifi_signal_4.xml
+++ b/res/drawable/ic_wifi_signal_4.xml
@@ -14,12 +14,7 @@
     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="26dp"
-    android:height="24dp"
-    android:viewportWidth="26"
-    android:viewportHeight="24">
-    <path
-        android:fillColor="?attr/wifi_signal_color"
-        android:pathData="M13.0,22.0L25.6,6.5C25.1,6.1 20.3,2.1 13.0,2.1S0.9,6.1 0.4,6.5L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0z"/>
-</vector>
+<com.android.settings.widget.TintDrawable
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@*android:drawable/ic_wifi_signal_4"
+    android:tint="?attr/wifi_signal_color" />
\ No newline at end of file
diff --git a/res/drawable/search_bar_selected_background.xml b/res/drawable/search_bar_selected_background.xml
new file mode 100644
index 0000000..b98ed9f
--- /dev/null
+++ b/res/drawable/search_bar_selected_background.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+        android:color="?android:attr/colorControlHighlight">
+    <item android:drawable="@color/search_bar_background"/>
+</ripple>
diff --git a/res/layout/choose_lock_password.xml b/res/layout/choose_lock_password.xml
index b779526..be947dc 100644
--- a/res/layout/choose_lock_password.xml
+++ b/res/layout/choose_lock_password.xml
@@ -34,7 +34,7 @@
         android:orientation="vertical">
 
         <TextView
-            android:id="@+id/message"
+            android:id="@+id/sud_layout_description"
             style="@style/SudDescription.Glif"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
diff --git a/res/layout/choose_lock_pattern_common.xml b/res/layout/choose_lock_pattern_common.xml
index 5d3cbca..0a2294f 100644
--- a/res/layout/choose_lock_pattern_common.xml
+++ b/res/layout/choose_lock_pattern_common.xml
@@ -70,7 +70,7 @@
             android:paddingRight="0dp">
 
             <TextView
-                android:id="@+id/message"
+                android:id="@+id/sud_layout_description"
                 style="@style/SudDescription.Glif"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
diff --git a/res/layout/confirm_lock_password_normal.xml b/res/layout/confirm_lock_password_normal.xml
index 7b04127..61d8505 100644
--- a/res/layout/confirm_lock_password_normal.xml
+++ b/res/layout/confirm_lock_password_normal.xml
@@ -28,7 +28,7 @@
         android:layout_height="match_parent">
 
         <TextView
-            android:id="@+id/detailsText"
+            android:id="@+id/sud_layout_description"
             style="@style/SudDescription.Glif"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
diff --git a/res/layout/confirm_lock_pattern_normal_base.xml b/res/layout/confirm_lock_pattern_normal_base.xml
index 03d3367..7e2cf8e 100644
--- a/res/layout/confirm_lock_pattern_normal_base.xml
+++ b/res/layout/confirm_lock_pattern_normal_base.xml
@@ -48,7 +48,7 @@
 
             <TextView
                 style="@style/SudDescription.Glif"
-                android:id="@+id/detailsText"
+                android:id="@+id/sud_layout_description"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginStart="?attr/sudMarginSides"
diff --git a/res/layout/encryption_interstitial.xml b/res/layout/encryption_interstitial.xml
index a2305f8..61ed292 100644
--- a/res/layout/encryption_interstitial.xml
+++ b/res/layout/encryption_interstitial.xml
@@ -30,7 +30,7 @@
         android:orientation="vertical">
 
         <TextView
-            android:id="@+id/encryption_message"
+            android:id="@+id/sud_layout_description"
             style="@style/SudDescription.Glif"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content" />
diff --git a/res/layout/face_enroll_introduction.xml b/res/layout/face_enroll_introduction.xml
index b55041a..71a02db 100644
--- a/res/layout/face_enroll_introduction.xml
+++ b/res/layout/face_enroll_introduction.xml
@@ -33,7 +33,7 @@
         android:orientation="vertical">
 
         <com.google.android.setupdesign.view.RichTextView
-            android:id="@+id/description_text"
+            android:id="@+id/sud_layout_description"
             style="@style/SudDescription.Glif"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
diff --git a/res/layout/fingerprint_enroll_enrolling_base.xml b/res/layout/fingerprint_enroll_enrolling_base.xml
index eed6fab..e1a9707 100644
--- a/res/layout/fingerprint_enroll_enrolling_base.xml
+++ b/res/layout/fingerprint_enroll_enrolling_base.xml
@@ -38,7 +38,7 @@
 
             <TextView
                 style="@style/SudDescription.Glif"
-                android:id="@+id/start_message"
+                android:id="@+id/sud_layout_description"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:minLines="3"
diff --git a/res/layout/fingerprint_enroll_find_sensor_base.xml b/res/layout/fingerprint_enroll_find_sensor_base.xml
index 2bef539..ce3104f 100644
--- a/res/layout/fingerprint_enroll_find_sensor_base.xml
+++ b/res/layout/fingerprint_enroll_find_sensor_base.xml
@@ -39,6 +39,7 @@
 
             <TextView
                 style="@style/SudDescription.Glif"
+                android:id="@+id/sud_layout_description"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginTop="@dimen/sud_description_glif_margin_top"
diff --git a/res/layout/fingerprint_enroll_finish_base.xml b/res/layout/fingerprint_enroll_finish_base.xml
index d85c56c..1f9167e 100644
--- a/res/layout/fingerprint_enroll_finish_base.xml
+++ b/res/layout/fingerprint_enroll_finish_base.xml
@@ -31,7 +31,7 @@
         android:clipChildren="false">
 
         <TextView
-            android:id="@+id/message"
+            android:id="@+id/sud_layout_description"
             style="@style/SudDescription.Glif"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
diff --git a/res/layout/fingerprint_enroll_introduction.xml b/res/layout/fingerprint_enroll_introduction.xml
index 47d2f02..41be2f6 100644
--- a/res/layout/fingerprint_enroll_introduction.xml
+++ b/res/layout/fingerprint_enroll_introduction.xml
@@ -31,7 +31,7 @@
         android:orientation="vertical">
 
         <com.google.android.setupdesign.view.RichTextView
-            android:id="@+id/description_text"
+            android:id="@+id/sud_layout_description"
             style="@style/SudDescription.Glif"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
diff --git a/res/layout/master_clear.xml b/res/layout/master_clear.xml
index 6368588..bf22b88 100644
--- a/res/layout/master_clear.xml
+++ b/res/layout/master_clear.xml
@@ -41,6 +41,7 @@
 
             <TextView
                 style="@style/TextAppearance.SudGlifItemSummary"
+                android:id="@+id/sud_layout_description"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:text="@string/master_clear_desc"/>
diff --git a/res/layout/master_clear_confirm.xml b/res/layout/master_clear_confirm.xml
index b4c0270..a236cd3 100644
--- a/res/layout/master_clear_confirm.xml
+++ b/res/layout/master_clear_confirm.xml
@@ -31,7 +31,7 @@
         android:orientation="vertical">
 
         <TextView
-            android:id="@+id/master_clear_confirm"
+            android:id="@+id/sud_layout_description"
             style="@style/SudItemTitle.GlifDescription"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
diff --git a/res/layout/panel_layout.xml b/res/layout/panel_layout.xml
index 3a8045f..c697afc 100644
--- a/res/layout/panel_layout.xml
+++ b/res/layout/panel_layout.xml
@@ -15,50 +15,60 @@
     limitations under the License
   -->
 
-<!-- Note: There is a landscape version of this layout. -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:layout_width="match_parent"
-              android:layout_height="wrap_content"
-              android:orientation="vertical">
-
-    <TextView
-        android:id="@+id/panel_title"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="center"
-        android:paddingBottom="24dp"
-        android:paddingTop="18dp"
-        android:textColor="?android:attr/colorPrimary"
-        android:textSize="20sp"/>
-
-    <include layout="@layout/panel_slice_list"/>
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/panel_container"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/settings_panel_background" >
 
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="8dp"
-        android:paddingBottom="8dp">
+        android:orientation="vertical">
 
-        <Button
-            android:id="@+id/see_more"
-            style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"
-            android:layout_width="wrap_content"
-            android:layout_height="48dp"
-            android:layout_marginStart="12dp"
-            android:text="@string/see_more"/>
+        <TextView
+            android:id="@+id/panel_title"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:paddingBottom="24dp"
+            android:paddingTop="18dp"
+            android:textColor="?android:attr/colorPrimary"
+            android:textSize="20sp"/>
 
-        <Space
-            android:layout_weight="1"
-            android:layout_width="0dp"
-            android:layout_height="match_parent" />
+        <include layout="@layout/horizontal_divider"/>
 
-        <Button
-            android:id="@+id/done"
-            style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"
-            android:layout_width="wrap_content"
-            android:layout_height="48dp"
-            android:layout_marginEnd="12dp"
-            android:text="@string/done"/>
+        <!-- Note: There is a landscape version of panel_slice_list which supports scrolling. -->
+        <include layout="@layout/panel_slice_list"/>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:paddingTop="8dp"
+            android:paddingBottom="8dp">
+
+            <Button
+                android:id="@+id/see_more"
+                style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"
+                android:layout_width="wrap_content"
+                android:layout_height="48dp"
+                android:layout_marginStart="12dp"
+                android:text="@string/see_more"/>
+
+            <Space
+                android:layout_weight="1"
+                android:layout_width="0dp"
+                android:layout_height="match_parent" />
+
+            <Button
+                android:id="@+id/done"
+                style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"
+                android:layout_width="wrap_content"
+                android:layout_height="48dp"
+                android:layout_marginEnd="12dp"
+                android:text="@string/done"/>
+        </LinearLayout>
     </LinearLayout>
-</LinearLayout>
\ No newline at end of file
+</FrameLayout>
\ No newline at end of file
diff --git a/res/layout/radio_info.xml b/res/layout/radio_info.xml
index fc8cc26..5c918fc 100644
--- a/res/layout/radio_info.xml
+++ b/res/layout/radio_info.xml
@@ -25,6 +25,19 @@
         android:descendantFocusability="beforeDescendants"
         android:focusableInTouchMode="true">
 
+        <!-- Phone index -->
+        <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/phone_index_label"
+                style="@style/info_label"
+                />
+
+        <Spinner android:id="@+id/phoneIndex"
+                 android:layout_width="match_parent"
+                 android:layout_height="wrap_content"
+                />
+
         <!-- IMEI -->
         <LinearLayout style="@style/entry_layout">
             <TextView android:text="@string/radio_info_imei_label" style="@style/info_label" />
@@ -37,6 +50,18 @@
             <TextView android:id="@+id/number" style="@style/info_value" />
         </LinearLayout>
 
+        <!-- Subscription ID -->
+        <LinearLayout style="@style/entry_layout">
+            <TextView android:text="@string/radio_info_subid" style="@style/info_label" />
+            <TextView android:id="@+id/subid" style="@style/info_value" />
+        </LinearLayout>
+
+        <!-- Default data subscription -->
+        <LinearLayout style="@style/entry_layout">
+            <TextView android:text="@string/radio_info_dds" style="@style/info_label" />
+            <TextView android:id="@+id/dds" style="@style/info_value" />
+        </LinearLayout>
+
         <!-- IMSI -->
         <LinearLayout style="@style/entry_layout">
             <TextView android:text="@string/radio_info_imsi_label" style="@style/info_label" />
diff --git a/res/layout/redaction_interstitial.xml b/res/layout/redaction_interstitial.xml
index f911572..0ad8b4d 100644
--- a/res/layout/redaction_interstitial.xml
+++ b/res/layout/redaction_interstitial.xml
@@ -33,7 +33,7 @@
         android:orientation="vertical">
 
         <TextView
-            android:id="@+id/message"
+            android:id="@+id/sud_layout_description"
             style="@style/SudDescription.Glif"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
diff --git a/res/layout/screen_zoom_preview_1.xml b/res/layout/screen_zoom_preview_1.xml
index b7d2d15..65d27ee 100644
--- a/res/layout/screen_zoom_preview_1.xml
+++ b/res/layout/screen_zoom_preview_1.xml
@@ -28,7 +28,7 @@
         <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:background="@color/conversation_background"
+            android:background="?android:attr/colorBackgroundFloating"
             android:paddingTop="@dimen/conversation_message_list_padding"
             android:paddingStart="@dimen/conversation_message_list_padding"
             android:paddingEnd="@dimen/conversation_message_list_padding"
diff --git a/res/layout/search_bar.xml b/res/layout/search_bar.xml
index dbd61df..420c965 100644
--- a/res/layout/search_bar.xml
+++ b/res/layout/search_bar.xml
@@ -28,7 +28,7 @@
         android:layout_width="match_parent"
         android:layout_height="@dimen/search_bar_height"
         android:layout_marginStart="-2dp"
-        android:background="?android:attr/selectableItemBackground"
+        android:background="@drawable/search_bar_selected_background"
         android:contentInsetStartWithNavigation="@dimen/search_bar_content_inset"
         android:navigationIcon="@drawable/ic_homepage_search">
         <TextView
diff --git a/res/layout/settings_homepage_container.xml b/res/layout/settings_homepage_container.xml
index c86bccf..856bd80 100644
--- a/res/layout/settings_homepage_container.xml
+++ b/res/layout/settings_homepage_container.xml
@@ -25,7 +25,6 @@
         android:id="@+id/main_content_scrollable_container"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:importantForAccessibility="no"
         app:layout_behavior="com.android.settings.widget.FloatingAppBarScrollingViewBehavior">
 
         <LinearLayout
diff --git a/res/layout/settings_panel.xml b/res/layout/settings_panel.xml
index 3405ef0..0b0b227 100644
--- a/res/layout/settings_panel.xml
+++ b/res/layout/settings_panel.xml
@@ -15,6 +15,5 @@
 -->
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/main_content"
-    android:layout_height="match_parent"
-    android:layout_width="match_parent"
-    android:animateLayoutChanges="true"/>
\ No newline at end of file
+    android:layout_height="wrap_content"
+    android:layout_width="match_parent"/>
\ No newline at end of file
diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml
index 8a6b697..f6f86f0 100644
--- a/res/values-night/colors.xml
+++ b/res/values-night/colors.xml
@@ -15,7 +15,6 @@
 -->
 
 <resources>
-  <color name="switchbar_text_color">@android:color/black</color>
   <color name="switchbar_switch_track_tint">#82000000</color>
   <color name="switchbar_switch_thumb_tint">@android:color/black</color>
   <color name="homepage_accessibility_background">#783BE5</color>
@@ -24,5 +23,6 @@
   <color name="homepage_status_bar_color">#cc000000</color>
   <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>
 </resources>
 
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index be6345b..83269cc 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -164,6 +164,11 @@
         <attr name="textOff" format="reference" />
     </declare-styleable>
 
+    <declare-styleable name="TintDrawable">
+        <attr name="android:tint" />
+        <attr name="android:drawable" />
+    </declare-styleable>
+
     <attr name="twoStateButtonPreferenceStyle" format="reference" />
 
     <attr name="fingerprint_layout_theme" format="reference" />
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 5d681ca..23fe255 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -63,7 +63,6 @@
     <color name="timestamp_text_incoming">#99ffffff</color>
     <color name="message_bubble_incoming">#689f38</color>
     <color name="message_bubble_outgoing">#ffffffff</color>
-    <color name="conversation_background">#eeeeee</color>
     <color name="message_icon_background_incoming">#689f38</color>
     <color name="message_icon_text_incoming">#ffffffff</color>
     <color name="message_icon_background_outgoing">#4285f4</color>
@@ -103,7 +102,7 @@
     <color name="contextual_card_background">@*android:color/background_device_default_light</color>
     <!-- End of dashboard/homepage icon background colors -->
 
-    <color name="switchbar_text_color">@android:color/white</color>
+    <color name="switchbar_background_color">@*android:color/material_grey_600</color>
     <color name="switchbar_switch_track_tint">#BFFFFFFF</color>
     <color name="switchbar_switch_thumb_tint">@android:color/white</color>
 
@@ -140,4 +139,7 @@
     <color name="qr_background_color">#b3ffffff</color> <!-- 70% white transparency -->
     <!-- End of QR code scanner colors -->
 
+    <!-- Search bar background color -->
+    <color name="search_bar_background">@android:color/white</color>
+
 </resources>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1567c75..6e85806 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -485,6 +485,10 @@
     <string name="proxy_url_title">"PAC URL: "</string>
 
     <!-- Radio Info screen. Label for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
+    <string name="radio_info_subid">Current subId:</string>
+    <!-- Radio Info screen. Label for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
+    <string name="radio_info_dds">SubId of default data SIM:</string>
+    <!-- Radio Info screen. Label for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
     <string name="radio_info_dl_kbps">DL Bandwidth (kbps):</string>
     <!-- Radio Info screen. Label for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
     <string name="radio_info_ul_kbps">UL Bandwidth (kbps):</string>
@@ -531,6 +535,8 @@
     <!-- Radio Info screen. Label for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
     <string name="radio_info_data_network_type_label">Data Network Type:</string>
     <!-- Radio Info screen. Label for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
+    <string name="phone_index_label">Select phone index</string>
+    <!-- Radio Info screen. Label for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
     <string name="radio_info_set_perferred_label">Set Preferred Network Type:</string>
     <!-- Radio Info screen. Label for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
     <string name="radio_info_ping_hostname_v4">Ping Hostname(www.google.com) IPv4:</string>
@@ -884,9 +890,9 @@
     <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>
-    <!-- Message shown for a toggle which when disabled, allows the user to enroll using a simpler flow for accessibility [CHAR LIMIT=NONE] -->
+    <!-- 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 disabled, allows the user to enroll using a simpler flow for accessibility [CHAR LIMIT=NONE] -->
+    <!-- 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_vision"></string>
     <!-- Button text to cancel enrollment from the introduction [CHAR LIMIT=22] -->
     <string name="security_settings_face_enroll_introduction_cancel">Cancel</string>
@@ -2237,6 +2243,8 @@
     <string name="wifi_carrier_content">Connect via <xliff:g id="name">%1$s</xliff:g></string>
 
     <string name="wifi_scan_always_turnon_message">To improve location accuracy and for other purposes, <xliff:g id="app_name">%1$s</xliff:g> wants to turn on network scanning, even when Wi-Fi is off.\n\nAllow this for all apps that want to scan?</string>
+    <!-- Message to inform user, an unknown app want to enable network scanning.  [CHAR LIMIT=200] -->
+    <string name="wifi_scan_always_turn_on_message_unknown">To improve location accuracy and for other purposes, an unknown app wants to turn on network scanning, even when Wi\u2011Fi is off.\n\nAllow this for all apps that want to scan?</string>
     <!-- Message informing the user how to turn off  [CHAR LIMIT=200] -->
     <string name="wifi_scan_always_turnoff_message">To turn this off, go to Advanced in the overflow menu.</string>
     <string name="wifi_scan_always_confirm_allow">Allow</string>
@@ -2783,7 +2791,7 @@
     <!-- Display settings screen, display white balance settings title [CHAR LIMIT=30] -->
     <string name="display_white_balance_title">Display white balance</string>
     <!-- Display settings screen, setting option name to enable adaptive sleep [CHAR LIMIT=30] -->
-    <string name="adaptive_sleep_title">Screen aware</string>
+    <string name="adaptive_sleep_title">Screen attention</string>
     <!-- Setting option summary when adaptive sleep is on [CHAR LIMIT=NONE] -->
     <string name="adaptive_sleep_summary_on">On / Screen won’t turn off if you’re looking at it</string>
     <!-- Setting option summary when adaptive sleep is off [CHAR LIMIT=NONE] -->
@@ -2791,7 +2799,7 @@
     <!-- Description about the feature adaptive sleep [CHAR LIMIT=NONE]-->
     <string name="adaptive_sleep_description">Prevents your screen from turning off if you’re looking at it.</string>
     <!-- Description feature's privacy sensitive details to make sure users understand what feature users, what it saves/sends etc [CHAR LIMIT=NONE]-->
-    <string name="adaptive_sleep_privacy">Screen aware uses the front camera to see if someone is looking at the screen. It works on device, and images are never stored or sent to Google.</string>
+    <string name="adaptive_sleep_privacy">Screen attention uses the front camera to see if someone is looking at the screen. It works on device, and images are never stored or sent to Google.</string>
 
 
     <!-- Night display screen, setting option name to enable night display (renamed "Night Light" with title caps). [CHAR LIMIT=30] -->
@@ -5321,11 +5329,11 @@
     <!-- Summary for the battery high usage tip, which presents battery may run out earlier [CHAR LIMIT=NONE] -->
     <string name="battery_tip_high_usage_summary">Battery may run out earlier than usual</string>
     <!-- Message for battery tip dialog to show the status about the battery [CHAR LIMIT=NONE] -->
-    <string name="battery_tip_dialog_message" product="default">Your phone has been used more than usual. Your battery may run out sooner than expected.\n\nMost used apps since full charge:</string>
+    <string name="battery_tip_dialog_message" product="default">Your phone has been used more than usual. Your battery may run out sooner than expected.\n\nTop apps by battery usage:</string>
     <!-- Message for battery tip dialog to show the status about the battery [CHAR LIMIT=NONE] -->
-    <string name="battery_tip_dialog_message" product="tablet">Your tablet has been used more than usual. Your battery may run out sooner than expected.\n\nMost used apps since full charge:</string>
+    <string name="battery_tip_dialog_message" product="tablet">Your tablet has been used more than usual. Your battery may run out sooner than expected.\n\nTop apps by battery usage:</string>
     <!-- Message for battery tip dialog to show the status about the battery [CHAR LIMIT=NONE] -->
-    <string name="battery_tip_dialog_message" product="device">Your device has been used more than usual. Your battery may run out sooner than expected.\n\nMost used apps since full charge:</string>
+    <string name="battery_tip_dialog_message" product="device">Your device has been used more than usual. Your battery may run out sooner than expected.\n\nTop apps by battery usage:</string>
     <!-- Footer message for battery tip dialog to show the status about the battery [CHAR LIMIT=NONE] -->
     <string name="battery_tip_dialog_message_footer">Includes high-power background activity</string>
     <!-- Title for restricted app preference, showing how many app need to be restricted [CHAR LIMIT=NONE] -->
@@ -9892,17 +9900,14 @@
     <string name="demo_mode">System UI demo mode</string>
 
     <!-- [CHAR LIMIT=60] Name of setting that changes the UI to dark -->
-    <string name="dark_ui_mode">Theme</string>
-
-    <!-- [CHAR LIMIT=60] Name of dev option that changes the color of the UI -->
-    <string name="dark_ui_mode_title">Choose Theme</string>
-
-    <!-- [CHAR_LIMIT=NONE] Summary that is shown in the footer when light mode is selected -->
-    <string name="dark_ui_settings_light_summary">This setting also applies to apps</string>
+    <string name="dark_ui_mode">Dark Theme</string>
 
     <!-- [CHAR_LIMIT=NONE] Summary that is shown in the footer when dark mode is selected -->
     <string name="dark_ui_settings_dark_summary">Supported apps will also switch to dark theme</string>
 
+    <!-- [CHAR_LIMIT=40] Positive button text in dark theme notification -->
+    <string name="dark_ui_settings_dialog_acknowledge">Got it</string>
+
     <!-- [CHAR LIMIT=60] Name of dev option to enable extra quick settings tiles -->
     <string name="quick_settings_developer_tiles">Quick settings developer tiles</string>
 
@@ -11017,12 +11022,12 @@
     <!-- Message for forget passpoint dialog [CHAR LIMIT=none] -->
     <string name="forget_passpoint_dialog_message">You may lose access to any remaining time or data. Check with your provider before removing.</string>
 
-    <!-- Keywords for Content Capture / Smart Suggestions feature [CHAR_LIMIT=none] -->
-    <string name="keywords_content_capture">content capture, smart suggestions</string>
+    <!-- Keywords for Content Capture feature [CHAR_LIMIT=none] -->
+    <string name="keywords_content_capture">content capture</string>
     <!-- Title of the 'Content Capture' feature toggle in the Settings -> Privacy screen [CHAR LIMIT=none]-->
-    <string name="content_capture">Smart Suggestions</string>
-    <!-- Description of the 'Content Capture / Smart Suggestions' feature toggle in the Settings -> Privacy screen [CHAR LIMIT=NONE]-->
-    <string name="content_capture_summary">Allow Android to save information seen on your screen or heard in video or audio content. Android makes helpful suggestions based on your device activity.</string>
+    <string name="content_capture">Content Capture</string>
+    <!-- Description of the 'Content Capture' feature toggle in the Settings -> Privacy screen [CHAR LIMIT=NONE]-->
+    <string name="content_capture_summary">Allow apps to send content to the Android system</string>
 
     <!-- Title for the button to initiate a heap dump for the system server. [CHAR LIMIT=NONE] -->
     <string name="capture_system_heap_dump_title">Capture system heap dump</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index b51a45d..9a02fcd 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -422,6 +422,7 @@
         <item name="cardElevation">0dp</item>
         <item name="strokeColor">@color/contextual_card_stroke_color</item>
         <item name="strokeWidth">1dp</item>
+        <item name="rippleColor">?android:attr/colorControlHighlight</item>
     </style>
 
     <style name="SearchBarStyle">
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 196e85b..5db5f2f 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -87,10 +87,10 @@
         <item name="android:backgroundDimEnabled">false</item>
     </style>
 
-    <style name="ThemeOverlay.SwitchBar.Settings" parent="@android:style/ThemeOverlay.Material.ActionBar">
+    <style name="ThemeOverlay.SwitchBar.Settings" parent="@*android:style/ThemeOverlay.DeviceDefault.ActionBar">
         <item name="switchBarMarginStart">@dimen/switchbar_subsettings_margin_start</item>
         <item name="switchBarMarginEnd">@dimen/switchbar_subsettings_margin_end</item>
-        <item name="switchBarBackgroundColor">?android:attr/textColorSecondary</item>
+        <item name="switchBarBackgroundColor">@color/switchbar_background_color</item>
         <item name="switchBarBackgroundActivatedColor">?android:attr/colorAccent</item>
         <item name="switchBarRestrictionIcon">@*android:drawable/ic_info</item>
     </style>
@@ -203,7 +203,7 @@
 
     <!-- Note that Dialog themes do not set list dividers -->
     <style name="Theme.BottomDialog" parent="@*android:style/Theme.DeviceDefault.Settings.Dialog">
-        <item name="android:windowBackground">@drawable/settings_panel_background</item>
+        <item name="android:windowBackground">@null</item>
         <item name="android:dividerHorizontal">@*android:drawable/list_divider_material</item>
         <item name="android:windowNoTitle">true</item>
         <item name="android:listDivider">@*android:drawable/list_divider_material</item>
diff --git a/res/values/themes_suw.xml b/res/values/themes_suw.xml
index 9bb67cf..add2fed 100644
--- a/res/values/themes_suw.xml
+++ b/res/values/themes_suw.xml
@@ -191,12 +191,20 @@
     </style>
 
     <style name="SuwAlertDialogThemeCompat" parent="@style/Theme.AppCompat.Dialog.Alert">
+        <!-- Referenced SudThemeGlifV3 style -->
+        <item name="android:textAllCaps">false</item>
+
+        <item name="android:windowSoftInputMode">adjustResize</item>
         <!-- copied from Theme.DeviceDefault.Light.Dialog.Alert -->
         <item name="colorAccent">@*android:color/accent_device_default_light</item>
         <item name="dialogCornerRadius">@*android:dimen/config_dialogCornerRadius</item>
     </style>
 
     <style name="SuwAlertDialogThemeCompat.Light" parent="@style/Theme.AppCompat.Light.Dialog.Alert">
+        <!-- Referenced SudThemeGlifV3.Light style -->
+        <item name="android:textAllCaps">false</item>
+
+        <item name="android:windowSoftInputMode">adjustResize</item>
         <!-- copied from Theme.DeviceDefault.Light.Dialog.Alert -->
         <item name="colorAccent">@*android:color/accent_device_default_light</item>
         <item name="dialogCornerRadius">@*android:dimen/config_dialogCornerRadius</item>
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index 26849d1..b4968f8 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -58,11 +58,10 @@
             android:title="@string/screen_zoom_title"
             settings:searchable="false"/>
 
-        <Preference
+        <SwitchPreference
             android:key="dark_ui_mode_accessibility"
-            android:fragment="com.android.settings.display.DarkUISettings"
             android:title="@string/dark_ui_mode"
-            settings:searchable="false" />
+            settings:searchable="false"/>
 
         <Preference
             android:fragment="com.android.settings.accessibility.MagnificationPreferenceFragment"
diff --git a/res/xml/display_settings.xml b/res/xml/display_settings.xml
index a612a47..bcd5100 100644
--- a/res/xml/display_settings.xml
+++ b/res/xml/display_settings.xml
@@ -56,11 +56,10 @@
     </com.android.settingslib.RestrictedPreference>
 
 
-    <Preference
+    <SwitchPreference
         android:key="dark_ui_mode"
-        android:fragment="com.android.settings.display.DarkUISettings"
         android:title="@string/dark_ui_mode"
-        settings:searchable="false"
+        settings:keywords="@string/keywords_dark_ui_mode"
         settings:controller="com.android.settings.display.DarkUIPreferenceController"/>
 
     <!-- Cross-listed item, if you change this, also change it in power_usage_summary.xml -->
diff --git a/res/xml/sound_settings.xml b/res/xml/sound_settings.xml
index e610df2..d99cc00 100644
--- a/res/xml/sound_settings.xml
+++ b/res/xml/sound_settings.xml
@@ -103,7 +103,7 @@
         settings:useAdminDisabledSummary="true"
         settings:keywords="@string/keywords_sounds_and_notifications_interruptions"
         settings:allowDividerAbove="true"
-        settings:controller="com.android.settings.notification.ZenModeSoundSettingsPreferenceController"/>
+        settings:controller="com.android.settings.notification.ZenModePreferenceController"/>
 
     <Preference
         android:key="gesture_prevent_ringing_sound"
diff --git a/res/xml/zen_mode_settings.xml b/res/xml/zen_mode_settings.xml
index 832150a..320a37c 100644
--- a/res/xml/zen_mode_settings.xml
+++ b/res/xml/zen_mode_settings.xml
@@ -20,7 +20,7 @@
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:key="zen_mode_settings"
     android:title="@string/zen_mode_settings_title"
-    settings:keywords="@string/keywords_zen_mode_settings">
+    settings:searchable="false">
 
     <PreferenceCategory
         android:key="zen_mode_settings_category_behavior"
@@ -66,11 +66,13 @@
 
     <!-- Turn on DND button -->
     <com.android.settingslib.widget.LayoutPreference
-        android:key="zen_mode_settings_button_container"
+        android:key="zen_mode_toggle"
+        android:title="@string/zen_mode_settings_title"
         android:selectable="false"
         android:layout="@layout/zen_mode_settings_button"
         settings:allowDividerAbove="true"
-        settings:allowDividerBelow="true"/>
+        settings:allowDividerBelow="true"
+        settings:keywords="@string/keywords_zen_mode_settings"/>
 
     <!-- Footer that shows if user is put into alarms only or total silence mode by an app -->
     <com.android.settingslib.widget.FooterPreference/>
diff --git a/src/com/android/settings/DisplaySettings.java b/src/com/android/settings/DisplaySettings.java
index b67e6e8..eb77d4a 100644
--- a/src/com/android/settings/DisplaySettings.java
+++ b/src/com/android/settings/DisplaySettings.java
@@ -18,11 +18,13 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.Context;
+import android.os.Bundle;
 import android.provider.SearchIndexableResource;
 
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.display.BrightnessLevelPreferenceController;
 import com.android.settings.display.CameraGesturePreferenceController;
+import com.android.settings.display.DarkUIPreferenceController;
 import com.android.settings.display.LiftToWakePreferenceController;
 import com.android.settings.display.NightDisplayPreferenceController;
 import com.android.settings.display.NightModePreferenceController;
@@ -63,6 +65,12 @@
     }
 
     @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        use(DarkUIPreferenceController.class).setParentFragment(this);
+    }
+
+    @Override
     protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
         return buildPreferenceControllers(context, getSettingsLifecycle());
     }
diff --git a/src/com/android/settings/EncryptionInterstitial.java b/src/com/android/settings/EncryptionInterstitial.java
index 317e3bd..515b1b0 100644
--- a/src/com/android/settings/EncryptionInterstitial.java
+++ b/src/com/android/settings/EncryptionInterstitial.java
@@ -141,7 +141,7 @@
                             R.string.encryption_interstitial_message_password;
                     break;
             }
-            TextView message = (TextView) getActivity().findViewById(R.id.encryption_message);
+            TextView message = (TextView) getActivity().findViewById(R.id.sud_layout_description);
             message.setText(msgId);
 
             setRequirePasswordState(getActivity().getIntent().getBooleanExtra(
diff --git a/src/com/android/settings/MasterClearConfirm.java b/src/com/android/settings/MasterClearConfirm.java
index ac97c11..a8c4341 100644
--- a/src/com/android/settings/MasterClearConfirm.java
+++ b/src/com/android/settings/MasterClearConfirm.java
@@ -207,7 +207,7 @@
 
     private void setAccessibilityTitle() {
         CharSequence currentTitle = getActivity().getTitle();
-        TextView confirmationMessage = mContentView.findViewById(R.id.master_clear_confirm);
+        TextView confirmationMessage = mContentView.findViewById(R.id.sud_layout_description);
         if (confirmationMessage != null) {
             String accessibleText = new StringBuilder(currentTitle).append(",").append(
                     confirmationMessage.getText()).toString();
@@ -218,7 +218,7 @@
     @VisibleForTesting
     void setSubtitle() {
         if (mEraseEsims) {
-            ((TextView) mContentView.findViewById(R.id.master_clear_confirm))
+            ((TextView) mContentView.findViewById(R.id.sud_layout_description))
                 .setText(R.string.master_clear_final_desc_esim);
         }
     }
diff --git a/src/com/android/settings/RadioInfo.java b/src/com/android/settings/RadioInfo.java
index 0b7d1be..e0ce1c0 100644
--- a/src/com/android/settings/RadioInfo.java
+++ b/src/com/android/settings/RadioInfo.java
@@ -125,6 +125,7 @@
             "Unknown"
     };
 
+    private static String[] mPhoneIndexLabels;
 
     private static final int CELL_INFO_LIST_RATE_DISABLED = Integer.MAX_VALUE;
     private static final int CELL_INFO_LIST_RATE_MAX = 0;
@@ -160,7 +161,7 @@
         60000
     };
 
-    private void log(String s) {
+    private static void log(String s) {
         Log.d(TAG, s);
     }
 
@@ -171,15 +172,17 @@
     private static final int EVENT_QUERY_SMSC_DONE = 1005;
     private static final int EVENT_UPDATE_SMSC_DONE = 1006;
 
-    private static final int MENU_ITEM_SELECT_BAND  = 0;
-    private static final int MENU_ITEM_VIEW_ADN     = 1;
-    private static final int MENU_ITEM_VIEW_FDN     = 2;
-    private static final int MENU_ITEM_VIEW_SDN     = 3;
-    private static final int MENU_ITEM_GET_IMS_STATUS = 4;
-    private static final int MENU_ITEM_TOGGLE_DATA  = 5;
+    private static final int MENU_ITEM_SELECT_BAND         = 0;
+    private static final int MENU_ITEM_VIEW_ADN            = 1;
+    private static final int MENU_ITEM_VIEW_FDN            = 2;
+    private static final int MENU_ITEM_VIEW_SDN            = 3;
+    private static final int MENU_ITEM_GET_IMS_STATUS      = 4;
+    private static final int MENU_ITEM_TOGGLE_DATA         = 5;
 
     private TextView mDeviceId; //DeviceId is the IMEI in GSM and the MEID in CDMA
     private TextView number;
+    private TextView mSubscriptionId;
+    private TextView mDds;
     private TextView mSubscriberId;
     private TextView callState;
     private TextView operatorName;
@@ -219,12 +222,13 @@
     private Switch cbrsDataSwitch;
     private Switch dsdsSwitch;
     private Spinner preferredNetworkType;
+    private Spinner mSelectPhoneIndex;
     private Spinner cellInfoRefreshRateSpinner;
 
     private ConnectivityManager mConnectivityManager;
     private TelephonyManager mTelephonyManager;
     private ImsManager mImsManager = null;
-    private Phone phone = null;
+    private Phone mPhone = null;
 
     private String mPingHostnameResultV4;
     private String mPingHostnameResultV6;
@@ -237,6 +241,7 @@
 
     private int mPreferredNetworkTypeResult;
     private int mCellInfoRefreshRateIndex;
+    private int mSelectedPhoneIndex;
 
     private final NetworkRequest mDefaultNetworkRequest = new NetworkRequest.Builder()
             .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
@@ -251,7 +256,9 @@
         }
     };
 
-    private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+    // not final because we need to recreate this object to register on a new subId (b/117555407)
+    private PhoneStateListener mPhoneStateListener = new RadioInfoPhoneStateListener();
+    private class RadioInfoPhoneStateListener extends PhoneStateListener {
         @Override
         public void onDataConnectionStateChanged(int state) {
             updateDataState();
@@ -319,7 +326,7 @@
             updatePhysicalChannelConfiguration(configs);
         }
 
-    };
+    }
 
     private void updatePhysicalChannelConfiguration(List<PhysicalChannelConfig> configs) {
             StringBuilder sb = new StringBuilder();
@@ -346,6 +353,21 @@
         preferredNetworkType.setSelection(mPreferredNetworkTypeResult, true);
     }
 
+    private void updatePhoneIndex(int phoneIndex, int subId) {
+        // unregister listeners on the old subId
+        unregisterPhoneStateListener();
+        mTelephonyManager.setCellInfoListRate(CELL_INFO_LIST_RATE_DISABLED);
+
+        // update the subId
+        mTelephonyManager = mTelephonyManager.createForSubscriptionId(subId);
+
+        // update the phoneId
+        mImsManager = ImsManager.getInstance(getApplicationContext(), phoneIndex);
+        mPhone = PhoneFactory.getPhone(phoneIndex);
+
+        updateAllFields();
+    }
+
     private Handler mHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
@@ -404,15 +426,17 @@
 
         mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
         mConnectivityManager = (ConnectivityManager)getSystemService(CONNECTIVITY_SERVICE);
-        phone = PhoneFactory.getDefaultPhone();
+        mPhone = PhoneFactory.getDefaultPhone();
 
-        //TODO: Need to update this if the default phoneId changes?
-        //      Better to have an instance per phone?
         mImsManager = ImsManager.getInstance(getApplicationContext(),
                 SubscriptionManager.getDefaultVoicePhoneId());
 
+        mPhoneIndexLabels = getPhoneIndexLabels(mTelephonyManager);
+
         mDeviceId = (TextView) findViewById(R.id.imei);
         number = (TextView) findViewById(R.id.number);
+        mSubscriptionId = (TextView) findViewById(R.id.subid);
+        mDds = (TextView) findViewById(R.id.dds);
         mSubscriberId = (TextView) findViewById(R.id.imsi);
         callState = (TextView) findViewById(R.id.call);
         operatorName = (TextView) findViewById(R.id.operator);
@@ -439,10 +463,17 @@
         mPhyChanConfig = (TextView) findViewById(R.id.phy_chan_config);
 
         preferredNetworkType = (Spinner) findViewById(R.id.preferredNetworkType);
-        ArrayAdapter<String> adapter = new ArrayAdapter<String> (this,
+        ArrayAdapter<String> preferredNetworkTypeAdapter = new ArrayAdapter<String> (this,
                 android.R.layout.simple_spinner_item, mPreferredNetworkLabels);
-        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
-        preferredNetworkType.setAdapter(adapter);
+        preferredNetworkTypeAdapter
+                .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        preferredNetworkType.setAdapter(preferredNetworkTypeAdapter);
+
+        mSelectPhoneIndex = (Spinner) findViewById(R.id.phoneIndex);
+        ArrayAdapter<String> phoneIndexAdapter = new ArrayAdapter<String> (this,
+                android.R.layout.simple_spinner_item, mPhoneIndexLabels);
+        phoneIndexAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        mSelectPhoneIndex.setAdapter(phoneIndexAdapter);
 
         cellInfoRefreshRateSpinner = (Spinner) findViewById(R.id.cell_info_rate_select);
         ArrayAdapter<String> cellInfoAdapter = new ArrayAdapter<String>(this,
@@ -455,7 +486,7 @@
         imsWfcProvisionedSwitch = (Switch) findViewById(R.id.wfc_provisioned_switch);
         eabProvisionedSwitch = (Switch) findViewById(R.id.eab_provisioned_switch);
 
-        if (!ImsManager.isImsSupportedOnDevice(phone.getContext())) {
+        if (!ImsManager.isImsSupportedOnDevice(mPhone.getContext())) {
             imsVolteProvisionedSwitch.setVisibility(View.GONE);
             imsVtProvisionedSwitch.setVisibility(View.GONE);
             imsWfcProvisionedSwitch.setVisibility(View.GONE);
@@ -513,9 +544,10 @@
 
         mCellInfoRefreshRateIndex = 0; //disabled
         mPreferredNetworkTypeResult = mPreferredNetworkLabels.length - 1; //Unknown
+        mSelectedPhoneIndex = 0; //phone 0
 
         //FIXME: Replace with TelephonyManager call
-        phone.getPreferredNetworkType(
+        mPhone.getPreferredNetworkType(
                 mHandler.obtainMessage(EVENT_QUERY_PREFERRED_TYPE_DONE));
 
         restoreFromBundle(icicle);
@@ -527,6 +559,10 @@
 
         log("Started onResume");
 
+        updateAllFields();
+    }
+
+    private void updateAllFields() {
         updateMessageWaiting();
         updateCallRedirect();
         updateDataState();
@@ -539,6 +575,7 @@
 
         updateLocation(mCellLocationResult);
         updateCellInfo(mCellInfoResult);
+        updateSubscriptionIds();
 
         mPingHostnameV4.setText(mPingHostnameResultV4);
         mPingHostnameV6.setText(mPingHostnameResultV6);
@@ -552,6 +589,10 @@
         preferredNetworkType.setSelection(mPreferredNetworkTypeResult, true);
         preferredNetworkType.setOnItemSelectedListener(mPreferredNetworkHandler);
 
+        // set phone index
+        mSelectPhoneIndex.setSelection(mSelectedPhoneIndex, true);
+        mSelectPhoneIndex.setOnItemSelectedListener(mSelectPhoneIndexHandler);
+
         radioPowerOnSwitch.setOnCheckedChangeListener(mRadioPowerOnChangeListener);
         imsVolteProvisionedSwitch.setOnCheckedChangeListener(mImsVolteCheckedChangeListener);
         imsVtProvisionedSwitch.setOnCheckedChangeListener(mImsVtCheckedChangeListener);
@@ -563,19 +604,8 @@
             cbrsDataSwitch.setOnCheckedChangeListener(mCbrsDataSwitchChangeListener);
         }
 
-        mTelephonyManager.listen(mPhoneStateListener,
-                  PhoneStateListener.LISTEN_CALL_STATE
-        //b/27803938 - RadioInfo currently cannot read PRECISE_CALL_STATE
-        //      | PhoneStateListener.LISTEN_PRECISE_CALL_STATE
-                | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
-                | PhoneStateListener.LISTEN_DATA_ACTIVITY
-                | PhoneStateListener.LISTEN_CELL_LOCATION
-                | PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
-                | PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR
-                | PhoneStateListener.LISTEN_CELL_INFO
-                | PhoneStateListener.LISTEN_SERVICE_STATE
-                | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
-                | PhoneStateListener.LISTEN_PHYSICAL_CHANNEL_CONFIGURATION);
+        unregisterPhoneStateListener();
+        registerPhoneStateListener();
 
         mConnectivityManager.registerNetworkCallback(
                 mDefaultNetworkRequest, mNetworkCallback, mHandler);
@@ -611,6 +641,8 @@
         mPreferredNetworkTypeResult = b.getInt("mPreferredNetworkTypeResult",
                                                mPreferredNetworkLabels.length - 1);
 
+        mSelectedPhoneIndex = b.getInt("mSelectedPhoneIndex", 0);
+
         mCellInfoRefreshRateIndex = b.getInt("mCellInfoRefreshRateIndex", 0);
     }
 
@@ -621,6 +653,7 @@
         outState.putString("mHttpClientTestResult", mHttpClientTestResult);
 
         outState.putInt("mPreferredNetworkTypeResult", mPreferredNetworkTypeResult);
+        outState.putInt("mSelectedPhoneIndex", mSelectedPhoneIndex);
         outState.putInt("mCellInfoRefreshRateIndex", mCellInfoRefreshRateIndex);
 
     }
@@ -636,7 +669,7 @@
                 R.string.radioInfo_menu_viewFDN).setOnMenuItemClickListener(mViewFDNCallback);
         menu.add(1, MENU_ITEM_VIEW_SDN, 0,
                 R.string.radioInfo_menu_viewSDN).setOnMenuItemClickListener(mViewSDNCallback);
-        if (ImsManager.isImsSupportedOnDevice(phone.getContext())) {
+        if (ImsManager.isImsSupportedOnDevice(mPhone.getContext())) {
             menu.add(1, MENU_ITEM_GET_IMS_STATUS,
                     0, R.string.radioInfo_menu_getIMS).setOnMenuItemClickListener(mGetImsStatus);
         }
@@ -668,9 +701,61 @@
         return true;
     }
 
+    // returns array of string labels for each phone index. The array index is equal to the phone
+    // index.
+    private static String[] getPhoneIndexLabels(TelephonyManager tm) {
+        int phones = tm.getPhoneCount();
+        String[] labels = new String[phones];
+        for (int i = 0; i < phones; i++) {
+            labels[i] = "Phone " + i;
+        }
+        return labels;
+    }
+
+    private void unregisterPhoneStateListener() {
+        mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
+
+        // clear all fields so they are blank until the next listener event occurs
+        operatorName.setText("");
+        gprsState.setText("");
+        dataNetwork.setText("");
+        voiceNetwork.setText("");
+        sent.setText("");
+        received.setText("");
+        callState.setText("");
+        mLocation.setText("");
+        mMwiValue = false;
+        mMwi.setText("");
+        mCfiValue = false;
+        mCfi.setText("");
+        mCellInfo.setText("");
+        dBm.setText("");
+        gsmState.setText("");
+        roamingState.setText("");
+        mPhyChanConfig.setText("");
+    }
+
+    // register mPhoneStateListener for relevant fields using the current TelephonyManager
+    private void registerPhoneStateListener() {
+        mPhoneStateListener = new RadioInfoPhoneStateListener();
+        mTelephonyManager.listen(mPhoneStateListener,
+                  PhoneStateListener.LISTEN_CALL_STATE
+        //b/27803938 - RadioInfo currently cannot read PRECISE_CALL_STATE
+        //      | PhoneStateListener.LISTEN_PRECISE_CALL_STATE
+                | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
+                | PhoneStateListener.LISTEN_DATA_ACTIVITY
+                | PhoneStateListener.LISTEN_CELL_LOCATION
+                | PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
+                | PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR
+                | PhoneStateListener.LISTEN_CELL_INFO
+                | PhoneStateListener.LISTEN_SERVICE_STATE
+                | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
+                | PhoneStateListener.LISTEN_PHYSICAL_CHANNEL_CONFIGURATION);
+    }
+
     private void updateDnsCheckState() {
         //FIXME: Replace with a TelephonyManager call
-        dnsCheckState.setText(phone.isDnsCheckDisabled() ?
+        dnsCheckState.setText(mPhone.isDnsCheckDisabled() ?
                 "0.0.0.0 allowed" :"0.0.0.0 not allowed");
     }
 
@@ -889,6 +974,11 @@
         mCellInfo.setText(buildCellInfoString(arrayCi));
     }
 
+    private final void updateSubscriptionIds() {
+        mSubscriptionId.setText(Integer.toString(mPhone.getSubId()));
+        mDds.setText(Integer.toString(SubscriptionManager.getDefaultDataSubscriptionId()));
+    }
+
     private final void
     updateMessageWaiting() {
         mMwi.setText(String.valueOf(mMwiValue));
@@ -975,12 +1065,12 @@
     }
 
     private final void updateNetworkType() {
-        if(phone != null) {
-            ServiceState ss = phone.getServiceState();
+        if(mPhone != null) {
+            ServiceState ss = mPhone.getServiceState();
             dataNetwork.setText(ServiceState.rilRadioTechnologyToString(
-                    phone.getServiceState().getRilDataRadioTechnology()));
+                    mPhone.getServiceState().getRilDataRadioTechnology()));
             voiceNetwork.setText(ServiceState.rilRadioTechnologyToString(
-                    phone.getServiceState().getRilVoiceRadioTechnology()));
+                    mPhone.getServiceState().getRilVoiceRadioTechnology()));
         }
     }
 
@@ -989,16 +1079,16 @@
         String s;
         Resources r = getResources();
 
-        s = phone.getDeviceId();
+        s = mPhone.getDeviceId();
         if (s == null) s = r.getString(R.string.radioInfo_unknown);
         mDeviceId.setText(s);
 
-        s = phone.getSubscriberId();
+        s = mPhone.getSubscriberId();
         if (s == null) s = r.getString(R.string.radioInfo_unknown);
         mSubscriberId.setText(s);
 
         //FIXME: Replace with a TelephonyManager call
-        s = phone.getLine1Number();
+        s = mPhone.getLine1Number();
         if (s == null) s = r.getString(R.string.radioInfo_unknown);
         number.setText(s);
     }
@@ -1075,7 +1165,7 @@
 
     private void refreshSmsc() {
         //FIXME: Replace with a TelephonyManager call
-        phone.getSmscAddress(mHandler.obtainMessage(EVENT_QUERY_SMSC_DONE));
+        mPhone.getSmscAddress(mHandler.obtainMessage(EVENT_QUERY_SMSC_DONE));
     }
 
     private final void updateAllCellInfo() {
@@ -1147,8 +1237,7 @@
             // the content provider, which causes it to be loaded in a process
             // other than the Dialer process, which causes a lot of stuff to
             // break.
-            intent.setClassName("com.android.phone",
-                    "com.android.phone.SimContacts");
+            intent.setClassName("com.android.phone", "com.android.phone.SimContacts");
             startActivity(intent);
             return true;
         }
@@ -1162,8 +1251,7 @@
             // the content provider, which causes it to be loaded in a process
             // other than the Dialer process, which causes a lot of stuff to
             // break.
-            intent.setClassName("com.android.phone",
-                    "com.android.phone.settings.fdn.FdnList");
+            intent.setClassName("com.android.phone", "com.android.phone.settings.fdn.FdnList");
             startActivity(intent);
             return true;
         }
@@ -1178,8 +1266,7 @@
             // the content provider, which causes it to be loaded in a process
             // other than the Dialer process, which causes a lot of stuff to
             // break.
-            intent.setClassName("com.android.phone",
-                    "com.android.phone.ADNList");
+            intent.setClassName("com.android.phone", "com.android.phone.ADNList");
             startActivity(intent);
             return true;
         }
@@ -1187,11 +1274,11 @@
 
     private MenuItem.OnMenuItemClickListener mGetImsStatus = new MenuItem.OnMenuItemClickListener() {
         public boolean onMenuItemClick(MenuItem item) {
-            boolean isImsRegistered = phone.isImsRegistered();
-            boolean availableVolte = phone.isVolteEnabled();
-            boolean availableWfc = phone.isWifiCallingEnabled();
-            boolean availableVt = phone.isVideoEnabled();
-            boolean availableUt = phone.isUtEnabled();
+            boolean isImsRegistered = mPhone.isImsRegistered();
+            boolean availableVolte = mPhone.isVolteEnabled();
+            boolean availableWfc = mPhone.isWifiCallingEnabled();
+            boolean availableVt = mPhone.isVideoEnabled();
+            boolean availableUt = mPhone.isUtEnabled();
 
             final String imsRegString = isImsRegistered ?
                 getString(R.string.radio_info_ims_reg_status_registered) :
@@ -1248,7 +1335,7 @@
 
     private boolean isRadioOn() {
         //FIXME: Replace with a TelephonyManager call
-        return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
+        return mPhone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
     }
 
     private void updateRadioPowerState() {
@@ -1280,7 +1367,7 @@
     }
 
     void setImsConfigProvisionedState(int configItem, boolean state) {
-        if (phone != null && mImsManager != null) {
+        if (mPhone != null && mImsManager != null) {
             QueuedWork.queue(new Runnable() {
                 public void run() {
                     try {
@@ -1299,14 +1386,14 @@
         @Override
         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
             log("toggle radio power: currently " + (isRadioOn()?"on":"off"));
-            phone.setRadioPower(isChecked);
+            mPhone.setRadioPower(isChecked);
        }
     };
 
     private boolean isImsVolteProvisioned() {
-        if (phone != null && mImsManager != null) {
-            return mImsManager.isVolteEnabledByPlatform(phone.getContext())
-                && mImsManager.isVolteProvisionedOnDevice(phone.getContext());
+        if (mPhone != null && mImsManager != null) {
+            return mImsManager.isVolteEnabledByPlatform(mPhone.getContext())
+                && mImsManager.isVolteProvisionedOnDevice(mPhone.getContext());
         }
         return false;
     }
@@ -1319,9 +1406,9 @@
     };
 
     private boolean isImsVtProvisioned() {
-        if (phone != null && mImsManager != null) {
-            return mImsManager.isVtEnabledByPlatform(phone.getContext())
-                && mImsManager.isVtProvisionedOnDevice(phone.getContext());
+        if (mPhone != null && mImsManager != null) {
+            return mImsManager.isVtEnabledByPlatform(mPhone.getContext())
+                && mImsManager.isVtProvisionedOnDevice(mPhone.getContext());
         }
         return false;
     }
@@ -1334,9 +1421,9 @@
     };
 
     private boolean isImsWfcProvisioned() {
-        if (phone != null && mImsManager != null) {
-            return mImsManager.isWfcEnabledByPlatform(phone.getContext())
-                && mImsManager.isWfcProvisionedOnDevice(phone.getContext());
+        if (mPhone != null && mImsManager != null) {
+            return mImsManager.isWfcEnabledByPlatform(mPhone.getContext())
+                && mImsManager.isWfcProvisionedOnDevice(mPhone.getContext());
         }
         return false;
     }
@@ -1391,7 +1478,7 @@
     }
 
     private void updateImsProvisionedState() {
-        if (!ImsManager.isImsSupportedOnDevice(phone.getContext())) {
+        if (!ImsManager.isImsSupportedOnDevice(mPhone.getContext())) {
             return;
         }
         log("updateImsProvisionedState isImsVolteProvisioned()=" + isImsVolteProvisioned());
@@ -1401,31 +1488,31 @@
         imsVolteProvisionedSwitch.setChecked(isImsVolteProvisioned());
         imsVolteProvisionedSwitch.setOnCheckedChangeListener(mImsVolteCheckedChangeListener);
         imsVolteProvisionedSwitch.setEnabled(!Build.IS_USER
-                && mImsManager.isVolteEnabledByPlatform(phone.getContext()));
+                && mImsManager.isVolteEnabledByPlatform(mPhone.getContext()));
 
         imsVtProvisionedSwitch.setOnCheckedChangeListener(null);
         imsVtProvisionedSwitch.setChecked(isImsVtProvisioned());
         imsVtProvisionedSwitch.setOnCheckedChangeListener(mImsVtCheckedChangeListener);
         imsVtProvisionedSwitch.setEnabled(!Build.IS_USER
-                && mImsManager.isVtEnabledByPlatform(phone.getContext()));
+                && mImsManager.isVtEnabledByPlatform(mPhone.getContext()));
 
         imsWfcProvisionedSwitch.setOnCheckedChangeListener(null);
         imsWfcProvisionedSwitch.setChecked(isImsWfcProvisioned());
         imsWfcProvisionedSwitch.setOnCheckedChangeListener(mImsWfcCheckedChangeListener);
         imsWfcProvisionedSwitch.setEnabled(!Build.IS_USER
-                && mImsManager.isWfcEnabledByPlatform(phone.getContext()));
+                && mImsManager.isWfcEnabledByPlatform(mPhone.getContext()));
 
         eabProvisionedSwitch.setOnCheckedChangeListener(null);
         eabProvisionedSwitch.setChecked(isEabProvisioned());
         eabProvisionedSwitch.setOnCheckedChangeListener(mEabCheckedChangeListener);
         eabProvisionedSwitch.setEnabled(!Build.IS_USER
-                && isEabEnabledByPlatform(phone.getContext()));
+                && isEabEnabledByPlatform(mPhone.getContext()));
     }
 
     OnClickListener mDnsCheckButtonHandler = new OnClickListener() {
         public void onClick(View v) {
             //FIXME: Replace with a TelephonyManager call
-            phone.disableDnsCheck(!phone.isDnsCheckDisabled());
+            mPhone.disableDnsCheck(!mPhone.isDnsCheckDisabled());
             updateDnsCheckState();
         }
     };
@@ -1452,7 +1539,7 @@
     OnClickListener mUpdateSmscButtonHandler = new OnClickListener() {
         public void onClick(View v) {
             updateSmscButton.setEnabled(false);
-            phone.setSmscAddress(smsc.getText().toString(),
+            mPhone.setSmscAddress(smsc.getText().toString(),
                     mHandler.obtainMessage(EVENT_UPDATE_SMSC_DONE));
         }
     };
@@ -1497,14 +1584,40 @@
                 // want this setting to be set, so that if the radio hiccups and this setting
                 // is for some reason unsuccessful, future calls to the radio will reflect
                 // the users's preference which is set here.
-                final int subId = phone.getSubId();
+                final int subId = mPhone.getSubId();
                 if (SubscriptionManager.isUsableSubIdValue(subId)) {
-                    Settings.Global.putInt(phone.getContext().getContentResolver(),
+                    Settings.Global.putInt(mPhone.getContext().getContentResolver(),
                             PREFERRED_NETWORK_MODE + subId, mPreferredNetworkTypeResult);
                 }
                 log("Calling setPreferredNetworkType(" + mPreferredNetworkTypeResult + ")");
                 Message msg = mHandler.obtainMessage(EVENT_SET_PREFERRED_TYPE_DONE);
-                phone.setPreferredNetworkType(mPreferredNetworkTypeResult, msg);
+                mPhone.setPreferredNetworkType(mPreferredNetworkTypeResult, msg);
+            }
+        }
+
+        public void onNothingSelected(AdapterView parent) {
+        }
+    };
+
+    AdapterView.OnItemSelectedListener mSelectPhoneIndexHandler =
+            new AdapterView.OnItemSelectedListener() {
+
+        public void onItemSelected(AdapterView parent, View v, int pos, long id) {
+            if (pos >= 0 && pos <= mPhoneIndexLabels.length - 1) {
+                // the array position is equal to the phone index
+                int phoneIndex = pos;
+                Phone[] phones = PhoneFactory.getPhones();
+                if (phones == null || phones.length <= phoneIndex) {
+                    return;
+                }
+                // getSubId says it takes a slotIndex, but it actually takes a phone index
+                int[] subIds = SubscriptionManager.getSubId(phoneIndex);
+                if (subIds == null || subIds.length < 1) {
+                    return;
+                }
+                mSelectedPhoneIndex = phoneIndex;
+
+                updatePhoneIndex(phoneIndex, subIds[0]);
             }
         }
 
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index d34dfeb..8077ee3 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -639,12 +639,7 @@
                 showDev, isAdmin)
                 || somethingChanged;
 
-        // For profiles, we want them to be included in the profile select dialog even if
-        // backup is not activated.
-        // For other users, enable/disable backup settings depending on whether backup is activated
-        // for the user.
-        boolean enableBackupTile = um.isManagedProfile()
-                || new BackupSettingsHelper(this).isBackupServiceActive();
+        boolean enableBackupTile = new BackupSettingsHelper(this).showBackupSettingsForUser();
         somethingChanged = setTileEnabled(changedList, new ComponentName(packageName,
                 UserBackupSettingsActivity.class.getName()), enableBackupTile, isAdmin)
                 || somethingChanged;
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index efa14f6..478db9f 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -244,7 +244,7 @@
     private SwitchPreference mToggleInversionPreference;
     private ColorInversionPreferenceController mInversionPreferenceController;
     private AccessibilityHearingAidPreferenceController mHearingAidPreferenceController;
-    private Preference mDarkUIModePreference;
+    private SwitchPreference mDarkUIModePreference;
     private DarkUIPreferenceController mDarkUIPreferenceController;
     private LiveCaptionPreferenceController mLiveCaptionPreferenceController;
 
@@ -524,8 +524,8 @@
         mDarkUIModePreference = findPreference(DARK_UI_MODE_PREFERENCE);
         mDarkUIPreferenceController = new DarkUIPreferenceController(getContext(),
                 DARK_UI_MODE_PREFERENCE);
+        mDarkUIPreferenceController.setParentFragment(this);
         mDarkUIPreferenceController.displayPreference(getPreferenceScreen());
-        mDarkUIModePreference.setSummary(mDarkUIPreferenceController.getSummary());
     }
 
     private void updateAllPreferences() {
diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java
index b4b909d..ba5e73f 100644
--- a/src/com/android/settings/applications/manageapplications/ManageApplications.java
+++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java
@@ -135,7 +135,7 @@
         implements View.OnClickListener, OnItemSelectedListener, SearchView.OnQueryTextListener {
 
     static final String TAG = "ManageApplications";
-    static final boolean DEBUG = true;
+    static final boolean DEBUG = false;
 
     // Intent extras.
     public static final String EXTRA_CLASSNAME = "classname";
@@ -151,6 +151,7 @@
     private static final String EXTRA_HAS_ENTRIES = "hasEntries";
     private static final String EXTRA_HAS_BRIDGE = "hasBridge";
     private static final String EXTRA_FILTER_TYPE = "filterType";
+    private static final String EXTRA_EXPAND_SEARCH_VIEW = "expand_search_view";
 
     // attributes used as keys when passing values to AppInfoDashboardFragment activity
     public static final String APP_CHG = "chg";
@@ -220,6 +221,9 @@
     FilterSpinnerAdapter mFilterAdapter;
     @VisibleForTesting
     RecyclerView mRecyclerView;
+    // Whether or not search view is expanded.
+    @VisibleForTesting
+    boolean mExpandSearch;
 
     private View mRootView;
     private Spinner mFilterSpinner;
@@ -307,12 +311,14 @@
         mFilter = appFilterRegistry.get(appFilterRegistry.getDefaultFilterType(mListType));
         mIsWorkOnly = args != null ? args.getBoolean(EXTRA_WORK_ONLY) : false;
         mWorkUserId = args != null ? args.getInt(EXTRA_WORK_ID) : NO_USER_SPECIFIED;
+        mExpandSearch = activity.getIntent().getBooleanExtra(EXTRA_EXPAND_SEARCH_VIEW, false);
 
         if (savedInstanceState != null) {
             mSortOrder = savedInstanceState.getInt(EXTRA_SORT_ORDER, mSortOrder);
             mShowSystem = savedInstanceState.getBoolean(EXTRA_SHOW_SYSTEM, mShowSystem);
             mFilterType =
                     savedInstanceState.getInt(EXTRA_FILTER_TYPE, AppFilterRegistry.FILTER_APPS_ALL);
+            mExpandSearch = savedInstanceState.getBoolean(EXTRA_EXPAND_SEARCH_VIEW);
         }
 
         mInvalidSizeStr = activity.getText(R.string.invalid_size_value);
@@ -501,6 +507,7 @@
         outState.putBoolean(EXTRA_SHOW_SYSTEM, mShowSystem);
         outState.putBoolean(EXTRA_HAS_ENTRIES, mApplications.mHasReceivedLoadEntries);
         outState.putBoolean(EXTRA_HAS_BRIDGE, mApplications.mHasReceivedBridgeCallback);
+        outState.putBoolean(EXTRA_EXPAND_SEARCH_VIEW, !mSearchView.isIconified());
         outState.putInt(EXTRA_FILTER_TYPE, mFilter.getFilterType());
         if (mApplications != null) {
             mApplications.onSaveInstanceState(outState);
@@ -607,6 +614,9 @@
             mSearchView = (SearchView) searchMenuItem.getActionView();
             mSearchView.setQueryHint(getText(R.string.search_settings));
             mSearchView.setOnQueryTextListener(this);
+            if (mExpandSearch) {
+                searchMenuItem.expandActionView();
+            }
         }
 
         updateOptionsMenu();
diff --git a/src/com/android/settings/backup/BackupInactivePreferenceController.java b/src/com/android/settings/backup/BackupInactivePreferenceController.java
index 83a0318..92a9487 100644
--- a/src/com/android/settings/backup/BackupInactivePreferenceController.java
+++ b/src/com/android/settings/backup/BackupInactivePreferenceController.java
@@ -28,6 +28,9 @@
 
     @Override
     public int getAvailabilityStatus() {
+        if (!new BackupSettingsHelper(mContext).showBackupSettingsForUser()) {
+            return AVAILABLE_UNSEARCHABLE;
+        }
         if (PrivacySettingsUtils.isInvisibleKey(mContext, PrivacySettingsUtils.BACKUP_INACTIVE)) {
             return UNSUPPORTED_ON_DEVICE;
         }
diff --git a/src/com/android/settings/backup/BackupSettingsHelper.java b/src/com/android/settings/backup/BackupSettingsHelper.java
index 1d3455b..ff4b0b5 100644
--- a/src/com/android/settings/backup/BackupSettingsHelper.java
+++ b/src/com/android/settings/backup/BackupSettingsHelper.java
@@ -50,6 +50,14 @@
         mContext = context;
     }
 
+    public boolean showBackupSettingsForUser() {
+        // For profiles, we want them to be included in the profile select dialog even if
+        // backup is not activated.
+        // For other users, enable/disable backup settings depending on whether backup is activated
+        // for the user.
+        return UserManager.get(mContext).isManagedProfile() || isBackupServiceActive();
+    }
+
     /**
      * If there is only one profile, show whether the backup is on or off.
      * Otherwise, show nothing.
diff --git a/src/com/android/settings/backup/UserBackupSettingsActivity.java b/src/com/android/settings/backup/UserBackupSettingsActivity.java
index 9baa9a3..dbbb135 100644
--- a/src/com/android/settings/backup/UserBackupSettingsActivity.java
+++ b/src/com/android/settings/backup/UserBackupSettingsActivity.java
@@ -98,7 +98,7 @@
      */
     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
-                private static final String BACKUP_SEARCH_INDEX_KEY = "backup";
+                private static final String BACKUP_SEARCH_INDEX_KEY = "Backup";
 
                 @Override
                 public List<SearchIndexableRaw> getRawDataToIndex(Context context,
@@ -119,6 +119,15 @@
 
                     return result;
                 }
+
+                @Override
+                public List<String> getNonIndexableKeys(Context context) {
+                    final List<String> keys = super.getNonIndexableKeys(context);
+                    if (!new BackupSettingsHelper(context).showBackupSettingsForUser()) {
+                        keys.add(BACKUP_SEARCH_INDEX_KEY);
+                    }
+                    return keys;
+                }
             };
 
     @VisibleForTesting
diff --git a/src/com/android/settings/biometrics/BiometricEnrollActivity.java b/src/com/android/settings/biometrics/BiometricEnrollActivity.java
index 1b41240..64ddf4f 100644
--- a/src/com/android/settings/biometrics/BiometricEnrollActivity.java
+++ b/src/com/android/settings/biometrics/BiometricEnrollActivity.java
@@ -20,11 +20,15 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.os.Bundle;
+import android.os.UserHandle;
 
+import com.android.settings.SetupWizardUtils;
 import com.android.settings.biometrics.face.FaceEnrollIntroduction;
+import com.android.settings.biometrics.fingerprint.FingerprintEnrollFindSensor;
 import com.android.settings.biometrics.fingerprint.FingerprintEnrollIntroduction;
 import com.android.settings.biometrics.fingerprint.SetupFingerprintEnrollIntroduction;
 import com.android.settings.core.InstrumentedActivity;
+import com.android.settings.password.ChooseLockSettingsHelper;
 
 import com.google.android.setupcompat.util.WizardManagerHelper;
 
@@ -36,6 +40,12 @@
  */
 public class BiometricEnrollActivity extends InstrumentedActivity {
 
+    private static final String TAG = "BiometricEnrollActivity";
+
+    public static final String EXTRA_SKIP_INTRO = "skip_intro";
+
+    public static final class InternalActivity extends BiometricEnrollActivity {}
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -45,19 +55,43 @@
 
         // This logic may have to be modified on devices with multiple biometrics.
         if (pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
-            intent = getFingerprintEnrollIntent();
+            // ChooseLockGeneric can request to start fingerprint enroll bypassing the intro screen.
+            if (getIntent().getBooleanExtra(EXTRA_SKIP_INTRO, false)
+                    && this instanceof InternalActivity) {
+                intent = getFingerprintFindSensorIntent();
+            } else {
+                intent = getFingerprintIntroIntent();
+            }
         } else if (pm.hasSystemFeature(PackageManager.FEATURE_FACE)) {
-            intent = getFaceEnrollIntent();
+            intent = getFaceIntroIntent();
         }
 
         if (intent != null) {
             intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+
+            if (this instanceof InternalActivity) {
+                // Propagate challenge and user Id from ChooseLockGeneric.
+                final byte[] token = getIntent()
+                        .getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
+                final int userId = getIntent()
+                        .getIntExtra(Intent.EXTRA_USER_ID, UserHandle.USER_NULL);
+
+                intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
+                intent.putExtra(Intent.EXTRA_USER_ID, userId);
+            }
+
             startActivity(intent);
         }
         finish();
     }
 
-    private Intent getFingerprintEnrollIntent() {
+    private Intent getFingerprintFindSensorIntent() {
+        Intent intent = new Intent(this, FingerprintEnrollFindSensor.class);
+        SetupWizardUtils.copySetupExtras(getIntent(), intent);
+        return intent;
+    }
+
+    private Intent getFingerprintIntroIntent() {
         if (WizardManagerHelper.isAnySetupWizard(getIntent())) {
             Intent intent = new Intent(this, SetupFingerprintEnrollIntroduction.class);
             WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent);
@@ -67,7 +101,7 @@
         }
     }
 
-    private Intent getFaceEnrollIntent() {
+    private Intent getFaceIntroIntent() {
         Intent intent = new Intent(this, FaceEnrollIntroduction.class);
         WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent);
         return intent;
diff --git a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java
index a8e4206..d80304f 100644
--- a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java
@@ -150,7 +150,9 @@
         if (!mHasPassword) {
             // No password registered, launch into enrollment wizard.
             launchChooseLock();
-        } else if (!mLaunchedConfirmLock || mToken == null) {
+        } else if (mToken == null) {
+            // It's possible to have a token but mLaunchedConfirmLock == false, since
+            // ChooseLockGeneric can pass us a token.
             launchConfirmLock(getConfirmLockTitleResId(), getChallenge());
         }
     }
@@ -276,7 +278,7 @@
     protected void initViews() {
         super.initViews();
 
-        TextView description = (TextView) findViewById(R.id.description_text);
+        TextView description = (TextView) findViewById(R.id.sud_layout_description);
         if (mBiometricUnlockDisabledByAdmin) {
             description.setText(getDescriptionResDisabledByAdmin());
         }
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
index 3d4ea16..ce5c768 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
@@ -131,7 +131,7 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.fingerprint_enroll_enrolling);
         setHeaderText(R.string.security_settings_fingerprint_enroll_repeat_title);
-        mStartMessage = (TextView) findViewById(R.id.start_message);
+        mStartMessage = (TextView) findViewById(R.id.sud_layout_description);
         mRepeatMessage = (TextView) findViewById(R.id.repeat_message);
         mErrorText = (TextView) findViewById(R.id.error_text);
         mProgressBar = (ProgressBar) findViewById(R.id.fingerprint_progress_bar);
diff --git a/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollIntroduction.java b/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollIntroduction.java
index c720b5d..7df66b7 100644
--- a/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollIntroduction.java
@@ -89,7 +89,7 @@
     protected void initViews() {
         super.initViews();
 
-        TextView description = (TextView) findViewById(R.id.description_text);
+        TextView description = (TextView) findViewById(R.id.sud_layout_description);
         description.setText(
                 R.string.security_settings_fingerprint_enroll_introduction_message_setup);
 
diff --git a/src/com/android/settings/core/FeatureFlags.java b/src/com/android/settings/core/FeatureFlags.java
index 55b31d2..9c00831 100644
--- a/src/com/android/settings/core/FeatureFlags.java
+++ b/src/com/android/settings/core/FeatureFlags.java
@@ -26,7 +26,6 @@
     public static final String MOBILE_NETWORK_V2 = "settings_mobile_network_v2";
     public static final String NETWORK_INTERNET_V2 = "settings_network_and_internet_v2";
     public static final String SLICE_INJECTION = "settings_slice_injection";
-    public static final String WIFI_DETAILS_SAVED_SCREEN = "settings_wifi_details_saved_screen";
     public static final String WIFI_DETAILS_DATAUSAGE_HEADER =
             "settings_wifi_details_datausage_header";
 }
diff --git a/src/com/android/settings/core/SliderPreferenceController.java b/src/com/android/settings/core/SliderPreferenceController.java
index 0ea6be3..0a7ece2 100644
--- a/src/com/android/settings/core/SliderPreferenceController.java
+++ b/src/com/android/settings/core/SliderPreferenceController.java
@@ -44,7 +44,7 @@
     }
 
     /**
-     * @return the value of the Slider's position based on the range: [0, maxSteps).
+     * @return the value of the Slider's position based on the range: [min, max].
      */
     public abstract int getSliderPosition();
 
@@ -57,9 +57,14 @@
     public abstract boolean setSliderPosition(int position);
 
     /**
-     * @return the number of steps supported by the slider.
+     * @return the maximum value supported by the slider.
      */
-    public abstract int getMaxSteps();
+    public abstract int getMax();
+
+    /**
+     * @return the minimum value supported by the slider.
+     */
+    public abstract int getMin();
 
     @Override
     public int getSliceType() {
diff --git a/src/com/android/settings/datausage/DataUsageList.java b/src/com/android/settings/datausage/DataUsageList.java
index e5158ff..96a1e22 100644
--- a/src/com/android/settings/datausage/DataUsageList.java
+++ b/src/com/android/settings/datausage/DataUsageList.java
@@ -99,22 +99,23 @@
                 }
             };
 
-    private ChartDataUsagePreference mChart;
-    private TelephonyManager mTelephonyManager;
-
     @VisibleForTesting
     NetworkTemplate mTemplate;
     @VisibleForTesting
     int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
     @VisibleForTesting
     int mNetworkType;
+    @VisibleForTesting
+    Spinner mCycleSpinner;
+    @VisibleForTesting
+    LoadingViewController mLoadingViewController;
+
+    private ChartDataUsagePreference mChart;
+    private TelephonyManager mTelephonyManager;
     private List<NetworkCycleChartData> mCycleData;
     private ArrayList<Long> mCycles;
-
-    private LoadingViewController mLoadingViewController;
     private UidDetailProvider mUidDetailProvider;
     private CycleAdapter mCycleAdapter;
-    private Spinner mCycleSpinner;
     private Preference mUsageAmount;
     private PreferenceGroup mApps;
     private View mHeader;
@@ -158,6 +159,7 @@
                     .launch();
         });
         mCycleSpinner = mHeader.findViewById(R.id.filter_spinner);
+        mCycleSpinner.setVisibility(View.GONE);
         mCycleAdapter = new CycleAdapter(mCycleSpinner.getContext(), new SpinnerInterface() {
             @Override
             public void setAdapter(CycleAdapter cycleAdapter) {
@@ -276,7 +278,8 @@
      * Update chart sweeps and cycle list to reflect {@link NetworkPolicy} for
      * current {@link #mTemplate}.
      */
-    private void updatePolicy() {
+    @VisibleForTesting
+    void updatePolicy() {
         final NetworkPolicy policy = services.mPolicyEditor.getPolicy(mTemplate);
         final View configureButton = mHeader.findViewById(R.id.filter_settings);
         //SUB SELECT
@@ -486,7 +489,8 @@
         }
     };
 
-    private final LoaderCallbacks<List<NetworkCycleChartData>> mNetworkCycleDataCallbacks =
+    @VisibleForTesting
+    final LoaderCallbacks<List<NetworkCycleChartData>> mNetworkCycleDataCallbacks =
             new LoaderCallbacks<List<NetworkCycleChartData>>() {
         @Override
         public Loader<List<NetworkCycleChartData>> onCreateLoader(int id, Bundle args) {
@@ -503,6 +507,7 @@
             mCycleData = data;
             // calculate policy cycles based on available data
             updatePolicy();
+            mCycleSpinner.setVisibility(View.VISIBLE);
         }
 
         @Override
diff --git a/src/com/android/settings/display/AdaptiveSleepPreferenceController.java b/src/com/android/settings/display/AdaptiveSleepPreferenceController.java
index bd9d386..6aa7187 100644
--- a/src/com/android/settings/display/AdaptiveSleepPreferenceController.java
+++ b/src/com/android/settings/display/AdaptiveSleepPreferenceController.java
@@ -15,9 +15,14 @@
 
 import static android.provider.Settings.System.ADAPTIVE_SLEEP;
 
+import android.Manifest;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.provider.Settings;
 
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
 import com.android.settings.R;
 import com.android.settings.core.TogglePreferenceController;
 
@@ -27,16 +32,24 @@
     private final String SYSTEM_KEY = ADAPTIVE_SLEEP;
     private final int DEFAULT_VALUE = 0;
 
+    private final boolean hasSufficientPermissions;
+
     public AdaptiveSleepPreferenceController(Context context, String key) {
         super(context, key);
+
+        final PackageManager packageManager = mContext.getPackageManager();
+        final String attentionPackage = packageManager.getAttentionServicePackageName();
+        hasSufficientPermissions = attentionPackage != null && packageManager.checkPermission(
+                Manifest.permission.CAMERA, attentionPackage) == PackageManager.PERMISSION_GRANTED;
     }
 
     @Override
     public boolean isChecked() {
-        return Settings.System.getInt(mContext.getContentResolver(),
+        return hasSufficientPermissions && Settings.System.getInt(mContext.getContentResolver(),
                 SYSTEM_KEY, DEFAULT_VALUE) != DEFAULT_VALUE;
     }
 
+
     @Override
     public boolean setChecked(boolean isChecked) {
         Settings.System.putInt(mContext.getContentResolver(), SYSTEM_KEY,
@@ -64,4 +77,15 @@
                 ? R.string.adaptive_sleep_summary_on
                 : R.string.adaptive_sleep_summary_off);
     }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        final Preference preference = screen.findPreference(SYSTEM_KEY);
+
+        if (preference != null) {
+            preference.setEnabled(hasSufficientPermissions);
+        }
+
+    }
 }
diff --git a/src/com/android/settings/display/DarkUIInfoDialogFragment.java b/src/com/android/settings/display/DarkUIInfoDialogFragment.java
new file mode 100644
index 0000000..8fca679
--- /dev/null
+++ b/src/com/android/settings/display/DarkUIInfoDialogFragment.java
@@ -0,0 +1,93 @@
+/*
+ * 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.display.DarkUIPreferenceController.DARK_MODE_PREFS;
+import static com.android.settings.display.DarkUIPreferenceController.PREF_DARK_MODE_DIALOG_SEEN;
+
+import android.app.Dialog;
+import android.app.UiModeManager;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
+
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+
+public class DarkUIInfoDialogFragment extends InstrumentedDialogFragment
+        implements DialogInterface.OnClickListener{
+
+    @Override
+    public int getMetricsCategory() {
+        // TODO(b/130251804): Add metrics constant in followup change to avoid merge conflict in
+        // beta cherrypick
+        return 0;
+    }
+
+    @NonNull
+    @Override
+    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+        Context context = getContext();
+        AlertDialog.Builder dialog = new AlertDialog.Builder(context);
+        LayoutInflater inflater = LayoutInflater.from(dialog.getContext());
+        View titleView = inflater.inflate(R.layout.settings_dialog_title, null);
+        ((ImageView) titleView.findViewById(R.id.settings_icon))
+                .setImageDrawable(context.getDrawable(R.drawable.dark_theme));
+        ((TextView) titleView.findViewById(R.id.settings_title)).setText(R.string.dark_ui_mode);
+
+        dialog.setCustomTitle(titleView)
+                .setMessage(R.string.dark_ui_settings_dark_summary)
+                .setPositiveButton(
+                        R.string.dark_ui_settings_dialog_acknowledge,
+                        this);
+        return dialog.create();
+    }
+
+    @Override
+    public void onDismiss(@NonNull DialogInterface dialog) {
+        enableDarkTheme();
+        super.onDismiss(dialog);
+    }
+
+    @Override
+    public void onClick(DialogInterface dialogInterface, int i) {
+        // We have to manually dismiss the dialog because changing night mode causes it to
+        // recreate itself.
+        dialogInterface.dismiss();
+        enableDarkTheme();
+    }
+
+    private void enableDarkTheme() {
+        final Context context = getContext();
+        if (context != null) {
+            Settings.Secure.putInt(context.getContentResolver(),
+                    Settings.Secure.DARK_MODE_DIALOG_SEEN,
+                    DarkUIPreferenceController.DIALOG_SEEN);
+            context.getSystemService(UiModeManager.class)
+                    .setNightMode(UiModeManager.MODE_NIGHT_YES);
+        }
+    }
+}
diff --git a/src/com/android/settings/display/DarkUIPreferenceController.java b/src/com/android/settings/display/DarkUIPreferenceController.java
index 7d8fd56..9df2402 100644
--- a/src/com/android/settings/display/DarkUIPreferenceController.java
+++ b/src/com/android/settings/display/DarkUIPreferenceController.java
@@ -18,37 +18,66 @@
 
 import android.app.UiModeManager;
 import android.content.Context;
+import android.provider.Settings;
 
 import androidx.annotation.VisibleForTesting;
-import androidx.preference.ListPreference;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
+import androidx.fragment.app.Fragment;
 
-import com.android.settings.R;
-import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.TogglePreferenceController;
 
-public class DarkUIPreferenceController extends BasePreferenceController {
+public class DarkUIPreferenceController extends TogglePreferenceController {
 
+    public static final String DARK_MODE_PREFS = "dark_mode_prefs";
+    public static final String PREF_DARK_MODE_DIALOG_SEEN = "dark_mode_dialog_seen";
+    public static final int DIALOG_SEEN = 1;
     private UiModeManager mUiModeManager;
+    private Context mContext;
+    private Fragment mFragment;
 
     public DarkUIPreferenceController(Context context, String key) {
         super(context, key);
+        mContext = context;
         mUiModeManager = context.getSystemService(UiModeManager.class);
     }
 
+    @Override
+    public boolean isChecked() {
+        return mUiModeManager.getNightMode() == UiModeManager.MODE_NIGHT_YES;
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        final boolean dialogSeen =
+                Settings.Secure.getInt(mContext.getContentResolver(),
+                        Settings.Secure.DARK_MODE_DIALOG_SEEN, 0) == DIALOG_SEEN;
+        if (!dialogSeen && isChecked) {
+            showDarkModeDialog();
+            return false;
+        }
+        mUiModeManager.setNightMode(isChecked
+                ? UiModeManager.MODE_NIGHT_YES
+                : UiModeManager.MODE_NIGHT_NO);
+        return true;
+    }
+
+    private void showDarkModeDialog() {
+        final DarkUIInfoDialogFragment frag = new DarkUIInfoDialogFragment();
+        if (mFragment.getFragmentManager() != null) {
+            frag.show(mFragment.getFragmentManager(), getClass().getName());
+        }
+    }
+
     @VisibleForTesting
     void setUiModeManager(UiModeManager uiModeManager) {
         mUiModeManager = uiModeManager;
     }
 
-    @Override
-    public int getAvailabilityStatus() {
-        return AVAILABLE;
+    public void setParentFragment(Fragment fragment) {
+        mFragment = fragment;
     }
 
     @Override
-    public CharSequence getSummary() {
-        return DarkUISettingsRadioButtonsController.modeToDescription(
-                mContext, mUiModeManager.getNightMode());
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
     }
 }
diff --git a/src/com/android/settings/display/DarkUISettings.java b/src/com/android/settings/display/DarkUISettings.java
deleted file mode 100644
index 50fd386..0000000
--- a/src/com/android/settings/display/DarkUISettings.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * 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.app.UiModeManager;
-import android.app.settings.SettingsEnums;
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.provider.SearchIndexableResource;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-import com.android.settings.R;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
-import com.android.settings.widget.RadioButtonPickerFragment;
-import com.android.settingslib.search.SearchIndexable;
-import com.android.settingslib.widget.CandidateInfo;
-import com.android.settingslib.widget.FooterPreference;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * The screen for selecting the dark theme preference for this device. Automatically updates
- * the associated footer view with any needed information.
- */
-@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
-public class DarkUISettings extends RadioButtonPickerFragment implements Indexable {
-
-  private DarkUISettingsRadioButtonsController mController;
-  private Preference mFooter;
-
-  @Override
-  protected int getPreferenceScreenResId() {
-      return R.xml.dark_ui_settings;
-  }
-
-  @Override
-  public void onAttach(Context context) {
-      super.onAttach(context);
-      // TODO(b/128686189): add illustration once it is ready
-      setIllustration(0, 0);
-      mFooter = new FooterPreference(context);
-      mFooter.setIcon(android.R.color.transparent);
-      mController = new DarkUISettingsRadioButtonsController(context, mFooter);
-  }
-
-  @Override
-  protected List<? extends CandidateInfo> getCandidates() {
-      final Context context = getContext();
-      final List<CandidateInfo> candidates = new ArrayList<>();
-      candidates.add(new DarkUISettingsCandidateInfo(
-              DarkUISettingsRadioButtonsController.modeToDescription(
-                      context, UiModeManager.MODE_NIGHT_YES),
-              /* summary */ null,
-              DarkUISettingsRadioButtonsController.KEY_DARK,
-              /* enabled */ true));
-      candidates.add(new DarkUISettingsCandidateInfo(
-              DarkUISettingsRadioButtonsController.modeToDescription(
-                      context, UiModeManager.MODE_NIGHT_NO),
-              /* summary */ null,
-              DarkUISettingsRadioButtonsController.KEY_LIGHT,
-              /* enabled */ true));
-      return candidates;
-  }
-
-  @Override
-  protected void addStaticPreferences(PreferenceScreen screen) {
-      screen.addPreference(mFooter);
-  }
-
-  @Override
-  protected String getDefaultKey() {
-      return mController.getDefaultKey();
-  }
-
-  @Override
-  protected boolean setDefaultKey(String key) {
-      return mController.setDefaultKey(key);
-  }
-
-  @Override
-  public int getMetricsCategory() {
-      return SettingsEnums.DARK_UI_SETTINGS;
-  }
-
-  static class DarkUISettingsCandidateInfo extends CandidateInfo {
-
-      private final CharSequence mLabel;
-      private final CharSequence mSummary;
-      private final String mKey;
-
-      DarkUISettingsCandidateInfo(CharSequence label, CharSequence summary, String key,
-              boolean enabled) {
-          super(enabled);
-          mLabel = label;
-          mKey = key;
-          mSummary = summary;
-      }
-
-      @Override
-      public CharSequence loadLabel() {
-          return mLabel;
-      }
-
-      @Override
-      public Drawable loadIcon() {
-          return null;
-      }
-
-      @Override
-      public String getKey() {
-          return mKey;
-      }
-
-      public CharSequence getSummary() {
-          return mSummary;
-      }
-  }
-
-  public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-      new BaseSearchIndexProvider() {
-        @Override
-        public List<SearchIndexableResource> getXmlResourcesToIndex(
-            Context context, boolean enabled) {
-          final SearchIndexableResource sir = new SearchIndexableResource(context);
-          sir.xmlResId = R.xml.dark_ui_settings;
-          return Arrays.asList(sir);
-        }
-      };
-}
diff --git a/src/com/android/settings/display/DarkUISettingsRadioButtonsController.java b/src/com/android/settings/display/DarkUISettingsRadioButtonsController.java
deleted file mode 100644
index 0fca306..0000000
--- a/src/com/android/settings/display/DarkUISettingsRadioButtonsController.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.app.UiModeManager;
-import android.content.Context;
-import androidx.preference.Preference;
-import com.android.settings.R;
-import androidx.annotation.VisibleForTesting;
-
-public class DarkUISettingsRadioButtonsController {
-
-    public static final String KEY_DARK = "key_dark_ui_settings_dark";
-    public static final String KEY_LIGHT = "key_dark_ui_settings_light";
-
-    @VisibleForTesting
-    UiModeManager mManager;
-
-    private Preference mFooter;
-
-    public DarkUISettingsRadioButtonsController(Context context, Preference footer) {
-        mManager = context.getSystemService(UiModeManager.class);
-        mFooter = footer;
-    }
-
-    public String getDefaultKey() {
-        final int mode = mManager.getNightMode();
-        updateFooter();
-        return mode == UiModeManager.MODE_NIGHT_YES ? KEY_DARK : KEY_LIGHT;
-    }
-
-    public boolean setDefaultKey(String key) {
-        switch(key) {
-            case KEY_DARK:
-                mManager.setNightMode(UiModeManager.MODE_NIGHT_YES);
-                break;
-            case KEY_LIGHT:
-                mManager.setNightMode(UiModeManager.MODE_NIGHT_NO);
-                break;
-            default:
-                throw new IllegalStateException(
-                        "Not a valid key for " + this.getClass().getSimpleName() + ": " + key);
-        }
-        updateFooter();
-        return true;
-    }
-
-    public void updateFooter() {
-        final int mode = mManager.getNightMode();
-        switch (mode) {
-            case UiModeManager.MODE_NIGHT_YES:
-                mFooter.setSummary(R.string.dark_ui_settings_dark_summary);
-                break;
-            case UiModeManager.MODE_NIGHT_NO:
-            case UiModeManager.MODE_NIGHT_AUTO:
-            default:
-                mFooter.setSummary(R.string.dark_ui_settings_light_summary);
-        }
-    }
-
-    public static String modeToDescription(Context context, int mode) {
-        final String[] values = context.getResources().getStringArray(R.array.dark_ui_mode_entries);
-        switch (mode) {
-            case UiModeManager.MODE_NIGHT_YES:
-                return values[0];
-            case UiModeManager.MODE_NIGHT_NO:
-            case UiModeManager.MODE_NIGHT_AUTO:
-            default:
-                return values[1];
-        }
-    }
-}
diff --git a/src/com/android/settings/display/NightDisplayIntensityPreferenceController.java b/src/com/android/settings/display/NightDisplayIntensityPreferenceController.java
index 48e261e..04e3b13 100644
--- a/src/com/android/settings/display/NightDisplayIntensityPreferenceController.java
+++ b/src/com/android/settings/display/NightDisplayIntensityPreferenceController.java
@@ -55,7 +55,8 @@
         super.displayPreference(screen);
         final SeekBarPreference preference = screen.findPreference(getPreferenceKey());
         preference.setContinuousUpdates(true);
-        preference.setMax(getMaxSteps());
+        preference.setMax(getMax());
+        preference.setMin(getMin());
     }
 
     @Override
@@ -75,10 +76,15 @@
     }
 
     @Override
-    public int getMaxSteps() {
+    public int getMax() {
         return convertTemperature(ColorDisplayManager.getMinimumColorTemperature(mContext));
     }
 
+    @Override
+    public int getMin() {
+        return ColorDisplayManager.getMinimumColorTemperature(mContext);
+    }
+
     /**
      * Inverts and range-adjusts a raw value from the SeekBar (i.e. [0, maxTemp-minTemp]), or
      * converts an inverted and range-adjusted value to the raw SeekBar value, depending on the
diff --git a/src/com/android/settings/fuelgauge/batterytip/HighUsageAdapter.java b/src/com/android/settings/fuelgauge/batterytip/HighUsageAdapter.java
index d832640..cd79ea0 100644
--- a/src/com/android/settings/fuelgauge/batterytip/HighUsageAdapter.java
+++ b/src/com/android/settings/fuelgauge/batterytip/HighUsageAdapter.java
@@ -79,9 +79,6 @@
                 Utils.getBadgedIcon(mIconDrawableFactory, mPackageManager, app.packageName,
                         UserHandle.getUserId(app.uid)));
         holder.appName.setText(Utils.getApplicationLabel(mContext, app.packageName));
-        if (app.screenOnTimeMs != 0) {
-            holder.appTime.setText(StringUtil.formatElapsedTime(mContext, app.screenOnTimeMs, false));
-        }
     }
 
     @Override
diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTip.java b/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTip.java
index 0867a01..ebc4939 100644
--- a/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTip.java
+++ b/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTip.java
@@ -160,7 +160,7 @@
     }
 
     /** Returns the color resid for tinting {@link #getIconId()} or {@link View#NO_ID} if none. */
-    protected @IdRes int getIconTintColorId() {
+    public @IdRes int getIconTintColorId() {
         return View.NO_ID;
     }
 
diff --git a/src/com/android/settings/gestures/PreventRingingSwitchPreferenceController.java b/src/com/android/settings/gestures/PreventRingingSwitchPreferenceController.java
index e21bb75..9545939 100644
--- a/src/com/android/settings/gestures/PreventRingingSwitchPreferenceController.java
+++ b/src/com/android/settings/gestures/PreventRingingSwitchPreferenceController.java
@@ -102,8 +102,15 @@
 
     @Override
     public void onSwitchChanged(Switch switchView, boolean isChecked) {
+        final int preventRingingSetting = Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.VOLUME_HUSH_GESTURE, Settings.Secure.VOLUME_HUSH_VIBRATE);
+        final int newRingingSetting = preventRingingSetting == Settings.Secure.VOLUME_HUSH_OFF
+                ? Settings.Secure.VOLUME_HUSH_VIBRATE
+                : preventRingingSetting;
+
         Settings.Secure.putInt(mContext.getContentResolver(),
-                Settings.Secure.VOLUME_HUSH_GESTURE, isChecked ? Settings.Secure.VOLUME_HUSH_VIBRATE
+                Settings.Secure.VOLUME_HUSH_GESTURE, isChecked
+                        ? newRingingSetting
                         : Settings.Secure.VOLUME_HUSH_OFF);
     }
 
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProvider.java b/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProvider.java
index bba7f53..bdf863e 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProvider.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProvider.java
@@ -16,8 +16,11 @@
 
 package com.android.settings.homepage.contextualcards;
 
-import java.util.List;
+import androidx.slice.Slice;
 
 /** Feature provider for the contextual card feature. */
 public interface ContextualCardFeatureProvider {
+
+    /** Log package when user clicks contextual notification channel card. */
+    void logNotificationPackage(Slice slice);
 }
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImpl.java b/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImpl.java
index 03a1550..4af2838 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImpl.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImpl.java
@@ -16,7 +16,22 @@
 
 package com.android.settings.homepage.contextualcards;
 
+import static android.content.Context.MODE_PRIVATE;
+
 import android.content.Context;
+import android.content.SharedPreferences;
+import android.util.ArraySet;
+
+import androidx.slice.Slice;
+import androidx.slice.SliceMetadata;
+import androidx.slice.core.SliceAction;
+
+import com.android.settings.SettingsActivity;
+import com.android.settings.applications.AppInfoBase;
+import com.android.settings.homepage.contextualcards.slices.ContextualNotificationChannelSlice;
+import com.android.settings.slices.CustomSliceRegistry;
+
+import java.util.Set;
 
 public class ContextualCardFeatureProviderImpl implements ContextualCardFeatureProvider {
     private final Context mContext;
@@ -24,4 +39,27 @@
     public ContextualCardFeatureProviderImpl(Context context) {
         mContext = context;
     }
+
+    @Override
+    public void logNotificationPackage(Slice slice) {
+        if (slice == null || !slice.getUri().equals(
+                CustomSliceRegistry.CONTEXTUAL_NOTIFICATION_CHANNEL_SLICE_URI)) {
+            return;
+        }
+
+        final SliceAction primaryAction = SliceMetadata.from(mContext, slice).getPrimaryAction();
+        final String currentPackage = primaryAction.getAction().getIntent()
+                .getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
+                .getString(AppInfoBase.ARG_PACKAGE_NAME);
+
+        final SharedPreferences prefs = mContext.getSharedPreferences(
+                ContextualNotificationChannelSlice.PREFS, MODE_PRIVATE);
+        final Set<String> interactedPackages = prefs.getStringSet(
+                ContextualNotificationChannelSlice.PREF_KEY_INTERACTED_PACKAGES, new ArraySet<>());
+
+        final Set<String> newInteractedPackages = new ArraySet<>(interactedPackages);
+        newInteractedPackages.add(currentPackage);
+        prefs.edit().putStringSet(ContextualNotificationChannelSlice.PREF_KEY_INTERACTED_PACKAGES,
+                newInteractedPackages).apply();
+    }
 }
diff --git a/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSlice.java b/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSlice.java
index a75f99a..761755c 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSlice.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSlice.java
@@ -25,6 +25,9 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.util.ArrayMap;
 
@@ -39,6 +42,7 @@
 import com.android.internal.os.BatteryStatsHelper;
 import com.android.settings.R;
 import com.android.settings.SubSettings;
+import com.android.settings.Utils;
 import com.android.settings.fuelgauge.BatteryStatsHelperLoader;
 import com.android.settings.fuelgauge.PowerUsageSummary;
 import com.android.settings.fuelgauge.batterytip.BatteryTipLoader;
@@ -107,8 +111,12 @@
             if (batteryTip.getState() == BatteryTip.StateType.INVISIBLE) {
                 continue;
             }
-            final IconCompat icon = IconCompat.createWithResource(mContext,
-                    batteryTip.getIconId());
+            final Drawable drawable = mContext.getDrawable(batteryTip.getIconId());
+            drawable.setColorFilter(new PorterDuffColorFilter(
+                    mContext.getResources().getColor(batteryTip.getIconTintColorId()),
+                    PorterDuff.Mode.SRC_IN));
+
+            final IconCompat icon = Utils.createIconWithDrawable(drawable);
             final SliceAction primaryAction = SliceAction.createDeeplink(getPrimaryAction(),
                     icon,
                     ListBuilder.ICON_IMAGE,
diff --git a/src/com/android/settings/homepage/contextualcards/slices/ContextualNotificationChannelSlice.java b/src/com/android/settings/homepage/contextualcards/slices/ContextualNotificationChannelSlice.java
index 2025a06..17cae77 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/ContextualNotificationChannelSlice.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/ContextualNotificationChannelSlice.java
@@ -16,14 +16,23 @@
 
 package com.android.settings.homepage.contextualcards.slices;
 
+import static android.content.Context.MODE_PRIVATE;
+
 import android.content.Context;
 import android.net.Uri;
+import android.util.ArraySet;
 
 import com.android.settings.R;
 import com.android.settings.slices.CustomSliceRegistry;
+import com.android.settings.slices.SliceBackgroundWorker;
+
+import java.util.Set;
 
 public class ContextualNotificationChannelSlice extends NotificationChannelSlice {
 
+    public static final String PREFS = "notification_channel_slice_prefs";
+    public static final String PREF_KEY_INTERACTED_PACKAGES = "interacted_packages";
+
     public ContextualNotificationChannelSlice(Context context) {
         super(context);
     }
@@ -37,4 +46,18 @@
     protected CharSequence getSubTitle(String packageName, int uid) {
         return mContext.getText(R.string.recently_installed_app);
     }
+
+    @Override
+    protected boolean isUserInteracted(String packageName) {
+        // Check the package has been interacted on current slice or not.
+        final Set<String> interactedPackages =
+                mContext.getSharedPreferences(PREFS, MODE_PRIVATE)
+                        .getStringSet(PREF_KEY_INTERACTED_PACKAGES, new ArraySet<>());
+        return interactedPackages.contains(packageName);
+    }
+
+    @Override
+    public Class<? extends SliceBackgroundWorker> getBackgroundWorkerClass() {
+        return NotificationChannelWorker.class;
+    }
 }
diff --git a/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSlice.java b/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSlice.java
index 0550e7b..07fc899 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSlice.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSlice.java
@@ -154,16 +154,12 @@
         // TODO(b/123065955): Review latency of NotificationChannelSlice
         final List<PackageInfo> multiChannelPackages = getMultiChannelPackages(
                 getRecentlyInstalledPackages());
-        final PackageInfo packageInfo = getMaxSentNotificationsPackage(multiChannelPackages);
-
-        // Return a header with IsError flag, if package is not found.
-        if (packageInfo == null) {
+        mPackageName = getMaxSentNotificationsPackage(multiChannelPackages);
+        if (mPackageName == null) {
+            // Return a header with IsError flag, if package is not found.
             return listBuilder.setHeader(getNoSuggestedAppHeader())
                     .setIsError(true).build();
         }
-
-        // Save eligible package name and its uid, they will be used in getIntent().
-        mPackageName = packageInfo.packageName;
         mUid = getApplicationUid(mPackageName);
 
         // Add notification channel header.
@@ -177,7 +173,7 @@
                 .setPrimaryAction(getPrimarySliceAction(icon, title, getIntent())));
 
         // Add notification channel rows.
-        final List<ListBuilder.RowBuilder> rows = getNotificationChannelRows(packageInfo, icon);
+        final List<ListBuilder.RowBuilder> rows = getNotificationChannelRows(icon);
         for (ListBuilder.RowBuilder rowBuilder : rows) {
             listBuilder.addRow(rowBuilder);
         }
@@ -218,6 +214,17 @@
                 .toIntent();
     }
 
+    /**
+     * Check the package has been interacted by user or not.
+     * Will use to filter package in {@link #getRecentlyInstalledPackages()}.
+     *
+     * @param packageName The app package name.
+     * @return true if the package was interacted, false otherwise.
+     */
+    protected boolean isUserInteracted(String packageName) {
+        return false;
+    }
+
     @VisibleForTesting
     IconCompat getApplicationIcon(String packageName) {
         final Drawable drawable;
@@ -271,8 +278,7 @@
                 .setPrimaryAction(primarySliceActionForNoSuggestedApp);
     }
 
-    private List<ListBuilder.RowBuilder> getNotificationChannelRows(PackageInfo packageInfo,
-            IconCompat icon) {
+    private List<ListBuilder.RowBuilder> getNotificationChannelRows(IconCompat icon) {
         final List<ListBuilder.RowBuilder> notificationChannelRows = new ArrayList<>();
         final List<NotificationChannel> displayableChannels = getDisplayableChannels(mAppRow);
 
@@ -328,8 +334,9 @@
         final List<PackageInfo> installedPackages =
                 mContext.getPackageManager().getInstalledPackages(0);
         for (PackageInfo packageInfo : installedPackages) {
-            // Not include system app.
-            if (packageInfo.applicationInfo.isSystemApp()) {
+            // Not include system app and interacted app.
+            if (packageInfo.applicationInfo.isSystemApp()
+                    || isUserInteracted(packageInfo.packageName)) {
                 continue;
             }
 
@@ -376,14 +383,14 @@
                 .collect(Collectors.toList());
     }
 
-    private PackageInfo getMaxSentNotificationsPackage(List<PackageInfo> packageInfoList) {
+    private String getMaxSentNotificationsPackage(List<PackageInfo> packageInfoList) {
         if (packageInfoList.isEmpty()) {
             return null;
         }
 
         // Get the package which has sent at least ~10 notifications and not turn off channels.
         int maxSentCount = 0;
-        PackageInfo maxSentCountPackage = null;
+        String maxSentCountPackage = null;
         for (PackageInfo packageInfo : packageInfoList) {
             final NotificationBackend.AppRow appRow = mNotificationBackend.loadAppRow(mContext,
                     mContext.getPackageManager(), packageInfo);
@@ -396,7 +403,7 @@
             final int sentCount = appRow.sentByApp.sentCount;
             if (sentCount >= MIN_NOTIFICATION_SENT_COUNT && sentCount > maxSentCount) {
                 maxSentCount = sentCount;
-                maxSentCountPackage = packageInfo;
+                maxSentCountPackage = packageInfo.packageName;
                 mAppRow = appRow;
             }
         }
diff --git a/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelWorker.java b/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelWorker.java
new file mode 100644
index 0000000..f1d0d59
--- /dev/null
+++ b/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelWorker.java
@@ -0,0 +1,77 @@
+/*
+ * 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.slices;
+
+import static android.content.Context.MODE_PRIVATE;
+
+import static com.android.settings.homepage.contextualcards.slices.ContextualNotificationChannelSlice.PREFS;
+import static com.android.settings.homepage.contextualcards.slices.ContextualNotificationChannelSlice.PREF_KEY_INTERACTED_PACKAGES;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
+import android.net.Uri;
+import android.util.ArraySet;
+
+import com.android.settings.slices.SliceBackgroundWorker;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class NotificationChannelWorker extends SliceBackgroundWorker<Void> {
+
+    public NotificationChannelWorker(Context context, Uri uri) {
+        super(context, uri);
+    }
+
+    @Override
+    protected void onSlicePinned() {
+    }
+
+    @Override
+    protected void onSliceUnpinned() {
+        removeUninstalledPackages();
+    }
+
+    @Override
+    public void close() throws IOException {
+    }
+
+    private void removeUninstalledPackages() {
+        final SharedPreferences prefs = getContext().getSharedPreferences(PREFS, MODE_PRIVATE);
+        final Set<String> interactedPackages =
+                prefs.getStringSet(PREF_KEY_INTERACTED_PACKAGES, new ArraySet());
+        if (interactedPackages.isEmpty()) {
+            return;
+        }
+
+        final List<PackageInfo> installedPackageInfos =
+                getContext().getPackageManager().getInstalledPackages(0);
+        final List<String> installedPackages = installedPackageInfos.stream()
+                .map(packageInfo -> packageInfo.packageName)
+                .collect(Collectors.toList());
+        final Set<String> newInteractedPackages = new ArraySet<>();
+        for (String packageName : interactedPackages) {
+            if (installedPackages.contains(packageName)) {
+                newInteractedPackages.add(packageName);
+            }
+        }
+        prefs.edit().putStringSet(PREF_KEY_INTERACTED_PACKAGES, newInteractedPackages).apply();
+    }
+}
diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
index 725f087..9898834 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.homepage.contextualcards.slices;
 
+import static android.app.slice.Slice.HINT_ERROR;
+
 import android.content.ContentResolver;
 import android.content.Context;
 import android.net.Uri;
@@ -117,6 +119,14 @@
                 return;
             }
 
+            if (slice.hasHint(HINT_ERROR)) {
+                Log.w(TAG, "Slice has HINT_ERROR, skipping rendering. uri=" + slice.getUri());
+                mSliceLiveDataMap.get(slice.getUri()).removeObservers(mLifecycleOwner);
+                mContext.getContentResolver().notifyChange(CardContentProvider.REFRESH_CARD_URI,
+                        null);
+                return;
+            }
+
             switch (holder.getItemViewType()) {
                 case VIEW_TYPE_DEFERRED_SETUP:
                     mDeferredSetupCardHelper.bindView(holder, card, slice);
diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java b/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java
index a9a8346..f7b2bf5 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java
@@ -27,6 +27,7 @@
 
 import com.android.settings.R;
 import com.android.settings.homepage.contextualcards.ContextualCard;
+import com.android.settings.homepage.contextualcards.ContextualCardFeatureProvider;
 import com.android.settings.homepage.contextualcards.logging.ContextualCardLogUtils;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -64,6 +65,12 @@
 
                     metricsFeatureProvider.action(mContext,
                             SettingsEnums.ACTION_CONTEXTUAL_CARD_CLICK, log);
+
+                    final ContextualCardFeatureProvider contextualCardFeatureProvider =
+                            FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider(
+                                    mContext);
+
+                    contextualCardFeatureProvider.logNotificationPackage(slice);
                 });
 
         // Customize slice view for Settings
diff --git a/src/com/android/settings/network/MobileNetworkSummaryController.java b/src/com/android/settings/network/MobileNetworkSummaryController.java
index 463d7ae..ae115eb 100644
--- a/src/com/android/settings/network/MobileNetworkSummaryController.java
+++ b/src/com/android/settings/network/MobileNetworkSummaryController.java
@@ -21,6 +21,7 @@
 
 import android.content.Context;
 import android.content.Intent;
+import android.os.UserManager;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.euicc.EuiccManager;
@@ -49,6 +50,7 @@
     private static final String KEY = "mobile_network_list";
 
     private SubscriptionManager mSubscriptionManager;
+    private UserManager mUserManager;
     private SubscriptionsChangeListener mChangeListener;
     private AddPreference mPreference;
 
@@ -70,6 +72,7 @@
     public MobileNetworkSummaryController(Context context, Lifecycle lifecycle) {
         super(context);
         mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
+        mUserManager = context.getSystemService(UserManager.class);
         if (lifecycle != null) {
           mChangeListener = new SubscriptionsChangeListener(context, this);
           lifecycle.addObserver(this);
@@ -137,6 +140,8 @@
                     startAddSimFlow();
                     return true;
                 });
+            } else {
+                mPreference.setEnabled(false);
             }
         } else {
             // We have one or more existing subscriptions, so we want the plus button if eSIM is
@@ -160,7 +165,7 @@
 
     @Override
     public boolean isAvailable() {
-        return !Utils.isWifiOnly(mContext);
+        return !Utils.isWifiOnly(mContext) && mUserManager.isAdminUser();
     }
 
     @Override
diff --git a/src/com/android/settings/notification/AudioHelper.java b/src/com/android/settings/notification/AudioHelper.java
index a918d86..d178113 100644
--- a/src/com/android/settings/notification/AudioHelper.java
+++ b/src/com/android/settings/notification/AudioHelper.java
@@ -74,4 +74,8 @@
     public int getMaxVolume(int stream) {
         return mAudioManager.getStreamMaxVolume(stream);
     }
+
+    public int getMinVolume(int stream) {
+        return mAudioManager.getStreamMinVolume(stream);
+    }
 }
diff --git a/src/com/android/settings/notification/RedactionInterstitial.java b/src/com/android/settings/notification/RedactionInterstitial.java
index f765694..74ccf59 100644
--- a/src/com/android/settings/notification/RedactionInterstitial.java
+++ b/src/com/android/settings/notification/RedactionInterstitial.java
@@ -123,7 +123,7 @@
             mUserId = Utils.getUserIdFromBundle(
                     getContext(), getActivity().getIntent().getExtras());
             if (UserManager.get(getContext()).isManagedProfile(mUserId)) {
-                ((TextView) view.findViewById(R.id.message))
+                ((TextView) view.findViewById(R.id.sud_layout_description))
                         .setText(R.string.lock_screen_notifications_interstitial_message_profile);
                 mShowAllButton.setText(R.string.lock_screen_notifications_summary_show_profile);
                 mRedactSensitiveButton
diff --git a/src/com/android/settings/notification/RemoteVolumePreferenceController.java b/src/com/android/settings/notification/RemoteVolumePreferenceController.java
index b455465..816d80f 100644
--- a/src/com/android/settings/notification/RemoteVolumePreferenceController.java
+++ b/src/com/android/settings/notification/RemoteVolumePreferenceController.java
@@ -43,7 +43,6 @@
     @VisibleForTesting
     static final int REMOTE_VOLUME = 100;
 
-    private MediaSessionManager mMediaSessionManager;
     private MediaSessions mMediaSessions;
     @VisibleForTesting
     MediaSession.Token mActiveToken;
@@ -86,28 +85,39 @@
 
     public RemoteVolumePreferenceController(Context context) {
         super(context, KEY_REMOTE_VOLUME);
-        mMediaSessionManager = context.getSystemService(MediaSessionManager.class);
         mMediaSessions = new MediaSessions(context, Looper.getMainLooper(), mCallbacks);
+        updateToken(getActiveRemoteToken(mContext));
     }
 
     @Override
     public int getAvailabilityStatus() {
-        final List<MediaController> controllers = mMediaSessionManager.getActiveSessions(null);
+        // Always return true to make it indexed in database
+        return AVAILABLE_UNSEARCHABLE;
+    }
+
+    /**
+     * Return {@link android.media.session.MediaSession.Token} for active remote token, or
+     * {@code null} if there is no active remote token.
+     */
+    public static MediaSession.Token getActiveRemoteToken(Context context) {
+        final MediaSessionManager sessionManager = context.getSystemService(
+                MediaSessionManager.class);
+        final List<MediaController> controllers = sessionManager.getActiveSessions(null);
         for (MediaController mediaController : controllers) {
             final MediaController.PlaybackInfo pi = mediaController.getPlaybackInfo();
             if (isRemote(pi)) {
-                updateToken(mediaController.getSessionToken());
-                return AVAILABLE;
+                return mediaController.getSessionToken();
             }
         }
 
         // No active remote media at this point
-        return CONDITIONALLY_UNAVAILABLE;
+        return null;
     }
 
     @Override
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
+        mPreference.setVisible(mActiveToken != null);
         if (mMediaController != null) {
             updatePreference(mPreference, mActiveToken, mMediaController.getPlaybackInfo());
         }
@@ -150,7 +160,7 @@
     }
 
     @Override
-    public int getMaxSteps() {
+    public int getMax() {
         if (mPreference != null) {
             return mPreference.getMax();
         }
@@ -162,6 +172,14 @@
     }
 
     @Override
+    public int getMin() {
+        if (mPreference != null) {
+            return mPreference.getMin();
+        }
+        return 0;
+    }
+
+    @Override
     public boolean isSliceable() {
         return TextUtils.equals(getPreferenceKey(), KEY_REMOTE_VOLUME);
     }
diff --git a/src/com/android/settings/notification/VolumeSeekBarPreference.java b/src/com/android/settings/notification/VolumeSeekBarPreference.java
index 7f36791..92b3cae 100644
--- a/src/com/android/settings/notification/VolumeSeekBarPreference.java
+++ b/src/com/android/settings/notification/VolumeSeekBarPreference.java
@@ -80,11 +80,6 @@
         mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
     }
 
-    @Override
-    public boolean isSelectable() {
-        return false;
-    }
-
     public void setStream(int stream) {
         mStream = stream;
         setMax(mAudioManager.getStreamMaxVolume(mStream));
diff --git a/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java b/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java
index fff9aaf..f7bf75f 100644
--- a/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java
+++ b/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java
@@ -92,13 +92,21 @@
     }
 
     @Override
-    public int getMaxSteps() {
+    public int getMax() {
         if (mPreference != null) {
             return mPreference.getMax();
         }
         return mHelper.getMaxVolume(getAudioStream());
     }
 
+    @Override
+    public int getMin() {
+        if (mPreference != null) {
+            return mPreference.getMin();
+        }
+        return mHelper.getMinVolume(getAudioStream());
+    }
+
     protected abstract int getAudioStream();
 
     protected abstract int getMuteIcon();
diff --git a/src/com/android/settings/notification/ZenModeButtonPreferenceController.java b/src/com/android/settings/notification/ZenModeButtonPreferenceController.java
index 4829a28..3a9bcb7 100644
--- a/src/com/android/settings/notification/ZenModeButtonPreferenceController.java
+++ b/src/com/android/settings/notification/ZenModeButtonPreferenceController.java
@@ -33,11 +33,12 @@
 public class ZenModeButtonPreferenceController extends AbstractZenModePreferenceController
         implements PreferenceControllerMixin {
 
+    public static final String KEY = "zen_mode_toggle";
+
     private static final String TAG = "EnableZenModeButton";
-    protected static final String KEY = "zen_mode_settings_button_container";
+    private final FragmentManager mFragment;
     private Button mZenButtonOn;
     private Button mZenButtonOff;
-    private FragmentManager mFragment;
 
     public ZenModeButtonPreferenceController(Context context, Lifecycle lifecycle, FragmentManager
             fragment) {
@@ -60,13 +61,13 @@
         super.updateState(preference);
 
         if (null == mZenButtonOn) {
-            mZenButtonOn = (Button) ((LayoutPreference) preference)
+            mZenButtonOn = ((LayoutPreference) preference)
                     .findViewById(R.id.zen_mode_settings_turn_on_button);
             updateZenButtonOnClickListener();
         }
 
         if (null == mZenButtonOff) {
-            mZenButtonOff = (Button) ((LayoutPreference) preference)
+            mZenButtonOff = ((LayoutPreference) preference)
                     .findViewById(R.id.zen_mode_settings_turn_off_button);
             mZenButtonOff.setOnClickListener(v -> {
                 mMetricsFeatureProvider.action(mContext,
diff --git a/src/com/android/settings/notification/ZenModeSettings.java b/src/com/android/settings/notification/ZenModeSettings.java
index 9360a33..f35c649 100644
--- a/src/com/android/settings/notification/ZenModeSettings.java
+++ b/src/com/android/settings/notification/ZenModeSettings.java
@@ -328,7 +328,6 @@
                 public List<String> getNonIndexableKeys(Context context) {
                     List<String> keys = super.getNonIndexableKeys(context);
                     keys.add(ZenModeDurationPreferenceController.KEY);
-                    keys.add(ZenModeButtonPreferenceController.KEY);
                     return keys;
                 }
 
diff --git a/src/com/android/settings/notification/ZenModeSliceBuilder.java b/src/com/android/settings/notification/ZenModeSliceBuilder.java
index e8b181a..9e88cea 100644
--- a/src/com/android/settings/notification/ZenModeSliceBuilder.java
+++ b/src/com/android/settings/notification/ZenModeSliceBuilder.java
@@ -18,8 +18,6 @@
 
 import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
 
-import static com.android.settings.notification.ZenModeSoundSettingsPreferenceController.ZEN_MODE_KEY;
-
 import android.annotation.ColorInt;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -47,6 +45,8 @@
 
     private static final String TAG = "ZenModeSliceBuilder";
 
+    private static final String ZEN_MODE_SLICE_KEY = ZenModeButtonPreferenceController.KEY;
+
     /**
      * Action notifying a change on the Zen Mode Slice.
      */
@@ -78,7 +78,8 @@
         final PendingIntent primaryAction = getPrimaryAction(context);
         final SliceAction primarySliceAction = SliceAction.createDeeplink(primaryAction,
                 (IconCompat) null /* icon */, ListBuilder.ICON_IMAGE, title);
-        final SliceAction toggleSliceAction = SliceAction.createToggle(toggleAction, null /* actionTitle */,
+        final SliceAction toggleSliceAction = SliceAction.createToggle(toggleAction,
+                null /* actionTitle */,
                 isZenModeEnabled);
 
         return new ListBuilder(context, CustomSliceRegistry.ZEN_MODE_SLICE_URI,
@@ -110,10 +111,10 @@
     }
 
     public static Intent getIntent(Context context) {
-        final Uri contentUri = new Uri.Builder().appendPath(ZEN_MODE_KEY).build();
+        final Uri contentUri = new Uri.Builder().appendPath(ZEN_MODE_SLICE_KEY).build();
         final String screenTitle = context.getText(R.string.zen_mode_settings_title).toString();
         return SliceBuilderUtils.buildSearchResultPageIntent(context,
-                ZenModeSettings.class.getName(), ZEN_MODE_KEY, screenTitle,
+                ZenModeSettings.class.getName(), ZEN_MODE_SLICE_KEY, screenTitle,
                 SettingsEnums.NOTIFICATION_ZEN_MODE)
                 .setClassName(context.getPackageName(), SubSettings.class.getName())
                 .setData(contentUri);
diff --git a/src/com/android/settings/notification/ZenModeSoundSettingsPreferenceController.java b/src/com/android/settings/notification/ZenModeSoundSettingsPreferenceController.java
deleted file mode 100644
index 842c49d..0000000
--- a/src/com/android/settings/notification/ZenModeSoundSettingsPreferenceController.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.notification;
-
-import android.content.Context;
-
-public class ZenModeSoundSettingsPreferenceController extends ZenModePreferenceController {
-
-    public static final String ZEN_MODE_KEY = "zen_mode";
-
-    public ZenModeSoundSettingsPreferenceController(Context context, String key) {
-        super(context, key);
-    }
-
-    @Override
-    public int getAvailabilityStatus() {
-        return AVAILABLE;
-    }
-}
diff --git a/src/com/android/settings/panel/PanelFragment.java b/src/com/android/settings/panel/PanelFragment.java
index f1391dc..173461c 100644
--- a/src/com/android/settings/panel/PanelFragment.java
+++ b/src/com/android/settings/panel/PanelFragment.java
@@ -16,12 +16,20 @@
 
 package com.android.settings.panel;
 
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
 import android.app.settings.SettingsEnums;
-import android.content.Context;
+import android.net.Uri;
 import android.os.Bundle;
+import android.os.Handler;
+import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
 import android.widget.Button;
 import android.widget.TextView;
 
@@ -29,8 +37,12 @@
 import androidx.annotation.Nullable;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentActivity;
+import androidx.lifecycle.LiveData;
+import androidx.slice.Slice;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
+import androidx.slice.SliceMetadata;
+import androidx.slice.widget.SliceLiveData;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
@@ -39,10 +51,24 @@
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.google.android.setupdesign.DividerItemDecoration;
 
+import java.util.ArrayList;
+import java.util.List;
+
 public class PanelFragment extends Fragment {
 
     private static final String TAG = "PanelFragment";
 
+    /**
+     * Duration of the animation entering or exiting the screen, in milliseconds.
+     */
+    private static final int DURATION_ANIMATE_PANEL_MS = 250;
+
+    /**
+     * Duration of timeout waiting for Slice data to bind, in milliseconds.
+     */
+    private static final int DURATION_SLICE_BINDING_TIMEOUT_MS = 250;
+
+    private View mLayoutView;
     private TextView mTitleView;
     private Button mSeeMoreButton;
     private Button mDoneButton;
@@ -50,21 +76,42 @@
 
     private PanelContent mPanel;
     private MetricsFeatureProvider mMetricsProvider;
+    private String mPanelClosedKey;
+
+    private final List<LiveData<Slice>> mSliceLiveData = new ArrayList<>();
 
     @VisibleForTesting
-    PanelSlicesAdapter mAdapter;
+    PanelSlicesLoaderCountdownLatch mPanelSlicesLoaderCountdownLatch;
+
+    private ViewTreeObserver.OnPreDrawListener mOnPreDrawListener = () -> {
+        return false;
+    };
+
+    private final ViewTreeObserver.OnGlobalLayoutListener mOnGlobalLayoutListener =
+            new ViewTreeObserver.OnGlobalLayoutListener() {
+        @Override
+        public void onGlobalLayout() {
+            animateIn();
+            if (mPanelSlices != null) {
+                mPanelSlices.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+            }
+        }
+    };
+
+    private PanelSlicesAdapter mAdapter;
 
     @Nullable
     @Override
     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
             @Nullable Bundle savedInstanceState) {
         final FragmentActivity activity = getActivity();
-        final View view = inflater.inflate(R.layout.panel_layout, container, false);
 
-        mPanelSlices = view.findViewById(R.id.panel_parent_layout);
-        mSeeMoreButton = view.findViewById(R.id.see_more);
-        mDoneButton = view.findViewById(R.id.done);
-        mTitleView = view.findViewById(R.id.panel_title);
+        mLayoutView = inflater.inflate(R.layout.panel_layout, container, false);
+
+        mPanelSlices = mLayoutView.findViewById(R.id.panel_parent_layout);
+        mSeeMoreButton = mLayoutView.findViewById(R.id.see_more);
+        mDoneButton = mLayoutView.findViewById(R.id.done);
+        mTitleView = mLayoutView.findViewById(R.id.panel_title);
 
         final Bundle arguments = getArguments();
         final String panelType =
@@ -80,6 +127,24 @@
                 .getPanel(activity, panelType, mediaPackageName);
 
         mMetricsProvider = FeatureFactory.getFactory(activity).getMetricsFeatureProvider();
+
+        mPanelSlices.setLayoutManager(new LinearLayoutManager((activity)));
+
+        // Add predraw listener to remove the animation and while we wait for Slices to load.
+        mLayoutView.getViewTreeObserver().addOnPreDrawListener(mOnPreDrawListener);
+
+        // Start loading Slices. When finished, the Panel will animate in.
+        loadAllSlices();
+
+        mTitleView.setText(mPanel.getTitle());
+        mSeeMoreButton.setOnClickListener(getSeeMoreListener());
+        mDoneButton.setOnClickListener(getCloseListener());
+
+        // If getSeeMoreIntent() is null, hide the mSeeMoreButton.
+        if (mPanel.getSeeMoreIntent() == null) {
+            mSeeMoreButton.setVisibility(View.GONE);
+        }
+
         // Log panel opened.
         mMetricsProvider.action(
                 0 /* attribution */,
@@ -88,38 +153,136 @@
                 callingPackageName,
                 0 /* value */);
 
-        mAdapter = new PanelSlicesAdapter(this, mPanel);
+        return mLayoutView;
+    }
 
-        mPanelSlices.setHasFixedSize(true);
-        mPanelSlices.setLayoutManager(new LinearLayoutManager((activity)));
-        mPanelSlices.setAdapter(mAdapter);
+    private void loadAllSlices() {
+        mSliceLiveData.clear();
+        final List<Uri> sliceUris = mPanel.getSlices();
+        mPanelSlicesLoaderCountdownLatch = new PanelSlicesLoaderCountdownLatch(sliceUris.size());
 
-        DividerItemDecoration itemDecoration = new DividerItemDecoration(getActivity());
-        itemDecoration.setDividerCondition(DividerItemDecoration.DIVIDER_CONDITION_BOTH);
-        mPanelSlices.addItemDecoration(itemDecoration);
+        for (Uri uri : sliceUris) {
+            final LiveData<Slice> sliceLiveData = SliceLiveData.fromUri(getActivity(), uri);
 
-        mTitleView.setText(mPanel.getTitle());
+            // Add slice first to make it in order.  Will remove it later if there's an error.
+            mSliceLiveData.add(sliceLiveData);
 
-        mSeeMoreButton.setOnClickListener(getSeeMoreListener());
-        mDoneButton.setOnClickListener(getCloseListener());
+            sliceLiveData.observe(getViewLifecycleOwner(), slice -> {
+                // If the Slice has already loaded, do nothing.
+                if (mPanelSlicesLoaderCountdownLatch.isSliceLoaded(uri)) {
+                    return;
+                }
 
-        //If getSeeMoreIntent() is null, hide the mSeeMoreButton.
-        if (mPanel.getSeeMoreIntent() == null) {
-            mSeeMoreButton.setVisibility(View.GONE);
+                /**
+                 * Watching for the {@link Slice} to load.
+                 * <p>
+                 *     If the Slice comes back {@code null} or with the Error attribute, remove the
+                 *     Slice data from the list, and mark the Slice as loaded.
+                 * <p>
+                 *     If the Slice has come back fully loaded, then mark the Slice as loaded.  No
+                 *     other actions required since we already have the Slice data in the list.
+                 * <p>
+                 *     If the Slice does not match the above condition, we will still want to mark
+                 *     it as loaded after 250ms timeout to avoid delay showing up the panel for
+                 *     too long.  Since we are still having the Slice data in the list, the Slice
+                 *     will show up later once it is loaded.
+                 */
+                final SliceMetadata metadata = SliceMetadata.from(getActivity(), slice);
+                if (slice == null || metadata.isErrorSlice()) {
+                    mSliceLiveData.remove(sliceLiveData);
+                    mPanelSlicesLoaderCountdownLatch.markSliceLoaded(uri);
+                } else if (metadata.getLoadingState() == SliceMetadata.LOADED_ALL) {
+                    mPanelSlicesLoaderCountdownLatch.markSliceLoaded(uri);
+                } else {
+                    Handler handler = new Handler();
+                    handler.postDelayed(() -> {
+                        mPanelSlicesLoaderCountdownLatch.markSliceLoaded(uri);
+                        loadPanelWhenReady();
+                    }, DURATION_SLICE_BINDING_TIMEOUT_MS);
+                }
+
+                loadPanelWhenReady();
+            });
+        }
+    }
+
+    /**
+     * When all of the Slices have loaded for the first time, then we can setup the
+     * {@link RecyclerView}.
+     * <p>
+     *     When the Recyclerview has been laid out, we can begin the animation with the
+     *     {@link mOnGlobalLayoutListener}, which calls {@link #animateIn()}.
+     */
+    private void loadPanelWhenReady() {
+        if (mPanelSlicesLoaderCountdownLatch.isPanelReadyToLoad()) {
+            mAdapter = new PanelSlicesAdapter(
+                    this, mSliceLiveData, mPanel.getMetricsCategory());
+            mPanelSlices.setAdapter(mAdapter);
+            mPanelSlices.getViewTreeObserver()
+                    .addOnGlobalLayoutListener(mOnGlobalLayoutListener);
+
+            DividerItemDecoration itemDecoration = new DividerItemDecoration(getActivity());
+            itemDecoration
+                    .setDividerCondition(DividerItemDecoration.DIVIDER_CONDITION_BOTH);
+            mPanelSlices.addItemDecoration(itemDecoration);
+        }
+    }
+
+    /**
+     * Animate a Panel onto the screen.
+     * <p>
+     *     Takes the entire panel and animates in from behind the navigation bar.
+     * <p>
+     *     Relies on the Panel being having a fixed height to begin the animation.
+     */
+    private void animateIn() {
+        final View panelContent = mLayoutView.findViewById(R.id.panel_container);
+        final AnimatorSet animatorSet = buildAnimatorSet(mLayoutView, panelContent.getHeight(),
+                0.0f, new DecelerateInterpolator());
+        final ValueAnimator animator = new ValueAnimator();
+        animator.setFloatValues(0.0f, 1.0f);
+        animatorSet.play(animator);
+        animatorSet.start();
+        // Remove the predraw listeners on the Panel.
+        mLayoutView.getViewTreeObserver().removeOnPreDrawListener(mOnPreDrawListener);
+    }
+
+    /**
+     * Build an {@link AnimatorSet} to bring the Panel, {@param parentView}in our out of the screen,
+     * based on the positional parameters {@param startY}, {@param endY} and at the rate set by the
+     * {@param interpolator}.
+     */
+    @NonNull
+    private static AnimatorSet buildAnimatorSet(@NonNull View parentView, float startY, float endY,
+            @NonNull Interpolator interpolator) {
+        final View sheet = parentView.findViewById(R.id.panel_container);
+        final AnimatorSet animatorSet = new AnimatorSet();
+        animatorSet.setDuration(DURATION_ANIMATE_PANEL_MS);
+        animatorSet.setInterpolator(interpolator);
+        animatorSet.playTogether(ObjectAnimator.ofFloat(sheet, View.TRANSLATION_Y, startY, endY));
+        return animatorSet;
+    }
+
+    @Override
+    public void onDestroyView() {
+        super.onDestroyView();
+
+        if (TextUtils.isEmpty(mPanelClosedKey)) {
+            mPanelClosedKey = PanelClosedKeys.KEY_OTHERS;
         }
 
-        return view;
+        mMetricsProvider.action(
+                0 /* attribution */,
+                SettingsEnums.PAGE_HIDE,
+                mPanel.getMetricsCategory(),
+                mPanelClosedKey,
+                0 /* value */);
     }
 
     @VisibleForTesting
     View.OnClickListener getSeeMoreListener() {
         return (v) -> {
-            mMetricsProvider.action(
-                    0 /* attribution */,
-                    SettingsEnums.PAGE_HIDE ,
-                    mPanel.getMetricsCategory(),
-                    PanelClosedKeys.KEY_SEE_MORE,
-                    0 /* value */);
+            mPanelClosedKey = PanelClosedKeys.KEY_SEE_MORE;
             final FragmentActivity activity = getActivity();
             activity.startActivityForResult(mPanel.getSeeMoreIntent(), 0);
             activity.finish();
@@ -129,12 +292,7 @@
     @VisibleForTesting
     View.OnClickListener getCloseListener() {
         return (v) -> {
-            mMetricsProvider.action(
-                    0 /* attribution */,
-                    SettingsEnums.PAGE_HIDE,
-                    mPanel.getMetricsCategory(),
-                    PanelClosedKeys.KEY_DONE,
-                    0 /* value */);
+            mPanelClosedKey = PanelClosedKeys.KEY_DONE;
             getActivity().finish();
         };
     }
diff --git a/src/com/android/settings/panel/PanelLoggingContract.java b/src/com/android/settings/panel/PanelLoggingContract.java
index e149186..e6e3012 100644
--- a/src/com/android/settings/panel/PanelLoggingContract.java
+++ b/src/com/android/settings/panel/PanelLoggingContract.java
@@ -39,8 +39,9 @@
         String KEY_DONE = "done";
 
         /**
-         * The user clicked outside the dialog, closing the Panel.
+         * The user closed the panel by other ways, for example: clicked outside of dialog, tapping
+         * on back button, etc.
          */
-        String KEY_CLICKED_OUT = "clicked_out";
+        String KEY_OTHERS = "others";
     }
 }
diff --git a/src/com/android/settings/panel/PanelSlicesAdapter.java b/src/com/android/settings/panel/PanelSlicesAdapter.java
index 0eec534..e244413 100644
--- a/src/com/android/settings/panel/PanelSlicesAdapter.java
+++ b/src/com/android/settings/panel/PanelSlicesAdapter.java
@@ -20,7 +20,6 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.net.Uri;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -30,13 +29,13 @@
 import androidx.lifecycle.LiveData;
 import androidx.recyclerview.widget.RecyclerView;
 import androidx.slice.Slice;
-import androidx.slice.widget.SliceLiveData;
 import androidx.slice.widget.SliceView;
 
 import com.android.settings.R;
 import com.android.settings.overlay.FeatureFactory;
 import com.google.android.setupdesign.DividerItemDecoration;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -45,14 +44,15 @@
 public class PanelSlicesAdapter
         extends RecyclerView.Adapter<PanelSlicesAdapter.SliceRowViewHolder> {
 
-    private final List<Uri> mSliceUris;
+    private final List<LiveData<Slice>> mSliceLiveData;
+    private final int mMetricsCategory;
     private final PanelFragment mPanelFragment;
-    private final PanelContent mPanelContent;
 
-    public PanelSlicesAdapter(PanelFragment fragment, PanelContent panel) {
+    public PanelSlicesAdapter(
+            PanelFragment fragment, List<LiveData<Slice>> sliceLiveData, int metricsCategory) {
         mPanelFragment = fragment;
-        mSliceUris = panel.getSlices();
-        mPanelContent = panel;
+        mSliceLiveData = new ArrayList<>(sliceLiveData);
+        mMetricsCategory = metricsCategory;
     }
 
     @NonNull
@@ -62,67 +62,60 @@
         final LayoutInflater inflater = LayoutInflater.from(context);
         final View view = inflater.inflate(R.layout.panel_slice_row, viewGroup, false);
 
-        return new SliceRowViewHolder(view, mPanelContent);
+        return new SliceRowViewHolder(view);
     }
 
     @Override
     public void onBindViewHolder(@NonNull SliceRowViewHolder sliceRowViewHolder, int position) {
-        sliceRowViewHolder.onBind(mPanelFragment, mSliceUris.get(position));
+        sliceRowViewHolder.onBind(mSliceLiveData.get(position));
     }
 
     @Override
     public int getItemCount() {
-        return mSliceUris.size();
+        return mSliceLiveData.size();
     }
 
     @VisibleForTesting
-    List<Uri> getData() {
-        return mSliceUris;
+    List<LiveData<Slice>> getData() {
+        return mSliceLiveData;
     }
 
     /**
      * ViewHolder for binding Slices to SliceViews.
      */
-    public static class SliceRowViewHolder extends RecyclerView.ViewHolder
+    public class SliceRowViewHolder extends RecyclerView.ViewHolder
             implements DividerItemDecoration.DividedViewHolder {
 
-        private final PanelContent mPanelContent;
-
         private boolean mDividerAllowedAbove = true;
 
         @VisibleForTesting
-        LiveData<Slice> sliceLiveData;
-
-        @VisibleForTesting
         final SliceView sliceView;
 
-        public SliceRowViewHolder(View view, PanelContent panelContent) {
+        public SliceRowViewHolder(View view) {
             super(view);
             sliceView = view.findViewById(R.id.slice_view);
             sliceView.setMode(SliceView.MODE_LARGE);
             sliceView.showTitleItems(true);
-            mPanelContent = panelContent;
         }
 
-        public void onBind(PanelFragment fragment, Uri sliceUri) {
-            final Context context = sliceView.getContext();
-            sliceLiveData = SliceLiveData.fromUri(context, sliceUri);
-            sliceLiveData.observe(fragment.getViewLifecycleOwner(), sliceView);
+        public void onBind(LiveData<Slice> sliceLiveData) {
+            sliceLiveData.observe(mPanelFragment.getViewLifecycleOwner(), sliceView);
 
             // Do not show the divider above media devices switcher slice per request
-            if (sliceUri.equals(MEDIA_OUTPUT_INDICATOR_SLICE_URI)) {
+            final Slice slice = sliceLiveData.getValue();
+            if (slice != null && slice.getUri().equals(MEDIA_OUTPUT_INDICATOR_SLICE_URI)) {
                 mDividerAllowedAbove = false;
             }
 
             // Log Panel interaction
             sliceView.setOnSliceActionListener(
                     ((eventInfo, sliceItem) -> {
-                        FeatureFactory.getFactory(context)
+                        FeatureFactory.getFactory(sliceView.getContext())
                                 .getMetricsFeatureProvider()
                                 .action(0 /* attribution */,
                                         SettingsEnums.ACTION_PANEL_INTERACTION,
-                                        mPanelContent.getMetricsCategory(),
-                                        sliceUri.toString() /* log key */,
+                                        mMetricsCategory,
+                                        sliceLiveData.toString() /* log key */,
                                         eventInfo.actionType /* value */);
                     })
             );
diff --git a/src/com/android/settings/panel/PanelSlicesLoaderCountdownLatch.java b/src/com/android/settings/panel/PanelSlicesLoaderCountdownLatch.java
new file mode 100644
index 0000000..6137d6c
--- /dev/null
+++ b/src/com/android/settings/panel/PanelSlicesLoaderCountdownLatch.java
@@ -0,0 +1,83 @@
+/*
+ * 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.panel;
+
+import android.net.Uri;
+
+import androidx.slice.Slice;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * Helper class to isolate the work tracking all of the {@link Slice Slices} being loaded.
+ * <p>
+ *     Uses a {@link CountDownLatch} and a {@link Set} of Slices to track how many
+ *     Slices have been loaded. A Slice can only be counted as being loaded a single time, even
+ *     when they get updated later.
+ * <p>
+ *     To use the class, pass the number of expected Slices to load into the constructor. For
+ *     every Slice that loads, call {@link #markSliceLoaded(Uri)} with the corresponding
+ *     {@link Uri}. Then check if all of the Slices have loaded with
+ *     {@link #isPanelReadyToLoad()}, which will return {@code true} the first time after all
+ *     Slices have loaded.
+ */
+public class PanelSlicesLoaderCountdownLatch {
+    private final Set<Uri> mLoadedSlices;
+    private final CountDownLatch mCountDownLatch;
+    private boolean slicesReadyToLoad = false;
+
+    public PanelSlicesLoaderCountdownLatch(int countdownSize) {
+        mLoadedSlices = new HashSet<>();
+        mCountDownLatch = new CountDownLatch(countdownSize);
+    }
+
+    /**
+     * Checks if the {@param sliceUri} has been loaded: if not, then decrement the countdown
+     * latch, and if so, then do nothing.
+     */
+    public void markSliceLoaded(Uri sliceUri) {
+        if (mLoadedSlices.contains(sliceUri)) {
+            return;
+        }
+        mLoadedSlices.add(sliceUri);
+        mCountDownLatch.countDown();
+    }
+
+    /**
+     * @return {@code true} if the Slice has already been loaded.
+     */
+    public boolean isSliceLoaded(Uri uri) {
+        return mLoadedSlices.contains(uri);
+    }
+
+    /**
+     * @return {@code true} when all Slices have loaded, and the Panel has not yet been loaded.
+     */
+    public boolean isPanelReadyToLoad() {
+        /**
+         * Use {@link slicesReadyToLoad} to track whether or not the Panel has been loaded. We
+         * only want to animate the Panel a single time.
+         */
+        if ((mCountDownLatch.getCount() == 0) && !slicesReadyToLoad) {
+            slicesReadyToLoad = true;
+            return true;
+        }
+        return false;
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/panel/SettingsPanelActivity.java b/src/com/android/settings/panel/SettingsPanelActivity.java
index 8aee382..eabd715 100644
--- a/src/com/android/settings/panel/SettingsPanelActivity.java
+++ b/src/com/android/settings/panel/SettingsPanelActivity.java
@@ -97,21 +97,4 @@
             fragmentManager.beginTransaction().add(R.id.main_content, panelFragment).commit();
         }
     }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
-            final PanelContent panelContent = FeatureFactory.getFactory(this)
-                    .getPanelFeatureProvider()
-                    .getPanel(this, getIntent().getAction(), null /* Media Package Name */);
-            FeatureFactory.getFactory(this)
-                    .getMetricsFeatureProvider()
-                    .action(0 /* attribution */,
-                            SettingsEnums.PAGE_HIDE,
-                            panelContent.getMetricsCategory(),
-                            PanelClosedKeys.KEY_CLICKED_OUT,
-                            0 /* value */);
-        }
-        return super.onTouchEvent(event);
-    }
 }
diff --git a/src/com/android/settings/panel/VolumePanel.java b/src/com/android/settings/panel/VolumePanel.java
index 4ea7fe7..2cbf729 100644
--- a/src/com/android/settings/panel/VolumePanel.java
+++ b/src/com/android/settings/panel/VolumePanel.java
@@ -30,6 +30,7 @@
 import android.provider.Settings;
 
 import com.android.settings.R;
+import com.android.settings.notification.RemoteVolumePreferenceController;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -54,7 +55,9 @@
     @Override
     public List<Uri> getSlices() {
         final List<Uri> uris = new ArrayList<>();
-        uris.add(VOLUME_REMOTE_MEDIA_URI);
+        if (RemoteVolumePreferenceController.getActiveRemoteToken(mContext) != null) {
+            uris.add(VOLUME_REMOTE_MEDIA_URI);
+        }
         uris.add(VOLUME_MEDIA_URI);
         uris.add(MEDIA_OUTPUT_INDICATOR_SLICE_URI);
         uris.add(VOLUME_CALL_URI);
diff --git a/src/com/android/settings/password/ChooseLockGeneric.java b/src/com/android/settings/password/ChooseLockGeneric.java
index 580c7ba..7eb8dc2 100644
--- a/src/com/android/settings/password/ChooseLockGeneric.java
+++ b/src/com/android/settings/password/ChooseLockGeneric.java
@@ -66,8 +66,8 @@
 import com.android.settings.SettingsActivity;
 import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.Utils;
+import com.android.settings.biometrics.BiometricEnrollActivity;
 import com.android.settings.biometrics.BiometricEnrollBase;
-import com.android.settings.biometrics.fingerprint.FingerprintEnrollFindSensor;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
 import com.android.settings.search.SearchFeatureProvider;
 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
@@ -76,7 +76,6 @@
 import com.android.settingslib.widget.FooterPreference;
 import com.android.settingslib.widget.FooterPreferenceMixinCompat;
 
-import java.util.Arrays;
 import java.util.List;
 
 public class ChooseLockGeneric extends SettingsActivity {
@@ -141,7 +140,7 @@
         @VisibleForTesting
         static final int CHOOSE_LOCK_REQUEST = 102;
         @VisibleForTesting
-        static final int CHOOSE_LOCK_BEFORE_FINGERPRINT_REQUEST = 103;
+        static final int CHOOSE_LOCK_BEFORE_BIOMETRIC_REQUEST = 103;
         @VisibleForTesting
         static final int SKIP_FINGERPRINT_REQUEST = 104;
 
@@ -366,7 +365,7 @@
                 startActivityForResult(
                         intent,
                         mIsSetNewPassword && mHasChallenge
-                                ? CHOOSE_LOCK_BEFORE_FINGERPRINT_REQUEST
+                                ? CHOOSE_LOCK_BEFORE_BIOMETRIC_REQUEST
                                 : ENABLE_ENCRYPTION_REQUEST);
             } else {
                 if (mForChangeCredRequiredForBoot) {
@@ -411,9 +410,9 @@
                         finish();
                     }
                 }
-            } else if (requestCode == CHOOSE_LOCK_BEFORE_FINGERPRINT_REQUEST
+            } else if (requestCode == CHOOSE_LOCK_BEFORE_BIOMETRIC_REQUEST
                     && resultCode == BiometricEnrollBase.RESULT_FINISHED) {
-                Intent intent = getFindSensorIntent(getActivity());
+                Intent intent = getBiometricEnrollIntent(getActivity());
                 if (data != null) {
                     intent.putExtras(data.getExtras());
                 }
@@ -438,8 +437,11 @@
             }
         }
 
-        protected Intent getFindSensorIntent(Context context) {
-            return new Intent(context, FingerprintEnrollFindSensor.class);
+        protected Intent getBiometricEnrollIntent(Context context) {
+            final Intent intent =
+                    new Intent(context, BiometricEnrollActivity.InternalActivity.class);
+            intent.putExtra(BiometricEnrollActivity.EXTRA_SKIP_INTRO, true);
+            return intent;
         }
 
         @Override
@@ -764,7 +766,7 @@
                 intent.putExtra(EXTRA_CHOOSE_LOCK_GENERIC_EXTRAS, getIntent().getExtras());
                 startActivityForResult(intent,
                         mIsSetNewPassword && mHasChallenge
-                                ? CHOOSE_LOCK_BEFORE_FINGERPRINT_REQUEST
+                                ? CHOOSE_LOCK_BEFORE_BIOMETRIC_REQUEST
                                 : CHOOSE_LOCK_REQUEST);
                 return;
             }
diff --git a/src/com/android/settings/password/ChooseLockPassword.java b/src/com/android/settings/password/ChooseLockPassword.java
index 16cecc8..21ef720 100644
--- a/src/com/android/settings/password/ChooseLockPassword.java
+++ b/src/com/android/settings/password/ChooseLockPassword.java
@@ -443,7 +443,7 @@
             mSkipOrClearButton = mixin.getSecondaryButton();
             mNextButton = mixin.getPrimaryButton();
 
-            mMessage = view.findViewById(R.id.message);
+            mMessage = view.findViewById(R.id.sud_layout_description);
             if (mForFingerprint) {
                 mLayout.setIcon(getActivity().getDrawable(R.drawable.ic_fingerprint_header));
             } else if (mForFace) {
diff --git a/src/com/android/settings/password/ChooseLockPattern.java b/src/com/android/settings/password/ChooseLockPattern.java
index e0974fe..85b9a46 100644
--- a/src/com/android/settings/password/ChooseLockPattern.java
+++ b/src/com/android/settings/password/ChooseLockPattern.java
@@ -520,7 +520,7 @@
             mTitleText = view.findViewById(R.id.suc_layout_title);
             mHeaderText = (TextView) view.findViewById(R.id.headerText);
             mDefaultHeaderColorList = mHeaderText.getTextColors();
-            mMessageText = view.findViewById(R.id.message);
+            mMessageText = view.findViewById(R.id.sud_layout_description);
             mLockPatternView = (LockPatternView) view.findViewById(R.id.lockPattern);
             mLockPatternView.setOnPatternListener(mChooseNewLockPatternListener);
             mLockPatternView.setTactileFeedbackEnabled(
diff --git a/src/com/android/settings/password/ConfirmLockPassword.java b/src/com/android/settings/password/ConfirmLockPassword.java
index 6c61967..f2b5a35 100644
--- a/src/com/android/settings/password/ConfirmLockPassword.java
+++ b/src/com/android/settings/password/ConfirmLockPassword.java
@@ -137,7 +137,7 @@
             if (mHeaderTextView == null) {
                 mHeaderTextView = view.findViewById(R.id.suc_layout_title);
             }
-            mDetailsTextView = (TextView) view.findViewById(R.id.detailsText);
+            mDetailsTextView = (TextView) view.findViewById(R.id.sud_layout_description);
             mErrorTextView = (TextView) view.findViewById(R.id.errorText);
             mIsAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == storedQuality
                     || DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == storedQuality
diff --git a/src/com/android/settings/password/ConfirmLockPattern.java b/src/com/android/settings/password/ConfirmLockPattern.java
index 6d3d6e5..f43ee7f 100644
--- a/src/com/android/settings/password/ConfirmLockPattern.java
+++ b/src/com/android/settings/password/ConfirmLockPattern.java
@@ -116,7 +116,7 @@
                     false);
             mHeaderTextView = (TextView) view.findViewById(R.id.headerText);
             mLockPatternView = (LockPatternView) view.findViewById(R.id.lockPattern);
-            mDetailsTextView = (TextView) view.findViewById(R.id.detailsText);
+            mDetailsTextView = (TextView) view.findViewById(R.id.sud_layout_description);
             mErrorTextView = (TextView) view.findViewById(R.id.errorText);
             mLeftSpacerLandscape = view.findViewById(R.id.leftSpacer);
             mRightSpacerLandscape = view.findViewById(R.id.rightSpacer);
diff --git a/src/com/android/settings/password/SetupChooseLockGeneric.java b/src/com/android/settings/password/SetupChooseLockGeneric.java
index 346e771..72b9fa8 100644
--- a/src/com/android/settings/password/SetupChooseLockGeneric.java
+++ b/src/com/android/settings/password/SetupChooseLockGeneric.java
@@ -42,6 +42,7 @@
 import com.android.settings.R;
 import com.android.settings.SetupEncryptionInterstitial;
 import com.android.settings.SetupWizardUtils;
+import com.android.settings.biometrics.BiometricEnrollActivity;
 import com.android.settings.biometrics.fingerprint.SetupFingerprintEnrollFindSensor;
 import com.android.settings.utils.SettingsDividerItemDecoration;
 
@@ -229,8 +230,8 @@
         }
 
         @Override
-        protected Intent getFindSensorIntent(Context context) {
-            final Intent intent = new Intent(context, SetupFingerprintEnrollFindSensor.class);
+        protected Intent getBiometricEnrollIntent(Context context) {
+            final Intent intent = getBiometricEnrollIntent(context);
             SetupWizardUtils.copySetupExtras(getActivity().getIntent(), intent);
             return intent;
         }
diff --git a/src/com/android/settings/sim/CallsSimListDialogFragment.java b/src/com/android/settings/sim/CallsSimListDialogFragment.java
new file mode 100644
index 0000000..bb5a003
--- /dev/null
+++ b/src/com/android/settings/sim/CallsSimListDialogFragment.java
@@ -0,0 +1,59 @@
+/*
+ * 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.sim;
+
+import android.content.Context;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Specialized version of SimListDialogFragment that fetches a list of SIMs which support calls.
+ */
+public class CallsSimListDialogFragment extends SimListDialogFragment {
+    @Override
+    protected List<SubscriptionInfo> getCurrentSubscriptions() {
+        final Context context = getContext();
+        final SubscriptionManager subscriptionManager = context.getSystemService(
+                SubscriptionManager.class);
+        final TelecomManager telecomManager = context.getSystemService(TelecomManager.class);
+        final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
+        final List<PhoneAccountHandle> phoneAccounts =
+                telecomManager.getCallCapablePhoneAccounts();
+        final List<SubscriptionInfo> result = new ArrayList<>();
+
+        if (phoneAccounts == null) {
+            return result;
+        }
+        for (PhoneAccountHandle handle : phoneAccounts) {
+            final PhoneAccount phoneAccount = telecomManager.getPhoneAccount(handle);
+            final int subId = telephonyManager.getSubIdForPhoneAccount(phoneAccount);
+
+            if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+                continue;
+            }
+            result.add(subscriptionManager.getActiveSubscriptionInfo(subId));
+        }
+        return result;
+    }
+}
diff --git a/src/com/android/settings/sim/PreferredSimDialogFragment.java b/src/com/android/settings/sim/PreferredSimDialogFragment.java
new file mode 100644
index 0000000..5b81e62
--- /dev/null
+++ b/src/com/android/settings/sim/PreferredSimDialogFragment.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.sim;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.appcompat.app.AlertDialog;
+
+import com.android.settings.R;
+
+/**
+ * Presents a dialog asking the user if they want to update all services to use a given "preferred"
+ * SIM. Typically this would be used in a case where a device goes from having multiple SIMs down to
+ * only one.
+ */
+public class PreferredSimDialogFragment extends SimDialogFragment implements
+        DialogInterface.OnClickListener {
+    private static final String TAG = "PreferredSimDialogFrag";
+
+    public static PreferredSimDialogFragment newInstance() {
+        final PreferredSimDialogFragment fragment = new PreferredSimDialogFragment();
+        final Bundle args = initArguments(SimDialogActivity.PREFERRED_PICK,
+                R.string.sim_preferred_title);
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    @NonNull
+    @Override
+    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+        final AlertDialog dialog = new AlertDialog.Builder(getContext())
+                .setTitle(getTitleResId())
+                .setPositiveButton(R.string.yes, this)
+                .setNegativeButton(R.string.no, null)
+                .create();
+        updateDialog(dialog);
+        return dialog;
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int buttonClicked) {
+        if (buttonClicked != DialogInterface.BUTTON_POSITIVE) {
+            return;
+        }
+        final SimDialogActivity activity = (SimDialogActivity) getActivity();
+        final SubscriptionInfo info = getPreferredSubscription();
+        if (info != null) {
+            activity.onSubscriptionSelected(getDialogType(), info.getSubscriptionId());
+        }
+    }
+
+    public SubscriptionInfo getPreferredSubscription() {
+        final Activity activity = getActivity();
+        final int slotId = activity.getIntent().getIntExtra(SimDialogActivity.PREFERRED_SIM,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        return getSubscriptionManager().getActiveSubscriptionInfoForSimSlotIndex(slotId);
+    }
+
+    private void updateDialog(AlertDialog dialog) {
+        final SubscriptionInfo info = getPreferredSubscription();
+        if (info == null) {
+            dismiss();
+            return;
+        }
+        final String message =
+                getContext().getString(R.string.sim_preferred_message, info.getDisplayName());
+        dialog.setMessage(message);
+    }
+
+    @Override
+    public void updateDialog() {
+        updateDialog((AlertDialog) getDialog());
+    }
+
+    @VisibleForTesting
+    protected SubscriptionManager getSubscriptionManager() {
+        return getContext().getSystemService(SubscriptionManager.class);
+    }
+}
diff --git a/src/com/android/settings/sim/SimDialogActivity.java b/src/com/android/settings/sim/SimDialogActivity.java
index 487dace..d721efd 100644
--- a/src/com/android/settings/sim/SimDialogActivity.java
+++ b/src/com/android/settings/sim/SimDialogActivity.java
@@ -16,37 +16,30 @@
 
 package com.android.settings.sim;
 
-import android.app.Activity;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.res.Resources;
+import android.content.Intent;
 import android.os.Bundle;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
-import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.ImageView;
-import android.widget.ListAdapter;
-import android.widget.TextView;
+import android.util.Log;
 import android.widget.Toast;
 
-import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
 
 import com.android.settings.R;
 
-import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
-public class SimDialogActivity extends Activity {
+/**
+ * This activity provides singleton semantics per dialog type for showing various kinds of
+ * dialogs asking the user to make choices about which SIM to use for various services
+ * (calls, SMS, and data).
+ */
+public class SimDialogActivity extends FragmentActivity {
     private static String TAG = "SimDialogActivity";
 
     public static String PREFERRED_SIM = "preferred_sim";
@@ -60,276 +53,118 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        final int dialogType = getIntent().getIntExtra(DIALOG_TYPE_KEY, INVALID_PICK);
+        showOrUpdateDialog();
+    }
 
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        setIntent(intent);
+        showOrUpdateDialog();
+    }
+
+    private void showOrUpdateDialog() {
+        final int dialogType = getIntent().getIntExtra(DIALOG_TYPE_KEY, INVALID_PICK);
+        final String tag = Integer.toString(dialogType);
+        final FragmentManager fragmentManager = getSupportFragmentManager();
+        SimDialogFragment fragment = (SimDialogFragment) fragmentManager.findFragmentByTag(tag);
+
+        if (fragment == null) {
+            fragment = createFragment(dialogType);
+            fragment.show(fragmentManager, tag);
+        } else {
+            fragment.updateDialog();
+        }
+    }
+
+    private SimDialogFragment createFragment(int dialogType) {
+        switch(dialogType) {
+            case DATA_PICK:
+                return SimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_data,
+                        false /* includeAskEveryTime */);
+            case CALLS_PICK:
+                return CallsSimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_calls,
+                        true /* includeAskEveryTime */);
+            case SMS_PICK:
+                return SimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_sms,
+                        false /* includeAskEveryTime */);
+            case PREFERRED_PICK:
+                if (!getIntent().hasExtra(PREFERRED_SIM)) {
+                    throw new IllegalArgumentException("Missing required extra " + PREFERRED_SIM);
+                }
+                return PreferredSimDialogFragment.newInstance();
+            default:
+                throw new IllegalArgumentException( "Invalid dialog type " + dialogType + " sent.");
+        }
+    }
+
+    public void onSubscriptionSelected(int dialogType, int subId) {
+        if (getSupportFragmentManager().findFragmentByTag(Integer.toString(dialogType)) == null) {
+            Log.w(TAG, "onSubscriptionSelected ignored because stored fragment was null");
+            return;
+        }
         switch (dialogType) {
             case DATA_PICK:
+                setDefaultDataSubId(subId);
+                break;
             case CALLS_PICK:
+                setDefaultCallsSubId(subId);
+                break;
             case SMS_PICK:
-                createDialog(this, dialogType).show();
+                setDefaultSmsSubId(subId);
                 break;
             case PREFERRED_PICK:
-                displayPreferredDialog(getIntent().getIntExtra(PREFERRED_SIM, 0));
+                setPreferredSim(subId);
                 break;
             default:
-                throw new IllegalArgumentException("Invalid dialog type " + dialogType + " sent.");
-        }
-
-    }
-
-    private void displayPreferredDialog(final int slotId) {
-        final Resources res = getResources();
-        final Context context = getApplicationContext();
-        final SubscriptionInfo sir = SubscriptionManager.from(context)
-                .getActiveSubscriptionInfoForSimSlotIndex(slotId);
-
-        if (sir != null) {
-            AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
-            alertDialogBuilder.setTitle(R.string.sim_preferred_title);
-            alertDialogBuilder.setMessage(res.getString(
-                        R.string.sim_preferred_message, sir.getDisplayName()));
-
-            alertDialogBuilder.setPositiveButton(R.string.yes, new
-                    DialogInterface.OnClickListener() {
-                @Override
-                public void onClick(DialogInterface dialog, int id) {
-                    final int subId = sir.getSubscriptionId();
-                    PhoneAccountHandle phoneAccountHandle =
-                            subscriptionIdToPhoneAccountHandle(subId);
-                    setDefaultDataSubId(context, subId);
-                    setDefaultSmsSubId(context, subId);
-                    setUserSelectedOutgoingPhoneAccount(phoneAccountHandle);
-                    finish();
-                }
-            });
-            alertDialogBuilder.setNegativeButton(R.string.no, new
-                    DialogInterface.OnClickListener() {
-                @Override
-                public void onClick(DialogInterface dialog,int id) {
-                    finish();
-                }
-            });
-
-            alertDialogBuilder.create().show();
-        } else {
-            finish();
+                throw new IllegalArgumentException(
+                        "Invalid dialog type " + dialogType + " sent.");
         }
     }
 
-    private static void setDefaultDataSubId(final Context context, final int subId) {
-        final SubscriptionManager subscriptionManager = SubscriptionManager.from(context);
-        final TelephonyManager telephonyManager = TelephonyManager.from(context)
-                .createForSubscriptionId(subId);
+    public void onFragmentDismissed(SimDialogFragment simDialogFragment) {
+        final List<Fragment> fragments = getSupportFragmentManager().getFragments();
+        if (fragments.size() == 1 && fragments.get(0) == simDialogFragment) {
+            finishAndRemoveTask();
+        }
+    }
+
+    private void setDefaultDataSubId(final int subId) {
+        final SubscriptionManager subscriptionManager = getSystemService(SubscriptionManager.class);
+        final TelephonyManager telephonyManager = getSystemService(
+                TelephonyManager.class).createForSubscriptionId(subId);
         subscriptionManager.setDefaultDataSubId(subId);
         telephonyManager.setDataEnabled(true);
-        Toast.makeText(context, R.string.data_switch_started, Toast.LENGTH_LONG).show();
+        Toast.makeText(this, R.string.data_switch_started, Toast.LENGTH_LONG).show();
     }
 
-    private static void setDefaultSmsSubId(final Context context, final int subId) {
-        final SubscriptionManager subscriptionManager = SubscriptionManager.from(context);
-        subscriptionManager.setDefaultSmsSubId(subId);
-    }
-
-    private void setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle phoneAccount) {
-        final TelecomManager telecomManager = TelecomManager.from(this);
+    private void setDefaultCallsSubId(final int subId) {
+        final PhoneAccountHandle phoneAccount = subscriptionIdToPhoneAccountHandle(subId);
+        final TelecomManager telecomManager = getSystemService(TelecomManager.class);
         telecomManager.setUserSelectedOutgoingPhoneAccount(phoneAccount);
     }
 
+    private void setDefaultSmsSubId(final int subId) {
+        final SubscriptionManager subscriptionManager = getSystemService(SubscriptionManager.class);
+        subscriptionManager.setDefaultSmsSubId(subId);
+    }
+
+    private void setPreferredSim(final int subId) {
+        setDefaultDataSubId(subId);
+        setDefaultSmsSubId(subId);
+        setDefaultCallsSubId(subId);
+    }
+
     private PhoneAccountHandle subscriptionIdToPhoneAccountHandle(final int subId) {
-        final TelecomManager telecomManager = TelecomManager.from(this);
-        final TelephonyManager telephonyManager = TelephonyManager.from(this);
-        final Iterator<PhoneAccountHandle> phoneAccounts =
-                telecomManager.getCallCapablePhoneAccounts().listIterator();
+        final TelecomManager telecomManager = getSystemService(TelecomManager.class);
+        final TelephonyManager telephonyManager = getSystemService(TelephonyManager.class);
 
-        while (phoneAccounts.hasNext()) {
-            final PhoneAccountHandle phoneAccountHandle = phoneAccounts.next();
-            final PhoneAccount phoneAccount = telecomManager.getPhoneAccount(phoneAccountHandle);
+        for (PhoneAccountHandle handle : telecomManager.getCallCapablePhoneAccounts()) {
+            final PhoneAccount phoneAccount = telecomManager.getPhoneAccount(handle);
             if (subId == telephonyManager.getSubIdForPhoneAccount(phoneAccount)) {
-                return phoneAccountHandle;
+                return handle;
             }
         }
-
         return null;
     }
-
-    public Dialog createDialog(final Context context, final int id) {
-        final ArrayList<String> list = new ArrayList<String>();
-        final SubscriptionManager subscriptionManager = SubscriptionManager.from(context);
-        final List<SubscriptionInfo> subInfoList =
-            subscriptionManager.getActiveSubscriptionInfoList(true);
-        final int selectableSubInfoLength = subInfoList == null ? 0 : subInfoList.size();
-
-        final DialogInterface.OnClickListener selectionListener =
-                new DialogInterface.OnClickListener() {
-                    @Override
-                    public void onClick(DialogInterface dialog, int value) {
-
-                        final SubscriptionInfo sir;
-
-                        switch (id) {
-                            case DATA_PICK:
-                                sir = subInfoList.get(value);
-                                setDefaultDataSubId(context, sir.getSubscriptionId());
-                                break;
-                            case CALLS_PICK:
-                                final TelecomManager telecomManager =
-                                        TelecomManager.from(context);
-                                final List<PhoneAccountHandle> phoneAccountsList =
-                                        telecomManager.getCallCapablePhoneAccounts();
-                                setUserSelectedOutgoingPhoneAccount(
-                                        value < 1 ? null : phoneAccountsList.get(value - 1));
-                                break;
-                            case SMS_PICK:
-                                sir = subInfoList.get(value);
-                                setDefaultSmsSubId(context, sir.getSubscriptionId());
-                                break;
-                            default:
-                                throw new IllegalArgumentException("Invalid dialog type "
-                                        + id + " in SIM dialog.");
-                        }
-
-                        finish();
-                    }
-                };
-
-        Dialog.OnKeyListener keyListener = new Dialog.OnKeyListener() {
-            @Override
-            public boolean onKey(DialogInterface arg0, int keyCode,
-                    KeyEvent event) {
-                    if (keyCode == KeyEvent.KEYCODE_BACK) {
-                        finish();
-                    }
-                    return true;
-                }
-            };
-
-        ArrayList<SubscriptionInfo> callsSubInfoList = new ArrayList<SubscriptionInfo>();
-        if (id == CALLS_PICK) {
-            final TelecomManager telecomManager = TelecomManager.from(context);
-            final TelephonyManager telephonyManager = TelephonyManager.from(context);
-            final Iterator<PhoneAccountHandle> phoneAccounts =
-                    telecomManager.getCallCapablePhoneAccounts().listIterator();
-
-            list.add(getResources().getString(R.string.sim_calls_ask_first_prefs_title));
-            callsSubInfoList.add(null);
-            while (phoneAccounts.hasNext()) {
-                final PhoneAccount phoneAccount =
-                        telecomManager.getPhoneAccount(phoneAccounts.next());
-                list.add((String)phoneAccount.getLabel());
-                int subId = telephonyManager.getSubIdForPhoneAccount(phoneAccount);
-                if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-                    final SubscriptionInfo sir = SubscriptionManager.from(context)
-                            .getActiveSubscriptionInfo(subId);
-                    callsSubInfoList.add(sir);
-                } else {
-                    callsSubInfoList.add(null);
-                }
-            }
-        } else {
-            for (int i = 0; i < selectableSubInfoLength; ++i) {
-                final SubscriptionInfo sir = subInfoList.get(i);
-                CharSequence displayName = sir.getDisplayName();
-                if (displayName == null) {
-                    displayName = "";
-                }
-                list.add(displayName.toString());
-            }
-        }
-
-        String[] arr = list.toArray(new String[0]);
-
-        AlertDialog.Builder builder = new AlertDialog.Builder(context);
-
-        ListAdapter adapter = new SelectAccountListAdapter(
-                id == CALLS_PICK ? callsSubInfoList : subInfoList,
-                builder.getContext(),
-                R.layout.select_account_list_item,
-                arr, id);
-
-        switch (id) {
-            case DATA_PICK:
-                builder.setTitle(R.string.select_sim_for_data);
-                break;
-            case CALLS_PICK:
-                builder.setTitle(R.string.select_sim_for_calls);
-                break;
-            case SMS_PICK:
-                builder.setTitle(R.string.select_sim_for_sms);
-                break;
-            default:
-                throw new IllegalArgumentException("Invalid dialog type "
-                        + id + " in SIM dialog.");
-        }
-
-        Dialog dialog = builder.setAdapter(adapter, selectionListener).create();
-        dialog.setOnKeyListener(keyListener);
-
-        dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
-            @Override
-            public void onCancel(DialogInterface dialogInterface) {
-                finish();
-            }
-        });
-
-        return dialog;
-
-    }
-
-    private class SelectAccountListAdapter extends ArrayAdapter<String> {
-        private Context mContext;
-        private int mResId;
-        private int mDialogId;
-        private final float OPACITY = 0.54f;
-        private List<SubscriptionInfo> mSubInfoList;
-
-        public SelectAccountListAdapter(List<SubscriptionInfo> subInfoList,
-                Context context, int resource, String[] arr, int dialogId) {
-            super(context, resource, arr);
-            mContext = context;
-            mResId = resource;
-            mDialogId = dialogId;
-            mSubInfoList = subInfoList;
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            LayoutInflater inflater = (LayoutInflater)
-                    mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-            View rowView;
-            final ViewHolder holder;
-
-            if (convertView == null) {
-                // Cache views for faster scrolling
-                rowView = inflater.inflate(mResId, null);
-                holder = new ViewHolder();
-                holder.title = (TextView) rowView.findViewById(R.id.title);
-                holder.summary = (TextView) rowView.findViewById(R.id.summary);
-                holder.icon = (ImageView) rowView.findViewById(R.id.icon);
-                rowView.setTag(holder);
-            } else {
-                rowView = convertView;
-                holder = (ViewHolder) rowView.getTag();
-            }
-
-            final SubscriptionInfo sir = mSubInfoList.get(position);
-            if (sir == null) {
-                holder.title.setText(getItem(position));
-                holder.summary.setText("");
-                holder.icon.setImageDrawable(getResources()
-                        .getDrawable(R.drawable.ic_live_help));
-                holder.icon.setAlpha(OPACITY);
-            } else {
-                holder.title.setText(sir.getDisplayName());
-                holder.summary.setText(sir.getNumber());
-                holder.icon.setImageBitmap(sir.createIconBitmap(mContext));
-            }
-            return rowView;
-        }
-
-        private class ViewHolder {
-            TextView title;
-            TextView summary;
-            ImageView icon;
-        }
-    }
 }
diff --git a/src/com/android/settings/sim/SimDialogFragment.java b/src/com/android/settings/sim/SimDialogFragment.java
new file mode 100644
index 0000000..10815fd
--- /dev/null
+++ b/src/com/android/settings/sim/SimDialogFragment.java
@@ -0,0 +1,57 @@
+/*
+ * 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.sim;
+
+import android.content.DialogInterface;
+import android.os.Bundle;
+
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;
+
+/** Common functionality for showing a dialog in SimDialogActivity. */
+public abstract class SimDialogFragment extends DialogFragment {
+    private static final String TAG = "SimDialogFragment";
+
+    private static final String KEY_TITLE_ID = "title_id";
+    private static final String KEY_DIALOG_TYPE = "dialog_type";
+
+    protected static Bundle initArguments(int dialogType, int titleResId) {
+        final Bundle args = new Bundle();
+        args.putInt(KEY_DIALOG_TYPE, dialogType);
+        args.putInt(KEY_TITLE_ID, titleResId);
+        return args;
+    }
+
+    public int getDialogType() {
+        return getArguments().getInt(KEY_DIALOG_TYPE);
+    }
+
+    public int getTitleResId() {
+        return getArguments().getInt(KEY_TITLE_ID);
+    }
+
+    @Override
+    public void onDismiss(@NonNull DialogInterface dialog) {
+        super.onDismiss(dialog);
+        final SimDialogActivity activity = (SimDialogActivity) getActivity();
+        if (activity != null && !activity.isFinishing()) {
+            activity.onFragmentDismissed(this);
+        }
+    }
+
+    public abstract void updateDialog();
+}
diff --git a/src/com/android/settings/sim/SimListDialogFragment.java b/src/com/android/settings/sim/SimListDialogFragment.java
new file mode 100644
index 0000000..f78c4e7
--- /dev/null
+++ b/src/com/android/settings/sim/SimListDialogFragment.java
@@ -0,0 +1,183 @@
+/*
+ * 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.sim;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.appcompat.app.AlertDialog;
+
+import com.android.settings.R;
+import com.android.settings.Utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Shows a dialog consisting of a list of SIMs (aka subscriptions), possibly including an additional
+ * entry indicating "ask me every time".
+ */
+public class SimListDialogFragment extends SimDialogFragment implements
+        DialogInterface.OnClickListener {
+    protected static final String KEY_INCLUDE_ASK_EVERY_TIME = "include_ask_every_time";
+
+    protected SelectSubscriptionAdapter mAdapter;
+    @VisibleForTesting
+    List<SubscriptionInfo>  mSubscriptions;
+
+    public static SimListDialogFragment newInstance(int dialogType, int titleResId,
+            boolean includeAskEveryTime) {
+        final SimListDialogFragment fragment = new SimListDialogFragment();
+        final Bundle args = initArguments(dialogType, titleResId);
+        args.putBoolean(KEY_INCLUDE_ASK_EVERY_TIME, includeAskEveryTime);
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    @NonNull
+    @Override
+    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+        mSubscriptions = new ArrayList<>();
+
+        final AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
+        builder.setTitle(getTitleResId());
+
+        mAdapter = new SelectSubscriptionAdapter(builder.getContext(), mSubscriptions);
+
+        setAdapter(builder);
+        final Dialog dialog = builder.create();
+        updateDialog();
+        return dialog;
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int selectionIndex) {
+        if (selectionIndex >= 0 && selectionIndex < mSubscriptions.size()) {
+            int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+            final SubscriptionInfo subscription = mSubscriptions.get(selectionIndex);
+            if (subscription != null) {
+                subId = subscription.getSubscriptionId();
+            }
+            final SimDialogActivity activity = (SimDialogActivity) getActivity();
+            activity.onSubscriptionSelected(getDialogType(), subId);
+        }
+    }
+
+    protected List<SubscriptionInfo> getCurrentSubscriptions() {
+        final SubscriptionManager manager = getContext().getSystemService(
+                SubscriptionManager.class);
+        return manager.getActiveSubscriptionInfoList(true);
+    }
+
+    @Override
+    public void updateDialog() {
+        List<SubscriptionInfo> currentSubscriptions = getCurrentSubscriptions();
+        if (currentSubscriptions == null) {
+            dismiss();
+            return;
+        }
+        if (getArguments().getBoolean(KEY_INCLUDE_ASK_EVERY_TIME)) {
+            final List<SubscriptionInfo> tmp = new ArrayList<>(currentSubscriptions.size() + 1);
+            tmp.add(null);
+            tmp.addAll(currentSubscriptions);
+            currentSubscriptions = tmp;
+        }
+        if (currentSubscriptions.equals(mSubscriptions)) {
+            return;
+        }
+        mSubscriptions.clear();
+        mSubscriptions.addAll(currentSubscriptions);
+        mAdapter.notifyDataSetChanged();
+    }
+
+    @VisibleForTesting
+    void setAdapter(AlertDialog.Builder builder) {
+        builder.setAdapter(mAdapter, this);
+    }
+
+    private static class SelectSubscriptionAdapter extends BaseAdapter {
+        private Context mContext;
+        private LayoutInflater mInflater;
+        List<SubscriptionInfo> mSubscriptions;
+
+        public SelectSubscriptionAdapter(Context context, List<SubscriptionInfo> subscriptions) {
+            mSubscriptions = subscriptions;
+            mContext = context;
+        }
+
+        @Override
+        public int getCount() {
+            return mSubscriptions.size();
+        }
+
+        @Override
+        public SubscriptionInfo getItem(int position) {
+            return mSubscriptions.get(position);
+        }
+
+        @Override
+        public long getItemId(int position) {
+            final SubscriptionInfo info = mSubscriptions.get(position);
+            if (info == null) {
+                return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+            }
+            return info.getSubscriptionId();
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            if (convertView == null) {
+                if (mInflater == null) {
+                    mInflater = LayoutInflater.from(parent.getContext());
+                }
+                convertView = mInflater.inflate(R.layout.select_account_list_item, parent, false);
+            }
+            final SubscriptionInfo sub = getItem(position);
+
+            final TextView title = convertView.findViewById(R.id.title);
+            final TextView summary = convertView.findViewById(R.id.summary);
+            final ImageView icon = convertView.findViewById(R.id.icon);
+
+            if (sub == null) {
+                title.setText(R.string.sim_calls_ask_first_prefs_title);
+                summary.setText("");
+                icon.setImageDrawable(mContext.getDrawable(R.drawable.ic_help));
+                icon.setImageTintList(
+                        Utils.getColorAttr(mContext, android.R.attr.textColorSecondary));
+            } else {
+                title.setText(sub.getDisplayName());
+                summary.setText(sub.getNumber());
+                icon.setImageBitmap(sub.createIconBitmap(mContext));
+
+            }
+            return convertView;
+        }
+    }
+}
diff --git a/src/com/android/settings/sim/SimSelectNotification.java b/src/com/android/settings/sim/SimSelectNotification.java
index a1e942a..3179e6a 100644
--- a/src/com/android/settings/sim/SimSelectNotification.java
+++ b/src/com/android/settings/sim/SimSelectNotification.java
@@ -29,6 +29,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
+import android.provider.Settings;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 
@@ -89,7 +90,7 @@
                 .setColor(context.getColor(R.color.sim_noitification))
                 .setContentTitle(resources.getString(R.string.sim_notification_title))
                 .setContentText(resources.getString(R.string.sim_notification_summary));
-        Intent resultIntent = new Intent(context, SimSettingsActivity.class);
+        Intent resultIntent = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
         resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         PendingIntent resultPendingIntent = PendingIntent.getActivity(context, 0, resultIntent,
                 PendingIntent.FLAG_CANCEL_CURRENT);
diff --git a/src/com/android/settings/slices/CustomSliceRegistry.java b/src/com/android/settings/slices/CustomSliceRegistry.java
index e400815..dc3324b 100644
--- a/src/com/android/settings/slices/CustomSliceRegistry.java
+++ b/src/com/android/settings/slices/CustomSliceRegistry.java
@@ -19,8 +19,6 @@
 import static android.provider.SettingsSlicesContract.KEY_LOCATION;
 import static android.provider.SettingsSlicesContract.KEY_WIFI;
 
-import static com.android.settings.notification.ZenModeSoundSettingsPreferenceController.ZEN_MODE_KEY;
-
 import android.content.ContentResolver;
 import android.net.Uri;
 import android.provider.SettingsSlicesContract;
@@ -43,6 +41,7 @@
 import com.android.settings.media.MediaOutputIndicatorSlice;
 import com.android.settings.media.MediaOutputSlice;
 import com.android.settings.network.telephony.MobileDataSlice;
+import com.android.settings.notification.ZenModeButtonPreferenceController;
 import com.android.settings.wifi.calling.WifiCallingSliceHelper;
 import com.android.settings.wifi.slice.ContextualWifiSlice;
 import com.android.settings.wifi.slice.WifiSlice;
@@ -298,7 +297,7 @@
             .scheme(ContentResolver.SCHEME_CONTENT)
             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
-            .appendPath(ZEN_MODE_KEY)
+            .appendPath(ZenModeButtonPreferenceController.KEY)
             .build();
 
     /**
diff --git a/src/com/android/settings/slices/SliceBroadcastReceiver.java b/src/com/android/settings/slices/SliceBroadcastReceiver.java
index 9926a52..fc3d0cc 100644
--- a/src/com/android/settings/slices/SliceBroadcastReceiver.java
+++ b/src/com/android/settings/slices/SliceBroadcastReceiver.java
@@ -164,11 +164,12 @@
         }
 
         final SliderPreferenceController sliderController = (SliderPreferenceController) controller;
-        final int maxSteps = sliderController.getMaxSteps();
-        if (newPosition < 0 || newPosition > maxSteps) {
+        final int minValue = sliderController.getMin();
+        final int maxValue = sliderController.getMax();
+        if (newPosition < minValue || newPosition > maxValue) {
             throw new IllegalArgumentException(
-                    "Invalid position passed to Slider controller. Expected between 0 and "
-                            + maxSteps + " but found " + newPosition);
+                    "Invalid position passed to Slider controller. Expected between " + minValue
+                            + " and " + maxValue + " but found " + newPosition);
         }
 
         sliderController.setSliderPosition(newPosition);
diff --git a/src/com/android/settings/slices/SliceBuilderUtils.java b/src/com/android/settings/slices/SliceBuilderUtils.java
index 00a82d2..aa76a9e 100644
--- a/src/com/android/settings/slices/SliceBuilderUtils.java
+++ b/src/com/android/settings/slices/SliceBuilderUtils.java
@@ -326,7 +326,8 @@
                         .setTitle(sliceData.getTitle())
                         .setSubtitle(subtitleText)
                         .setPrimaryAction(primaryAction)
-                        .setMax(sliderController.getMaxSteps())
+                        .setMax(sliderController.getMax())
+                        .setMin(sliderController.getMin())
                         .setValue(sliderController.getSliderPosition())
                         .setInputAction(actionIntent))
                 .setKeywords(keywords)
diff --git a/src/com/android/settings/widget/SeekBarPreference.java b/src/com/android/settings/widget/SeekBarPreference.java
index f4d2aac..44def11 100644
--- a/src/com/android/settings/widget/SeekBarPreference.java
+++ b/src/com/android/settings/widget/SeekBarPreference.java
@@ -93,7 +93,7 @@
 
     @Override
     public boolean isSelectable() {
-        return false;
+        return isDisabledByAdmin();
     }
 
     @Override
diff --git a/src/com/android/settings/widget/TintDrawable.java b/src/com/android/settings/widget/TintDrawable.java
new file mode 100644
index 0000000..13eb121
--- /dev/null
+++ b/src/com/android/settings/widget/TintDrawable.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.widget;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.content.res.Resources.Theme;
+import android.content.res.TypedArray;
+import android.graphics.drawable.DrawableWrapper;
+import android.util.AttributeSet;
+import android.util.Log;
+
+import com.android.settings.R;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+/**
+ * A Drawable that tints a contained Drawable, overriding the existing tint specified in the
+ * underlying drawable. This class should only be used in XML.
+ *
+ * @attr ref android.R.styleable#DrawableWrapper_drawable
+ * @attr ref R.styleable#TintDrawable_tint
+ */
+public class TintDrawable extends DrawableWrapper {
+    private ColorStateList mTint;
+    private int[] mThemeAttrs;
+
+    /** No-arg constructor used by drawable inflation. */
+    public TintDrawable() {
+        super(null);
+    }
+
+    @Override
+    public void inflate(@NonNull Resources r, @NonNull XmlPullParser parser,
+            @NonNull AttributeSet attrs, @Nullable Theme theme)
+            throws XmlPullParserException, IOException {
+        final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.TintDrawable);
+
+        super.inflate(r, parser, attrs, theme);
+
+        mThemeAttrs = a.extractThemeAttrs();
+        updateStateFromTypedArray(a);
+        a.recycle();
+
+        applyTint();
+    }
+
+    @Override
+    public void applyTheme(Theme t) {
+        super.applyTheme(t);
+
+        if (mThemeAttrs != null) {
+            final TypedArray a = t.resolveAttributes(mThemeAttrs, R.styleable.TintDrawable);
+            updateStateFromTypedArray(a);
+            a.recycle();
+        }
+
+        // Ensure tint is reapplied after applying the theme to ensure this drawables'
+        // tint overrides the underlying drawables' tint.
+        applyTint();
+    }
+
+    @Override
+    public boolean canApplyTheme() {
+        return (mThemeAttrs != null && mThemeAttrs.length > 0) || super.canApplyTheme();
+    }
+
+    private void updateStateFromTypedArray(@NonNull TypedArray a) {
+        if (a.hasValue(R.styleable.TintDrawable_android_drawable)) {
+            setDrawable(a.getDrawable(R.styleable.TintDrawable_android_drawable));
+        }
+        if (a.hasValue(R.styleable.TintDrawable_android_tint)) {
+            mTint = a.getColorStateList(R.styleable.TintDrawable_android_tint);
+        }
+    }
+
+    private void applyTint() {
+        if (getDrawable() != null && mTint != null) {
+            getDrawable().mutate().setTintList(mTint);
+        }
+    }
+}
diff --git a/src/com/android/settings/wifi/WifiDialog.java b/src/com/android/settings/wifi/WifiDialog.java
index fbea824..875f35d 100644
--- a/src/com/android/settings/wifi/WifiDialog.java
+++ b/src/com/android/settings/wifi/WifiDialog.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.wifi;
 
+import android.annotation.StyleRes;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -64,11 +65,21 @@
     public static WifiDialog createModal(Context context, WifiDialogListener listener,
             AccessPoint accessPoint, int mode) {
         return new WifiDialog(context, listener, accessPoint, mode, 0 /* style */,
-                mode == WifiConfigUiBase.MODE_VIEW /* hideSubmitButton*/);
+                mode == WifiConfigUiBase.MODE_VIEW /* hideSubmitButton */);
+    }
+
+    /**
+     * Creates a WifiDialog with customized style. It displays as a dialog above the current
+     * view.
+     */
+    public static WifiDialog createModal(Context context, WifiDialogListener listener,
+        AccessPoint accessPoint, int mode, @StyleRes int style) {
+        return new WifiDialog(context, listener, accessPoint, mode, style,
+                mode == WifiConfigUiBase.MODE_VIEW /* hideSubmitButton */);
     }
 
     /* package */ WifiDialog(Context context, WifiDialogListener listener, AccessPoint accessPoint,
-            int mode, int style, boolean hideSubmitButton) {
+            int mode, @StyleRes int style, boolean hideSubmitButton) {
         super(context, style);
         mMode = mode;
         mListener = listener;
diff --git a/src/com/android/settings/wifi/WifiDialogActivity.java b/src/com/android/settings/wifi/WifiDialogActivity.java
index 35de66e..8268ecc 100644
--- a/src/com/android/settings/wifi/WifiDialogActivity.java
+++ b/src/com/android/settings/wifi/WifiDialogActivity.java
@@ -28,6 +28,7 @@
 
 import androidx.annotation.VisibleForTesting;
 
+import com.android.settings.R;
 import com.android.settings.SetupWizardUtils;
 import com.android.settings.wifi.dpp.WifiDppUtils;
 import com.android.settingslib.wifi.AccessPoint;
@@ -74,8 +75,13 @@
             accessPoint = new AccessPoint(this, accessPointState);
         }
 
-        mDialog = WifiDialog.createModal(
-                this, this, accessPoint, WifiConfigUiBase.MODE_CONNECT);
+        if (WizardManagerHelper.isAnySetupWizard(getIntent())) {
+            mDialog = WifiDialog.createModal(this, this, accessPoint,
+                    WifiConfigUiBase.MODE_CONNECT, R.style.SuwAlertDialogThemeCompat_Light);
+        } else {
+            mDialog = WifiDialog.createModal(
+                    this, this, accessPoint, WifiConfigUiBase.MODE_CONNECT);
+        }
         mDialog.show();
         mDialog.setOnDismissListener(this);
     }
diff --git a/src/com/android/settings/wifi/WifiScanModeActivity.java b/src/com/android/settings/wifi/WifiScanModeActivity.java
index 934e972..5342729 100644
--- a/src/com/android/settings/wifi/WifiScanModeActivity.java
+++ b/src/com/android/settings/wifi/WifiScanModeActivity.java
@@ -25,6 +25,7 @@
 import android.net.wifi.WifiManager;
 import android.os.Bundle;
 import android.provider.Settings;
+import android.text.TextUtils;
 
 import androidx.appcompat.app.AlertDialog;
 import androidx.fragment.app.DialogFragment;
@@ -132,7 +133,9 @@
         @Override
         public Dialog onCreateDialog(Bundle savedInstanceState) {
             return new AlertDialog.Builder(getActivity())
-                    .setMessage(getString(R.string.wifi_scan_always_turnon_message, mApp))
+                    .setMessage(TextUtils.isEmpty(mApp) ?
+                        getString(R.string.wifi_scan_always_turn_on_message_unknown) :
+                        getString(R.string.wifi_scan_always_turnon_message, mApp))
                     .setPositiveButton(R.string.wifi_scan_always_confirm_allow,
                             new DialogInterface.OnClickListener() {
                                 public void onClick(DialogInterface dialog, int whichButton) {
diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
index 79b6383..238143e 100644
--- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
@@ -71,7 +71,6 @@
 import com.android.settings.wifi.WifiDialog.WifiDialogListener;
 import com.android.settings.wifi.WifiUtils;
 import com.android.settings.wifi.dpp.WifiDppUtils;
-import com.android.settings.wifi.savedaccesspoints.SavedAccessPointsWifiSettings;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -259,9 +258,9 @@
         public void onLost(Network network) {
             final boolean lostCurrentNetwork = network.equals(mNetwork);
             if (lostCurrentNetwork) {
-                // If support detail page for saved network, should update as disconnect but not
-                // exit. Except for ephemeral network which should not show on saved network list.
-                if (SavedAccessPointsWifiSettings.usingDetailsFragment(mContext) && !mIsEphemeral) {
+                // Should update as disconnect but not exit. Except for ephemeral network which
+                // should not show on saved network list.
+                if (!mIsEphemeral) {
                     return;
                 }
 
@@ -351,16 +350,12 @@
         mLifecycle = lifecycle;
         lifecycle.addObserver(this);
 
-        if (SavedAccessPointsWifiSettings.usingDetailsFragment(mContext)) {
-            mWifiTracker = WifiTrackerFactory.create(
-                    mFragment.getActivity(),
-                    mWifiListener,
-                    mLifecycle,
-                    true /*includeSaved*/,
-                    true /*includeScans*/);
-        } else {
-            mWifiTracker = null;
-        }
+        mWifiTracker = WifiTrackerFactory.create(
+                mFragment.getActivity(),
+                mWifiListener,
+                mLifecycle,
+                true /*includeSaved*/,
+                true /*includeScans*/);
         mConnected = mAccessPoint.isActive();
         // When lost the network connection, WifiInfo/NetworkInfo will be clear. So causes we
         // could not check if the AccessPoint is ephemeral. Need to cache it in first.
@@ -409,9 +404,7 @@
                 .setButton3Enabled(true)
                 .setButton4Text(R.string.share)
                 .setButton4Icon(R.drawable.ic_qrcode_24dp)
-                .setButton4OnClickListener(view -> shareNetwork())
-                .setButton4Visible(
-                        WifiDppUtils.isSupportConfiguratorQrCodeGenerator(mContext, mAccessPoint));
+                .setButton4OnClickListener(view -> shareNetwork());
 
         mSignalStrengthPref = screen.findPreference(KEY_SIGNAL_STRENGTH_PREF);
         mTxLinkSpeedPref = screen.findPreference(KEY_TX_LINK_SPEED);
@@ -545,11 +538,6 @@
             if (mNetwork == null || mNetworkInfo == null || mWifiInfo == null) {
                 // Once connected, can't get mNetworkInfo immediately, return false and wait for
                 // next time to update UI.
-                if (SavedAccessPointsWifiSettings.usingDetailsFragment(mContext)) {
-                    return false;
-                }
-
-                exitActivity();
                 return false;
             }
 
@@ -749,20 +737,24 @@
         mButtonsPref.setButton1Text(
                 mIsEphemeral ? R.string.wifi_disconnect_button_text : R.string.forget);
 
-        mButtonsPref.setButton1Visible(canForgetNetwork());
-        mButtonsPref.setButton2Visible(canSignIntoNetwork());
-        mButtonsPref.setButton3Visible(canConnectNetwork());
-        mButtonsPref.setButton4Visible(canShareNetwork());
-        mButtonsPref.setVisible(canSignIntoNetwork()
-                || canForgetNetwork()
-                || canShareNetwork()
-                || canConnectNetwork());
+        boolean canForgetNetwork = canForgetNetwork();
+        boolean canSignIntoNetwork = canSignIntoNetwork();
+        boolean canConnectNetwork = canConnectNetwork();
+        boolean canShareNetwork = canShareNetwork();
+
+        mButtonsPref.setButton1Visible(canForgetNetwork);
+        mButtonsPref.setButton2Visible(canSignIntoNetwork);
+        mButtonsPref.setButton3Visible(canConnectNetwork);
+        mButtonsPref.setButton4Visible(canShareNetwork);
+        mButtonsPref.setVisible(canForgetNetwork
+                || canSignIntoNetwork
+                || canConnectNetwork
+                || canShareNetwork);
     }
 
     private boolean canConnectNetwork() {
         // Display connect button for disconnected AP even not in the range.
-        return SavedAccessPointsWifiSettings.usingDetailsFragment(mContext)
-                && !mAccessPoint.isActive();
+        return !mAccessPoint.isActive();
     }
 
     private void refreshIpLayerInfo() {
@@ -854,7 +846,8 @@
      * Returns whether the user can share the network represented by this preference with QR code.
      */
     private boolean canShareNetwork() {
-        return mAccessPoint.getConfig() != null;
+        return mAccessPoint.getConfig() != null &&
+                WifiDppUtils.isSupportConfiguratorQrCodeGenerator(mContext, mAccessPoint);
     }
 
     /**
diff --git a/src/com/android/settings/wifi/dpp/WifiDppUtils.java b/src/com/android/settings/wifi/dpp/WifiDppUtils.java
index 98673d4..4644f12 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppUtils.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppUtils.java
@@ -345,6 +345,9 @@
      */
     public static boolean isSupportConfiguratorQrCodeScanner(Context context,
             AccessPoint accessPoint) {
+        if (accessPoint.isPasspoint()) {
+            return false;
+        }
         return isSupportWifiDpp(context, accessPoint.getSecurity());
     }
 
@@ -356,6 +359,9 @@
      */
     public static boolean isSupportConfiguratorQrCodeGenerator(Context context,
             AccessPoint accessPoint) {
+        if (accessPoint.isPasspoint()) {
+            return false;
+        }
         return isSupportZxing(context, accessPoint.getSecurity());
     }
 
diff --git a/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsPreferenceController.java b/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsPreferenceController.java
index 40e6e56..82c6028 100644
--- a/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsPreferenceController.java
+++ b/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsPreferenceController.java
@@ -92,7 +92,7 @@
     @Override
     public boolean onPreferenceClick(Preference preference) {
         if (mHost != null) {
-            mHost.showWifiDialog((AccessPointPreference) preference);
+            mHost.showWifiPage((AccessPointPreference) preference);
         }
         return false;
     }
diff --git a/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettings.java b/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettings.java
index 3f600e6..4daf7da 100644
--- a/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettings.java
+++ b/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettings.java
@@ -41,12 +41,10 @@
 /**
  * UI to manage saved networks/access points.
  */
-public class SavedAccessPointsWifiSettings extends DashboardFragment
-        implements WifiDialog.WifiDialogListener, DialogInterface.OnCancelListener {
+public class SavedAccessPointsWifiSettings extends DashboardFragment {
 
     private static final String TAG = "SavedAccessPoints";
 
-    private WifiManager mWifiManager;
     private Bundle mAccessPointSavedState;
     private AccessPoint mSelectedAccessPoint;
 
@@ -71,8 +69,6 @@
     @Override
     public void onAttach(Context context) {
         super.onAttach(context);
-        mWifiManager = (WifiManager) getContext()
-                .getApplicationContext().getSystemService(Context.WIFI_SERVICE);
         use(SavedAccessPointsPreferenceController.class)
                 .setHost(this);
         use(SubscribedAccessPointsPreferenceController.class)
@@ -90,7 +86,7 @@
         }
     }
 
-    public void showWifiDialog(@Nullable AccessPointPreference accessPoint) {
+    public void showWifiPage(@Nullable AccessPointPreference accessPoint) {
         removeDialog(WifiSettings.WIFI_DIALOG_ID);
 
         if (accessPoint != null) {
@@ -102,52 +98,18 @@
             mAccessPointSavedState = null;
         }
 
-        if (usingDetailsFragment(getContext())) {
-            if (mSelectedAccessPoint == null) {
-                mSelectedAccessPoint = new AccessPoint(getActivity(), mAccessPointSavedState);
-            }
-            final Bundle savedState = new Bundle();
-            mSelectedAccessPoint.saveWifiState(savedState);
-
-            new SubSettingLauncher(getContext())
-                    .setTitleText(mSelectedAccessPoint.getTitle())
-                    .setDestination(WifiNetworkDetailsFragment.class.getName())
-                    .setArguments(savedState)
-                    .setSourceMetricsCategory(getMetricsCategory())
-                    .launch();
-        } else {
-            showDialog(WifiSettings.WIFI_DIALOG_ID);
+        if (mSelectedAccessPoint == null) {
+            mSelectedAccessPoint = new AccessPoint(getActivity(), mAccessPointSavedState);
         }
-    }
+        final Bundle savedState = new Bundle();
+        mSelectedAccessPoint.saveWifiState(savedState);
 
-    @Override
-    public Dialog onCreateDialog(int dialogId) {
-        switch (dialogId) {
-            case WifiSettings.WIFI_DIALOG_ID:
-                // Modify network
-                if (mSelectedAccessPoint == null) {
-                    // Restore AP from save state
-                    mSelectedAccessPoint = new AccessPoint(getActivity(), mAccessPointSavedState);
-                    // Reset the saved access point data
-                    mAccessPointSavedState = null;
-                }
-                final WifiDialog dialog = WifiDialog.createModal(
-                        getActivity(), this, mSelectedAccessPoint, WifiConfigUiBase.MODE_VIEW);
-                dialog.setOnCancelListener(this);
-
-                return dialog;
-        }
-        return super.onCreateDialog(dialogId);
-    }
-
-    @Override
-    public int getDialogMetricsCategory(int dialogId) {
-        switch (dialogId) {
-            case WifiSettings.WIFI_DIALOG_ID:
-                return SettingsEnums.DIALOG_WIFI_SAVED_AP_EDIT;
-            default:
-                return 0;
-        }
+        new SubSettingLauncher(getContext())
+                .setTitleText(mSelectedAccessPoint.getTitle())
+                .setDestination(WifiNetworkDetailsFragment.class.getName())
+                .setArguments(savedState)
+                .setSourceMetricsCategory(getMetricsCategory())
+                .launch();
     }
 
     @Override
@@ -162,45 +124,6 @@
         }
     }
 
-    @Override
-    public void onForget(WifiDialog dialog) {
-        if (mSelectedAccessPoint != null) {
-            if (mSelectedAccessPoint.isPasspointConfig()) {
-                try {
-                    mWifiManager.removePasspointConfiguration(
-                            mSelectedAccessPoint.getPasspointFqdn());
-                } catch (RuntimeException e) {
-                    Log.e(TAG, "Failed to remove Passpoint configuration for "
-                            + mSelectedAccessPoint.getConfigName());
-                }
-                if (isSubscriptionsFeatureEnabled()) {
-                    use(SubscribedAccessPointsPreferenceController.class)
-                            .postRefreshSubscribedAccessPoints();
-                } else {
-                    use(SavedAccessPointsPreferenceController.class)
-                            .postRefreshSavedAccessPoints();
-                }
-            } else {
-                // both onSuccess/onFailure will call postRefreshSavedAccessPoints
-                mWifiManager.forget(mSelectedAccessPoint.getConfig().networkId,
-                        use(SavedAccessPointsPreferenceController.class));
-            }
-            mSelectedAccessPoint = null;
-        }
-    }
-
-    @Override
-    public void onCancel(DialogInterface dialog) {
-        mSelectedAccessPoint = null;
-    }
-
-    /**
-     * Checks if showing WifiNetworkDetailsFragment when clicking saved network item.
-     */
-    public static boolean usingDetailsFragment(Context context) {
-        return FeatureFlagUtils.isEnabled(context, FeatureFlags.WIFI_DETAILS_SAVED_SCREEN);
-    }
-
     boolean isSubscriptionsFeatureEnabled() {
         return FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.MOBILE_NETWORK_V2)
                 && FeatureFlagPersistent.isEnabled(getContext(), FeatureFlags.NETWORK_INTERNET_V2);
diff --git a/src/com/android/settings/wifi/savedaccesspoints/SubscribedAccessPointsPreferenceController.java b/src/com/android/settings/wifi/savedaccesspoints/SubscribedAccessPointsPreferenceController.java
index 8d31c82..048999a 100644
--- a/src/com/android/settings/wifi/savedaccesspoints/SubscribedAccessPointsPreferenceController.java
+++ b/src/com/android/settings/wifi/savedaccesspoints/SubscribedAccessPointsPreferenceController.java
@@ -91,7 +91,7 @@
     @Override
     public boolean onPreferenceClick(Preference preference) {
         if (mHost != null) {
-            mHost.showWifiDialog((AccessPointPreference) preference);
+            mHost.showWifiPage((AccessPointPreference) preference);
         }
         return false;
     }
diff --git a/tests/robotests/src/com/android/settings/MasterClearConfirmTest.java b/tests/robotests/src/com/android/settings/MasterClearConfirmTest.java
index 0c6903a..822eb3c 100644
--- a/tests/robotests/src/com/android/settings/MasterClearConfirmTest.java
+++ b/tests/robotests/src/com/android/settings/MasterClearConfirmTest.java
@@ -47,7 +47,7 @@
         masterClearConfirm.setSubtitle();
 
         assertThat(((TextView) masterClearConfirm.mContentView
-                .findViewById(R.id.master_clear_confirm)).getText())
+                .findViewById(R.id.sud_layout_description)).getText())
                 .isEqualTo(mActivity.getString(R.string.master_clear_final_desc_esim));
     }
 
@@ -61,7 +61,7 @@
         masterClearConfirm.setSubtitle();
 
         assertThat(((TextView) masterClearConfirm.mContentView
-                .findViewById(R.id.master_clear_confirm)).getText())
+                .findViewById(R.id.sud_layout_description)).getText())
                 .isEqualTo(mActivity.getString(R.string.master_clear_final_desc));
     }
 }
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
index 0cc9dc4..a07ffb9 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
@@ -154,19 +154,6 @@
         assertThat(preference.getSummary()).isEqualTo(mContext.getResources().getString(resId));
     }
 
-    @Test
-    public void testDarkUIModePreferenceSummary_shouldUpdateSummary() {
-        final Preference darkUIModePreference = new Preference(mContext);
-        final DarkUIPreferenceController mController;
-        doReturn(darkUIModePreference).when(mSettings).findPreference(
-            DARK_UI_MODE_PREFERENCE);
-        mController = new DarkUIPreferenceController(mContext, DARK_UI_MODE_PREFERENCE);
-        final String darkUIModeDescription = modeToDescription(mUiModeManager.getNightMode());
-        darkUIModePreference.setSummary(mController.getSummary());
-
-        assertThat(darkUIModePreference.getSummary()).isEqualTo(darkUIModeDescription);
-    }
-
     private String modeToDescription(int mode) {
         String[] values = mContext.getResources().getStringArray(R.array.dark_ui_mode_entries);
         switch (mode) {
diff --git a/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java b/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java
index 27c3e7d..58b1408 100644
--- a/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java
@@ -19,17 +19,14 @@
 import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_DRAGGING;
 import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE;
 
-import static com.android.settings.applications.manageapplications.AppFilterRegistry
-        .FILTER_APPS_ALL;
-import static com.android.settings.applications.manageapplications.ManageApplications
-        .LIST_TYPE_MAIN;
-import static com.android.settings.applications.manageapplications.ManageApplications
-        .LIST_TYPE_NOTIFICATION;
+import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_ALL;
+import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_MAIN;
+import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_NOTIFICATION;
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doNothing;
@@ -172,7 +169,7 @@
         when(searchMenu.getActionView()).thenReturn(searchView);
         when(mMenu.findItem(R.id.search_app_list_menu)).thenReturn(searchMenu);
         when(mMenu.add(anyInt() /* groupId */, anyInt() /* itemId */, anyInt() /* order */,
-            anyInt() /* titleRes */)).thenReturn(helpMenu);
+                anyInt() /* titleRes */)).thenReturn(helpMenu);
         doReturn("Test").when(mFragment).getText(anyInt() /* resId */);
         doNothing().when(mFragment).updateOptionsMenu();
 
@@ -182,9 +179,27 @@
     }
 
     @Test
+    public void onCreateOptionsMenu_hasExpandSearchFlag_shouldExpandSearchView() {
+        final SearchView searchView = mock(SearchView.class);
+        final MenuItem searchMenu = mock(MenuItem.class);
+        final MenuItem helpMenu = mock(MenuItem.class);
+        when(searchMenu.getActionView()).thenReturn(searchView);
+        when(mMenu.findItem(R.id.search_app_list_menu)).thenReturn(searchMenu);
+        when(mMenu.add(anyInt() /* groupId */, anyInt() /* itemId */, anyInt() /* order */,
+                anyInt() /* titleRes */)).thenReturn(helpMenu);
+        doReturn("Test").when(mFragment).getText(anyInt() /* resId */);
+        doNothing().when(mFragment).updateOptionsMenu();
+
+        mFragment.mExpandSearch = true;
+        mFragment.onCreateOptionsMenu(mMenu, mock(MenuInflater.class));
+
+        verify(searchMenu).expandActionView();
+    }
+
+    @Test
     public void onQueryTextChange_shouldFilterSearchInApplicationsAdapter() {
         final ManageApplications.ApplicationsAdapter adapter =
-            mock(ManageApplications.ApplicationsAdapter.class);
+                mock(ManageApplications.ApplicationsAdapter.class);
         final String query = "Test App";
         ReflectionHelpers.setField(mFragment, "mApplications", adapter);
 
@@ -289,13 +304,13 @@
         when(listContainer.getVisibility()).thenReturn(View.VISIBLE);
         ReflectionHelpers.setField(mFragment, "mListContainer", listContainer);
         ReflectionHelpers.setField(
-            mFragment, "mFilterAdapter", mock(ManageApplications.FilterSpinnerAdapter.class));
+                mFragment, "mFilterAdapter", mock(ManageApplications.FilterSpinnerAdapter.class));
         final ArrayList<ApplicationsState.AppEntry> appList = new ArrayList<>();
         appList.add(mock(ApplicationsState.AppEntry.class));
         final ManageApplications.ApplicationsAdapter adapter =
-            spy(new ManageApplications.ApplicationsAdapter(mState, mFragment,
-                AppFilterRegistry.getInstance().get(FILTER_APPS_ALL),
-                null /* savedInstanceState */));
+                spy(new ManageApplications.ApplicationsAdapter(mState, mFragment,
+                        AppFilterRegistry.getInstance().get(FILTER_APPS_ALL),
+                        null /* savedInstanceState */));
 
         adapter.onRebuildComplete(appList);
 
@@ -365,7 +380,7 @@
         ReflectionHelpers.setField(holder, "itemView", mock(View.class));
         ManageApplications.ApplicationsAdapter adapter =
                 new ManageApplications.ApplicationsAdapter(mState,
-                    mFragment, mock(AppFilterItem.class),
+                        mFragment, mock(AppFilterItem.class),
                         mock(Bundle.class));
         final ArrayList<ApplicationsState.AppEntry> appList = new ArrayList<>();
         final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
@@ -399,8 +414,8 @@
     @Test
     public void applicationsAdapter_filterSearch_emptyQuery_shouldShowFullList() {
         final ManageApplications.ApplicationsAdapter adapter =
-            new ManageApplications.ApplicationsAdapter(
-                mState, mFragment, mock(AppFilterItem.class), Bundle.EMPTY);
+                new ManageApplications.ApplicationsAdapter(
+                        mState, mFragment, mock(AppFilterItem.class), Bundle.EMPTY);
         final String[] appNames = {"Apricot", "Banana", "Cantaloupe", "Fig", "Mango"};
         ReflectionHelpers.setField(adapter, "mOriginalEntries", getTestAppList(appNames));
 
@@ -412,8 +427,8 @@
     @Test
     public void applicationsAdapter_filterSearch_noMatch_shouldShowEmptyList() {
         final ManageApplications.ApplicationsAdapter adapter =
-            new ManageApplications.ApplicationsAdapter(
-                mState, mFragment, mock(AppFilterItem.class), Bundle.EMPTY);
+                new ManageApplications.ApplicationsAdapter(
+                        mState, mFragment, mock(AppFilterItem.class), Bundle.EMPTY);
         final String[] appNames = {"Apricot", "Banana", "Cantaloupe", "Fig", "Mango"};
         ReflectionHelpers.setField(adapter, "mOriginalEntries", getTestAppList(appNames));
 
@@ -425,8 +440,8 @@
     @Test
     public void applicationsAdapter_filterSearch_shouldShowMatchedItemsOnly() {
         final ManageApplications.ApplicationsAdapter adapter =
-            new ManageApplications.ApplicationsAdapter(
-                mState, mFragment, mock(AppFilterItem.class), Bundle.EMPTY);
+                new ManageApplications.ApplicationsAdapter(
+                        mState, mFragment, mock(AppFilterItem.class), Bundle.EMPTY);
         final String[] appNames = {"Apricot", "Banana", "Cantaloupe", "Fig", "Mango"};
         ReflectionHelpers.setField(adapter, "mOriginalEntries", getTestAppList(appNames));
 
diff --git a/tests/robotests/src/com/android/settings/backup/BackupInactivePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/backup/BackupInactivePreferenceControllerTest.java
index 1d8d028..669aabb 100644
--- a/tests/robotests/src/com/android/settings/backup/BackupInactivePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/backup/BackupInactivePreferenceControllerTest.java
@@ -31,8 +31,10 @@
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 
+import static com.android.settings.backup.UserBackupSettingsActivityTest.ShadowBackupSettingsHelper;
+
 @RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowPrivacySettingsUtils.class})
+@Config(shadows = {ShadowPrivacySettingsUtils.class, ShadowBackupSettingsHelper.class})
 public class BackupInactivePreferenceControllerTest {
     private Context mContext;
     private BackupInactivePreferenceController mController;
@@ -48,18 +50,32 @@
     @After
     public void tearDown() {
         ShadowPrivacySettingsUtils.reset();
+        ShadowBackupSettingsHelper.reset();
     }
 
     @Test
-    public void getAvailabilityStatus_isnotInvisibleKey_shouldBeAvailable() {
+    public void getAvailabilityStatus_isnotInvisibleKey_showBackup_shouldBeAvailable() {
         ShadowPrivacySettingsUtils.setIsInvisibleKey(false);
+        ShadowBackupSettingsHelper.showBackupSettingsForUser = true;
+
         assertThat(mController.getAvailabilityStatus())
                 .isEqualTo(BasePreferenceController.AVAILABLE);
     }
 
     @Test
+    public void getAvailabilityStatus_isnotInvisibleKey_dontShowBackup_shouldBeUnsearchable() {
+        ShadowPrivacySettingsUtils.setIsInvisibleKey(false);
+        ShadowBackupSettingsHelper.showBackupSettingsForUser = false;
+
+        assertThat(mController.getAvailabilityStatus())
+                .isEqualTo(BasePreferenceController.AVAILABLE_UNSEARCHABLE);
+    }
+
+    @Test
     public void getAvailabilityStatus_isInvisibleKey_shouldBeDisabledUnsupported() {
         ShadowPrivacySettingsUtils.setIsInvisibleKey(true);
+        ShadowBackupSettingsHelper.showBackupSettingsForUser = true;
+
         assertThat(mController.getAvailabilityStatus())
                 .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
     }
diff --git a/tests/robotests/src/com/android/settings/backup/UserBackupSettingsActivityTest.java b/tests/robotests/src/com/android/settings/backup/UserBackupSettingsActivityTest.java
index 19a6051..9c5a11a 100644
--- a/tests/robotests/src/com/android/settings/backup/UserBackupSettingsActivityTest.java
+++ b/tests/robotests/src/com/android/settings/backup/UserBackupSettingsActivityTest.java
@@ -29,7 +29,6 @@
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.os.UserHandle;
 
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentManager;
@@ -53,8 +52,7 @@
 import org.robolectric.shadows.ShadowPackageManager;
 
 @RunWith(RobolectricTestRunner.class)
-@Config(shadows = {UserBackupSettingsActivityTest.ShadowBackupSettingsHelper.class,
-                UserBackupSettingsActivityTest.ShadowUserHandle.class})
+@Config(shadows = {UserBackupSettingsActivityTest.ShadowBackupSettingsHelper.class})
 public class UserBackupSettingsActivityTest {
     private ActivityController<UserBackupSettingsActivity> mActivityController;
     private UserBackupSettingsActivity mActivity;
@@ -85,7 +83,7 @@
 
     @After
     public void resetShadows() {
-        ShadowUserHandle.reset();
+        ShadowBackupSettingsHelper.reset();
     }
 
     @Test
@@ -125,7 +123,9 @@
     }
 
     @Test
-    public void getNonIndexableKeys_SystemUser() {
+    public void getNonIndexableKeys_whenShowBackupSettings() {
+        ShadowBackupSettingsHelper.showBackupSettingsForUser = true;
+
         assertThat(UserBackupSettingsActivity.SEARCH_INDEX_DATA_PROVIDER.getRawDataToIndex(
                 mApplication, true)).isNotEmpty();
         assertThat(UserBackupSettingsActivity.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(
@@ -133,17 +133,24 @@
     }
 
     @Test
-    public void getNonIndexableKeys_NonSystemUser() {
-        ShadowUserHandle.setUid(1); // Non-SYSTEM user.
+    public void getNonIndexableKeys_whenDontShowBackupSettings() {
+        ShadowBackupSettingsHelper.showBackupSettingsForUser = false;
 
         assertThat(UserBackupSettingsActivity.SEARCH_INDEX_DATA_PROVIDER.getRawDataToIndex(
             mApplication, true)).isNotEmpty();
         assertThat(UserBackupSettingsActivity.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(
-            mApplication)).isEmpty();
+            mApplication)).contains("Backup");
     }
 
     @Implements(BackupSettingsHelper.class)
     public static class ShadowBackupSettingsHelper {
+        static boolean showBackupSettingsForUser = true;
+
+        @Implementation
+        public boolean showBackupSettingsForUser() {
+            return showBackupSettingsForUser;
+        }
+
         @Implementation
         protected Intent getIntentForBackupSettings() {
             return mIntent;
@@ -153,24 +160,10 @@
         protected boolean isBackupProvidedByManufacturer() {
             return mIsBackupProvidedByOEM;
         }
-    }
-
-    @Implements(UserHandle.class)
-    public static class ShadowUserHandle {
-        private static int sUid = 0; // SYSTEM by default
-
-        public static void setUid(int uid) {
-            sUid = uid;
-        }
-
-        @Implementation
-        protected static int myUserId() {
-            return sUid;
-        }
 
         @Resetter
         public static void reset() {
-            sUid = 0;
+            showBackupSettingsForUser = true;
         }
     }
 }
diff --git a/tests/robotests/src/com/android/settings/core/SettingsSliderPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/core/SettingsSliderPreferenceControllerTest.java
index ba9cd5d..a04ec37 100644
--- a/tests/robotests/src/com/android/settings/core/SettingsSliderPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/core/SettingsSliderPreferenceControllerTest.java
@@ -41,7 +41,8 @@
                 "key");
 
         mPreference.setContinuousUpdates(true);
-        mPreference.setMax(mSliderController.getMaxSteps());
+        mPreference.setMin(mSliderController.getMin());
+        mPreference.setMax(mSliderController.getMax());
     }
 
     @Test
@@ -89,11 +90,16 @@
         }
 
         @Override
-        public int getMaxSteps() {
+        public int getMax() {
             return MAX_STEPS;
         }
 
         @Override
+        public int getMin() {
+            return 0;
+        }
+
+        @Override
         public int getAvailabilityStatus() {
             return AVAILABLE;
         }
diff --git a/tests/robotests/src/com/android/settings/core/SliderPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/core/SliderPreferenceControllerTest.java
index dbe7a14..ab0d9f5 100644
--- a/tests/robotests/src/com/android/settings/core/SliderPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/core/SliderPreferenceControllerTest.java
@@ -88,11 +88,16 @@
         }
 
         @Override
-        public int getMaxSteps() {
+        public int getMax() {
             return MAX_STEPS;
         }
 
         @Override
+        public int getMin() {
+            return 0;
+        }
+
+        @Override
         public int getAvailabilityStatus() {
             return AVAILABLE;
         }
diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java
index 7d042ce..9aa1c6f 100644
--- a/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java
@@ -18,22 +18,32 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.content.Context;
+import android.app.Activity;
 import android.content.Intent;
 import android.net.ConnectivityManager;
 import android.net.NetworkTemplate;
 import android.os.Bundle;
 import android.provider.Settings;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.FrameLayout;
 import android.widget.Spinner;
 
+import androidx.fragment.app.FragmentActivity;
+import androidx.preference.PreferenceManager;
+
+import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.widget.LoadingViewController;
 import com.android.settingslib.AppItem;
 import com.android.settingslib.NetworkPolicyEditor;
 import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
@@ -45,15 +55,14 @@
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
+import org.robolectric.android.controller.ActivityController;
 import org.robolectric.util.ReflectionHelpers;
 
 import java.util.ArrayList;
 import java.util.List;
 
-import androidx.fragment.app.FragmentActivity;
-import androidx.preference.PreferenceManager;
-
 @RunWith(RobolectricTestRunner.class)
 public class DataUsageListTest {
 
@@ -61,18 +70,21 @@
     private CellDataPreference.DataStateListener mListener;
     @Mock
     private TemplatePreference.NetworkServices mNetworkServices;
-    @Mock
-    private Context mContext;
+
+    private Activity mActivity;
     private DataUsageList mDataUsageList;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         FakeFeatureFactory.setupForTest();
+        final ActivityController<Activity> mActivityController =
+                Robolectric.buildActivity(Activity.class);
+        mActivity = spy(mActivityController.get());
         mNetworkServices.mPolicyEditor = mock(NetworkPolicyEditor.class);
         mDataUsageList = spy(DataUsageList.class);
 
-        doReturn(mContext).when(mDataUsageList).getContext();
+        doReturn(mActivity).when(mDataUsageList).getContext();
         ReflectionHelpers.setField(mDataUsageList, "mDataStateListener", mListener);
         ReflectionHelpers.setField(mDataUsageList, "services", mNetworkServices);
     }
@@ -86,11 +98,11 @@
 
         mDataUsageList.onResume();
 
-        verify(mListener).setListener(true, mDataUsageList.mSubId, mContext);
+        verify(mListener).setListener(true, mDataUsageList.mSubId, mActivity);
 
         mDataUsageList.onPause();
 
-        verify(mListener).setListener(false, mDataUsageList.mSubId, mContext);
+        verify(mListener).setListener(false, mDataUsageList.mSubId, mActivity);
     }
 
     @Test
@@ -140,7 +152,7 @@
         final List<NetworkCycleChartData> data = new ArrayList<>();
         final NetworkCycleChartData.Builder builder = new NetworkCycleChartData.Builder();
         builder.setStartTime(startTime)
-            .setEndTime(endTime);
+                .setEndTime(endTime);
         data.add(builder.build());
         ReflectionHelpers.setField(mDataUsageList, "mCycleData", data);
         final Spinner spinner = mock(Spinner.class);
@@ -150,14 +162,58 @@
 
         mDataUsageList.startAppDataUsage(new AppItem());
 
-        verify(mContext).startActivity(intent.capture());
+        verify(mActivity).startActivity(intent.capture());
         final Bundle arguments =
-            intent.getValue().getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
+                intent.getValue().getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
         assertThat(arguments.getLong(AppDataUsage.ARG_SELECTED_CYCLE)).isEqualTo(endTime);
         final ArrayList<Long> cycles =
-            (ArrayList) arguments.getSerializable(AppDataUsage.ARG_NETWORK_CYCLES);
+                (ArrayList) arguments.getSerializable(AppDataUsage.ARG_NETWORK_CYCLES);
         assertThat(cycles).hasSize(2);
         assertThat(cycles.get(0)).isEqualTo(endTime);
         assertThat(cycles.get(1)).isEqualTo(startTime);
     }
+
+    @Test
+    public void onViewCreated_shouldHideCycleSpinner() {
+        final View view = new View(mActivity);
+        final View header = getHeader();
+        final Spinner spinner = getSpinner(header);
+        spinner.setVisibility(View.VISIBLE);
+        doReturn(header).when(mDataUsageList).setPinnedHeaderView(anyInt());
+        doReturn(view).when(mDataUsageList).getView();
+
+        mDataUsageList.onViewCreated(view, null);
+
+        assertThat(spinner.getVisibility()).isEqualTo(View.GONE);
+    }
+
+    @Test
+    public void onLoadFinished_networkCycleDataCallback_shouldShowCycleSpinner() {
+        final LoadingViewController loadingViewController = mock(LoadingViewController.class);
+        mDataUsageList.mLoadingViewController = loadingViewController;
+        final Spinner spinner = getSpinner(getHeader());
+        spinner.setVisibility(View.INVISIBLE);
+        mDataUsageList.mCycleSpinner = spinner;
+        assertThat(spinner.getVisibility()).isEqualTo(View.INVISIBLE);
+        doNothing().when(mDataUsageList).updatePolicy();
+
+        mDataUsageList.mNetworkCycleDataCallbacks.onLoadFinished(null, null);
+
+        assertThat(spinner.getVisibility()).isEqualTo(View.VISIBLE);
+    }
+
+    private View getHeader() {
+        final View rootView = LayoutInflater.from(mActivity)
+                .inflate(R.layout.preference_list_fragment, null, false);
+        final FrameLayout pinnedHeader = rootView.findViewById(R.id.pinned_header);
+        final View header = mActivity.getLayoutInflater()
+                .inflate(R.layout.apps_filter_spinner, pinnedHeader, false);
+
+        return header;
+    }
+
+    private Spinner getSpinner(View header) {
+        final Spinner spinner = header.findViewById(R.id.filter_spinner);
+        return spinner;
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/display/AdaptiveSleepPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AdaptiveSleepPreferenceControllerTest.java
index d426e7a..9adb1ad 100644
--- a/tests/robotests/src/com/android/settings/display/AdaptiveSleepPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/AdaptiveSleepPreferenceControllerTest.java
@@ -20,15 +20,21 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.provider.Settings;
 
 import com.android.settings.R;
+import com.android.settingslib.RestrictedPreference;
 
 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;
@@ -42,6 +48,9 @@
     private AdaptiveSleepPreferenceController mController;
     private ContentResolver mContentResolver;
 
+    @Mock
+    private PackageManager mPackageManager;
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
@@ -49,6 +58,10 @@
         mContext = RuntimeEnvironment.application;
         mContentResolver = mContext.getContentResolver();
         mController = new AdaptiveSleepPreferenceController(mContext, PREFERENCE_KEY);
+
+
+        when(mPackageManager.checkPermission(any(), any())).thenReturn(
+                PackageManager.PERMISSION_GRANTED);
     }
 
     @Test
@@ -114,4 +127,24 @@
                 new AdaptiveSleepPreferenceController(mContext, "any_key");
         assertThat(controller.isSliceable()).isTrue();
     }
+
+    @Test
+    public void isChecked_returnsFalseWhenNotSufficientPermissions() {
+        when(mPackageManager.checkPermission(any(), any())).thenReturn(
+                PackageManager.PERMISSION_DENIED);
+
+        mController.setChecked(true);
+        assertThat(mController.isChecked()).isFalse();
+    }
+
+    @Test
+    public void isEnabled_returnsFalseWhenNotSufficientPermissions() {
+        when(mPackageManager.checkPermission(any(), any())).thenReturn(
+                PackageManager.PERMISSION_DENIED);
+
+        mController.setChecked(true);
+        final RestrictedPreference mPreference = new RestrictedPreference(mContext);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isEnabled()).isFalse();
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/display/DarkUIInfoDialogFragmentTest.java b/tests/robotests/src/com/android/settings/display/DarkUIInfoDialogFragmentTest.java
new file mode 100644
index 0000000..7a8bded
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/display/DarkUIInfoDialogFragmentTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.SharedPreferences;
+
+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 DarkUIInfoDialogFragmentTest {
+    private DarkUIInfoDialogFragment mFragment;
+    @Mock
+    private DialogInterface dialog;
+
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mFragment = spy(new DarkUIInfoDialogFragment());
+    }
+
+    @Test
+    public void dialogDismissedOnConfirmation() {
+        doReturn(RuntimeEnvironment.application).when(mFragment).getContext();
+        SharedPreferences prefs = RuntimeEnvironment.application.getSharedPreferences(
+                DarkUIPreferenceController.DARK_MODE_PREFS,
+                Context.MODE_PRIVATE);
+        assertThat(prefs.getBoolean(DarkUIPreferenceController.PREF_DARK_MODE_DIALOG_SEEN, false))
+                .isFalse();
+        mFragment.onClick(dialog, DialogInterface.BUTTON_POSITIVE);
+        verify(dialog, times(1)).dismiss();
+        assertThat(prefs.getBoolean(DarkUIPreferenceController.PREF_DARK_MODE_DIALOG_SEEN, false))
+                .isTrue();
+
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/display/DarkUISettingsRadioButtonsControllerTest.java b/tests/robotests/src/com/android/settings/display/DarkUISettingsRadioButtonsControllerTest.java
deleted file mode 100644
index 76142a4..0000000
--- a/tests/robotests/src/com/android/settings/display/DarkUISettingsRadioButtonsControllerTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.android.settings.display;
-
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.verify;
-
-import android.app.UiModeManager;
-import android.content.Context;
-import androidx.preference.Preference;
-import com.android.settings.R;
-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 DarkUISettingsRadioButtonsControllerTest {
-
-    @Mock
-    private UiModeManager mUiModeManager;
-    @Mock
-    private Preference mFooter;
-    private Context mContext;
-    private DarkUISettingsRadioButtonsController mController;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
-        mController = new DarkUISettingsRadioButtonsController(mContext, mFooter);
-        mController.mManager = mUiModeManager;
-    }
-
-    @Test
-    public void footerUpdatesCorrectly() {
-        doReturn(UiModeManager.MODE_NIGHT_YES).when(mUiModeManager).getNightMode();
-        mController.updateFooter();
-        verify(mFooter).setSummary(eq(R.string.dark_ui_settings_dark_summary));
-
-        doReturn(UiModeManager.MODE_NIGHT_NO).when(mUiModeManager).getNightMode();
-        mController.updateFooter();
-        verify(mFooter).setSummary(eq(R.string.dark_ui_settings_light_summary));
-    }
-
-    public int getCurrentMode() {
-        final UiModeManager uiModeManager = mContext.getSystemService(UiModeManager.class);
-        return uiModeManager.getNightMode();
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/gestures/PreventRingingSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/PreventRingingSwitchPreferenceControllerTest.java
index 85eeacc..ccb2bf6 100644
--- a/tests/robotests/src/com/android/settings/gestures/PreventRingingSwitchPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/PreventRingingSwitchPreferenceControllerTest.java
@@ -16,6 +16,10 @@
 
 package com.android.settings.gestures;
 
+import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE;
+import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
+import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
@@ -43,6 +47,9 @@
 
 @RunWith(RobolectricTestRunner.class)
 public class PreventRingingSwitchPreferenceControllerTest {
+
+    private static final int UNKNOWN = -1;
+
     private Context mContext;
     private Resources mResources;
     private PreventRingingSwitchPreferenceController mController;
@@ -76,35 +83,88 @@
     }
 
     @Test
-    public void testOn_updateState_hushOff() {
+    public void updateState_hushOff_uncheck() {
         Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE,
-                Settings.Secure.VOLUME_HUSH_OFF);
+                VOLUME_HUSH_OFF);
+
         mController.updateState(mPreference);
+
         verify(mController.mSwitch, times(1)).setChecked(false);
     }
 
     @Test
-    public void testOn_updateState_hushVibrate() {
+    public void updateState_hushVibrate_setChecked() {
         Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE,
-                Settings.Secure.VOLUME_HUSH_VIBRATE);
+                VOLUME_HUSH_VIBRATE);
+
         mController.updateState(mPreference);
+
         verify(mController.mSwitch, times(1)).setChecked(true);
     }
 
     @Test
-    public void testOn_updateState_hushMute() {
+    public void updateState_hushMute_setChecked() {
         Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE,
-                Settings.Secure.VOLUME_HUSH_MUTE);
+                VOLUME_HUSH_MUTE);
+
         mController.updateState(mPreference);
+
         verify(mController.mSwitch, times(1)).setChecked(true);
     }
 
     @Test
+    public void onSwitchChanged_wasHushOff_checked_returnHushVibrate() {
+        Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE,
+                VOLUME_HUSH_OFF);
+
+        mController.onSwitchChanged(null, true);
+
+        assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.VOLUME_HUSH_GESTURE, UNKNOWN)).isEqualTo(VOLUME_HUSH_VIBRATE);
+    }
+
+    @Test
+    public void onSwitchChanged_wasHushMute_unchecked_returnHushOff() {
+        Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE,
+                VOLUME_HUSH_MUTE);
+
+        mController.onSwitchChanged(null, false);
+
+        assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.VOLUME_HUSH_GESTURE, UNKNOWN)).isEqualTo(VOLUME_HUSH_OFF);
+    }
+
+    @Test
+    public void onSwitchChanged_wasHushMute_checked_returnHushMute() {
+        // this is the case for the page open
+        Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE,
+                VOLUME_HUSH_MUTE);
+
+        mController.onSwitchChanged(null, true);
+
+        assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.VOLUME_HUSH_GESTURE, UNKNOWN)).isEqualTo(VOLUME_HUSH_MUTE);
+    }
+
+    @Test
+    public void onSwitchChanged_wasHushVibrate_checked_returnHushVibrate() {
+        // this is the case for the page open
+        Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE,
+                VOLUME_HUSH_VIBRATE);
+
+        mController.onSwitchChanged(null, true);
+
+        assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.VOLUME_HUSH_GESTURE, UNKNOWN)).isEqualTo(VOLUME_HUSH_VIBRATE);
+    }
+
+    @Test
     public void testPreferenceClickListenerAttached() {
         PreferenceScreen preferenceScreen = mock(PreferenceScreen.class);
         LayoutPreference mLayoutPreference = mock(LayoutPreference.class);
         when(preferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
                 mLayoutPreference);
+
         mController.displayPreference(preferenceScreen);
 
         verify(mLayoutPreference, times(1))
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImplTest.java
new file mode 100644
index 0000000..e380636
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImplTest.java
@@ -0,0 +1,130 @@
+/*
+ * 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.content.Context.MODE_PRIVATE;
+
+import static com.android.settings.homepage.contextualcards.slices.ContextualNotificationChannelSlice.PREFS;
+import static com.android.settings.homepage.contextualcards.slices.ContextualNotificationChannelSlice.PREF_KEY_INTERACTED_PACKAGES;
+import static com.android.settings.slices.CustomSliceRegistry.CONTEXTUAL_NOTIFICATION_CHANNEL_SLICE_URI;
+import static com.android.settings.slices.CustomSliceRegistry.FLASHLIGHT_SLICE_URI;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.ArraySet;
+
+import androidx.core.graphics.drawable.IconCompat;
+import androidx.slice.Slice;
+import androidx.slice.SliceProvider;
+import androidx.slice.builders.ListBuilder;
+import androidx.slice.builders.SliceAction;
+import androidx.slice.widget.SliceLiveData;
+
+import com.android.settings.R;
+import com.android.settings.SettingsActivity;
+import com.android.settings.applications.AppInfoBase;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.Set;
+
+@RunWith(RobolectricTestRunner.class)
+public class ContextualCardFeatureProviderImplTest {
+
+    private Context mContext;
+    private ContextualCardFeatureProviderImpl mImpl;
+    private SharedPreferences mSharedPreferences;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mImpl = new ContextualCardFeatureProviderImpl(mContext);
+        mSharedPreferences = mContext.getSharedPreferences(PREFS, MODE_PRIVATE);
+        // Set-up specs for SliceMetadata.
+        SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
+    }
+
+    @After
+    public void tearDown() {
+        removeInteractedPackageFromSharedPreference();
+    }
+
+    @Test
+    public void logNotificationPackage_isContextualNotificationChannel_shouldLogPackage() {
+        final String packageName = "com.android.test.app";
+        final Slice slice = buildSlice(CONTEXTUAL_NOTIFICATION_CHANNEL_SLICE_URI, packageName);
+
+        mImpl.logNotificationPackage(slice);
+
+        final Set<String> interactedPackages = mSharedPreferences.getStringSet(
+                PREF_KEY_INTERACTED_PACKAGES, new ArraySet<>());
+        assertThat(interactedPackages.contains(packageName)).isTrue();
+    }
+
+    @Test
+    public void logNotificationPackage_isNotContextualNotificationChannel_shouldNotLogPackage() {
+        final String packageName = "com.android.test.app";
+        final Slice slice = buildSlice(FLASHLIGHT_SLICE_URI, packageName);
+
+        mImpl.logNotificationPackage(slice);
+
+        final Set<String> interactedPackages = mSharedPreferences.getStringSet(
+                PREF_KEY_INTERACTED_PACKAGES, new ArraySet<>());
+        assertThat(interactedPackages.contains(packageName)).isFalse();
+    }
+
+    private Slice buildSlice(Uri sliceUri, String packageName) {
+        final Bundle args = new Bundle();
+        args.putString(AppInfoBase.ARG_PACKAGE_NAME, packageName);
+        final Intent intent = new Intent("action");
+        intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS, args);
+
+        final PendingIntent pendingIntent = spy(
+                PendingIntent.getActivity(mContext, 0 /* requestCode */, intent, 0 /* flags */));
+        doReturn(intent).when(pendingIntent).getIntent();
+        final IconCompat icon = IconCompat.createWithResource(mContext, R.drawable.empty_icon);
+        final SliceAction action = SliceAction.createDeeplink(pendingIntent, icon,
+                ListBuilder.SMALL_IMAGE, "title");
+
+        return new ListBuilder(mContext, sliceUri, ListBuilder.INFINITY)
+                .addRow(new ListBuilder.RowBuilder()
+                        .addEndItem(icon, ListBuilder.ICON_IMAGE)
+                        .setTitle("title")
+                        .setPrimaryAction(action))
+                .build();
+    }
+
+    private void removeInteractedPackageFromSharedPreference() {
+        if (mSharedPreferences.contains(PREF_KEY_INTERACTED_PACKAGES)) {
+            mSharedPreferences.edit().remove(PREF_KEY_INTERACTED_PACKAGES).apply();
+        }
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSliceTest.java
index 1027cf1..dcfba42 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSliceTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSliceTest.java
@@ -18,7 +18,11 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import android.content.Context;
+import android.net.Uri;
 
 import androidx.slice.Slice;
 import androidx.slice.SliceMetadata;
@@ -26,11 +30,13 @@
 import androidx.slice.widget.SliceLiveData;
 
 import com.android.internal.os.BatteryStatsHelper;
+import com.android.settings.R;
 import com.android.settings.fuelgauge.BatteryStatsHelperLoader;
 import com.android.settings.fuelgauge.batterytip.BatteryTipLoader;
 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
 import com.android.settings.fuelgauge.batterytip.tips.EarlyWarningTip;
 import com.android.settings.fuelgauge.batterytip.tips.LowBatteryTip;
+import com.android.settings.slices.SliceBackgroundWorker;
 
 import org.junit.After;
 import org.junit.Before;
@@ -48,6 +54,10 @@
 import java.util.List;
 
 @RunWith(RobolectricTestRunner.class)
+@Config(shadows = {
+        BatteryFixSliceTest.ShadowBatteryStatsHelperLoader.class,
+        BatteryFixSliceTest.ShadowBatteryTipLoader.class
+})
 public class BatteryFixSliceTest {
 
     private Context mContext;
@@ -66,13 +76,11 @@
     @After
     public void tearDown() {
         ShadowBatteryTipLoader.reset();
+        ShadowSliceBackgroundWorker.reset();
+        ShadowEarlyWarningTip.reset();
     }
 
     @Test
-    @Config(shadows = {
-            ShadowBatteryStatsHelperLoader.class,
-            ShadowBatteryTipLoader.class
-    })
     public void updateBatteryTipAvailabilityCache_hasImportantTip_shouldReturnTrue() {
         final List<BatteryTip> tips = new ArrayList<>();
         tips.add(new LowBatteryTip(BatteryTip.StateType.INVISIBLE, false, ""));
@@ -85,10 +93,6 @@
     }
 
     @Test
-    @Config(shadows = {
-            ShadowBatteryStatsHelperLoader.class,
-            ShadowBatteryTipLoader.class
-    })
     public void getSlice_unimportantSlice_shouldSkip() {
         final List<BatteryTip> tips = new ArrayList<>();
         tips.add(new LowBatteryTip(BatteryTip.StateType.INVISIBLE, false, ""));
@@ -101,6 +105,28 @@
         assertThat(SliceMetadata.from(mContext, slice).isErrorSlice()).isTrue();
     }
 
+    @Test
+    @Config(shadows = {
+            BatteryFixSliceTest.ShadowEarlyWarningTip.class,
+            BatteryFixSliceTest.ShadowSliceBackgroundWorker.class
+    })
+    public void getSlice_hasImportantTip_shouldTintIcon() {
+        final List<BatteryTip> tips = new ArrayList<>();
+        tips.add(new EarlyWarningTip(BatteryTip.StateType.NEW, false));
+        // Create fake cache data
+        ShadowBatteryTipLoader.setBatteryTips(tips);
+        BatteryFixSlice.updateBatteryTipAvailabilityCache(mContext);
+        // Create fake background worker data
+        BatteryFixSlice.BatteryTipWorker batteryTipWorker = mock(
+                BatteryFixSlice.BatteryTipWorker.class);
+        when(batteryTipWorker.getResults()).thenReturn(tips);
+        ShadowSliceBackgroundWorker.setBatteryTipWorkerWorker(batteryTipWorker);
+
+        final Slice slice = mSlice.getSlice();
+
+        assertThat(ShadowEarlyWarningTip.isIconTintColorIdCalled()).isTrue();
+    }
+
     @Implements(BatteryStatsHelperLoader.class)
     public static class ShadowBatteryStatsHelperLoader {
 
@@ -129,4 +155,45 @@
             sBatteryTips = tips;
         }
     }
+
+    @Implements(SliceBackgroundWorker.class)
+    public static class ShadowSliceBackgroundWorker {
+
+        private static BatteryFixSlice.BatteryTipWorker sBatteryTipWorkerWorker;
+
+        @Resetter
+        public static void reset() {
+            sBatteryTipWorkerWorker = null;
+        }
+
+        @Implementation
+        protected static <T extends SliceBackgroundWorker> T getInstance(Uri uri) {
+            return (T) sBatteryTipWorkerWorker;
+        }
+
+        public static void setBatteryTipWorkerWorker(BatteryFixSlice.BatteryTipWorker worker) {
+            sBatteryTipWorkerWorker = worker;
+        }
+    }
+
+    @Implements(EarlyWarningTip.class)
+    public static class ShadowEarlyWarningTip {
+
+        private static boolean mIsGetIconTintColorIdCalled;
+
+        @Resetter
+        public static void reset() {
+            mIsGetIconTintColorIdCalled = false;
+        }
+
+        @Implementation
+        protected int getIconTintColorId() {
+            mIsGetIconTintColorIdCalled = true;
+            return R.color.battery_bad_color_light;
+        }
+
+        public static boolean isIconTintColorIdCalled() {
+            return mIsGetIconTintColorIdCalled;
+        }
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/ContextualNotificationChannelSliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/ContextualNotificationChannelSliceTest.java
index f2b87be..8541a30 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/ContextualNotificationChannelSliceTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/ContextualNotificationChannelSliceTest.java
@@ -16,30 +16,49 @@
 
 package com.android.settings.homepage.contextualcards.slices;
 
+import static android.content.Context.MODE_PRIVATE;
+
+import static com.android.settings.homepage.contextualcards.slices.ContextualNotificationChannelSlice.PREFS;
+import static com.android.settings.homepage.contextualcards.slices.ContextualNotificationChannelSlice.PREF_KEY_INTERACTED_PACKAGES;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import android.content.Context;
+import android.content.SharedPreferences;
 import android.net.Uri;
+import android.util.ArraySet;
 
 import com.android.settings.R;
 import com.android.settings.slices.CustomSliceRegistry;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 
+import java.util.Set;
+
 @RunWith(RobolectricTestRunner.class)
 public class ContextualNotificationChannelSliceTest {
 
+    private static final String PACKAGE_NAME = "package_name";
+
     private Context mContext;
     private ContextualNotificationChannelSlice mNotificationChannelSlice;
+    private SharedPreferences mSharedPreferences;
 
     @Before
     public void setUp() {
         mContext = RuntimeEnvironment.application;
         mNotificationChannelSlice = new ContextualNotificationChannelSlice(mContext);
+        mSharedPreferences = mContext.getSharedPreferences(PREFS, MODE_PRIVATE);
+    }
+
+    @After
+    public void tearDown() {
+        removeInteractedPackageFromSharedPreference();
     }
 
     @Test
@@ -55,4 +74,34 @@
 
         assertThat(subTitle).isEqualTo(mContext.getText(R.string.recently_installed_app));
     }
+
+    @Test
+    public void isUserInteracted_hasInteractedPackage_shouldBeTrue() {
+        addInteractedPackageToSharedPreference();
+
+        final boolean isInteracted = mNotificationChannelSlice.isUserInteracted(PACKAGE_NAME);
+
+        assertThat(isInteracted).isTrue();
+    }
+
+    @Test
+    public void isUserInteracted_noInteractedPackage_shouldBeFalse() {
+        final boolean isInteracted = mNotificationChannelSlice.isUserInteracted(PACKAGE_NAME);
+
+        assertThat(isInteracted).isFalse();
+    }
+
+    private void addInteractedPackageToSharedPreference() {
+        final Set<String> interactedPackages = new ArraySet<>();
+        interactedPackages.add(PACKAGE_NAME);
+
+        mSharedPreferences.edit().putStringSet(PREF_KEY_INTERACTED_PACKAGES,
+                interactedPackages).apply();
+    }
+
+    private void removeInteractedPackageFromSharedPreference() {
+        if (mSharedPreferences.contains(PREF_KEY_INTERACTED_PACKAGES)) {
+            mSharedPreferences.edit().remove(PREF_KEY_INTERACTED_PACKAGES).apply();
+        }
+    }
 }
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 12513f6..81f5797 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
@@ -26,7 +26,6 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
 import static org.robolectric.Shadows.shadowOf;
 
 import android.app.NotificationChannel;
@@ -299,6 +298,21 @@
         assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.no_suggested_app));
     }
 
+    @Test
+    @Config(shadows = ShadowRestrictedLockUtilsInternal.class)
+    public void getSlice_isInteractedPackage_shouldHaveNoSuggestedAppTitle() {
+        addMockPackageToPackageManager(true /* isRecentlyInstalled */,
+                ApplicationInfo.FLAG_INSTALLED);
+        mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */,
+                false /* isChannelBlocked */);
+        doReturn(true).when(mNotificationChannelSlice).isUserInteracted(any(String.class));
+
+        final Slice slice = mNotificationChannelSlice.getSlice();
+
+        final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
+        assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.no_suggested_app));
+    }
+
     private void addMockPackageToPackageManager(boolean isRecentlyInstalled, int flags) {
         final ApplicationInfo applicationInfo = new ApplicationInfo();
         applicationInfo.name = APP_LABEL;
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelWorkerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelWorkerTest.java
new file mode 100644
index 0000000..6ac8b70
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelWorkerTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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.slices;
+
+import static android.content.Context.MODE_PRIVATE;
+
+import static com.android.settings.homepage.contextualcards.slices.ContextualNotificationChannelSlice.PREFS;
+import static com.android.settings.homepage.contextualcards.slices.ContextualNotificationChannelSlice.PREF_KEY_INTERACTED_PACKAGES;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.robolectric.Shadows.shadowOf;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
+import android.net.Uri;
+import android.util.ArraySet;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowPackageManager;
+
+import java.util.Set;
+
+@RunWith(RobolectricTestRunner.class)
+public class NotificationChannelWorkerTest {
+    private static final Uri URI = Uri.parse("content://com.android.settings.slices/test");
+    private static final String PACKAGE_NAME = "com.test.notification.channel.slice";
+
+    private Context mContext;
+    private NotificationChannelWorker mNotificationChannelWorker;
+    private ShadowPackageManager mPackageManager;
+    private SharedPreferences mSharedPreferences;
+
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mNotificationChannelWorker = new NotificationChannelWorker(mContext, URI);
+
+        // Shadow PackageManager to add mock package.
+        mPackageManager = shadowOf(mContext.getPackageManager());
+
+        mSharedPreferences = mContext.getSharedPreferences(PREFS, MODE_PRIVATE);
+        addInteractedPackageToSharedPreference();
+    }
+
+    @After
+    public void tearDown() {
+        mPackageManager.removePackage(PACKAGE_NAME);
+        removeInteractedPackageFromSharedPreference();
+    }
+
+    @Test
+    public void onSliceUnpinned_interactedPackageIsUninstalled_shouldRemovePackage() {
+        mNotificationChannelWorker.onSliceUnpinned();
+
+        final Set<String> interactedPackages = mSharedPreferences.getStringSet(
+                PREF_KEY_INTERACTED_PACKAGES, new ArraySet<>());
+        assertThat(interactedPackages.contains(PACKAGE_NAME)).isFalse();
+    }
+
+    @Test
+    public void onSliceUnpinned_interactedPackageIsInstalled_shouldKeepPackage() {
+        mockInteractedPackageAsInstalled();
+
+        mNotificationChannelWorker.onSliceUnpinned();
+
+        final Set<String> interactedPackages = mSharedPreferences.getStringSet(
+                PREF_KEY_INTERACTED_PACKAGES, new ArraySet<>());
+        assertThat(interactedPackages.contains(PACKAGE_NAME)).isTrue();
+    }
+
+    private void mockInteractedPackageAsInstalled() {
+        final PackageInfo packageInfo = new PackageInfo();
+        packageInfo.packageName = PACKAGE_NAME;
+        mPackageManager.addPackage(packageInfo);
+    }
+
+    private void addInteractedPackageToSharedPreference() {
+        final Set<String> interactedPackages = new ArraySet<>();
+        interactedPackages.add(PACKAGE_NAME);
+
+        mSharedPreferences.edit().putStringSet(PREF_KEY_INTERACTED_PACKAGES,
+                interactedPackages).apply();
+    }
+
+    private void removeInteractedPackageFromSharedPreference() {
+        if (mSharedPreferences.contains(PREF_KEY_INTERACTED_PACKAGES)) {
+            mSharedPreferences.edit().remove(PREF_KEY_INTERACTED_PACKAGES).apply();
+        }
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
index 8bcf8b6..b8ba63c 100644
--- a/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
@@ -31,6 +31,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.net.ConnectivityManager;
+import android.os.UserManager;
 import android.provider.Settings;
 import android.telephony.SubscriptionInfo;
 import android.telephony.TelephonyManager;
@@ -65,6 +66,8 @@
     private EuiccManager mEuiccManager;
     @Mock
     private PreferenceScreen mPreferenceScreen;
+    @Mock
+    private UserManager mUserManager;
 
     private AddPreference mPreference;
     private Context mContext;
@@ -76,6 +79,7 @@
         mContext = spy(Robolectric.setupActivity(Activity.class));
         when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
         when(mContext.getSystemService(EuiccManager.class)).thenReturn(mEuiccManager);
+        when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
         when(mTelephonyManager.getNetworkCountryIso()).thenReturn("");
         when(mEuiccManager.isEnabled()).thenReturn(true);
         Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.EUICC_PROVISIONED, 1);
@@ -97,10 +101,23 @@
         final ConnectivityManager cm = mock(ConnectivityManager.class);
         when(cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
         when(mContext.getSystemService(ConnectivityManager.class)).thenReturn(cm);
+        when(mUserManager.isAdminUser()).thenReturn(true);
+
         assertThat(mController.isAvailable()).isFalse();
     }
 
     @Test
+    public void isAvailable_secondaryUser_notAvailable() {
+        final ConnectivityManager cm = mock(ConnectivityManager.class);
+        when(cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(true);
+        when(mContext.getSystemService(ConnectivityManager.class)).thenReturn(cm);
+        when(mUserManager.isAdminUser()).thenReturn(false);
+
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+
+    @Test
     public void getSummary_noSubscriptions_correctSummaryAndClickHandler() {
         mController.displayPreference(mPreferenceScreen);
         mController.onResume();
@@ -283,6 +300,18 @@
     }
 
     @Test
+    public void onResume_noSubscriptionEsimDisabled_isDisabled() {
+        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0);
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(null);
+        when(mEuiccManager.isEnabled()).thenReturn(false);
+        mController.displayPreference(mPreferenceScreen);
+
+        mController.onResume();
+
+        assertThat(mPreference.isEnabled()).isFalse();
+    }
+
+    @Test
     public void onAirplaneModeChanged_oneSubscriptionAirplaneModeGetsTurnedOn_isDisabled() {
         final SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
         SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1));
diff --git a/tests/robotests/src/com/android/settings/notification/AdjustVolumeRestrictedPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/AdjustVolumeRestrictedPreferenceControllerTest.java
index 3126cdf..de00189 100644
--- a/tests/robotests/src/com/android/settings/notification/AdjustVolumeRestrictedPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/AdjustVolumeRestrictedPreferenceControllerTest.java
@@ -121,7 +121,12 @@
         }
 
         @Override
-        public int getMaxSteps() {
+        public int getMax() {
+            return 0;
+        }
+
+        @Override
+        public int getMin() {
             return 0;
         }
     }
diff --git a/tests/robotests/src/com/android/settings/notification/RemoteVolumePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/RemoteVolumePreferenceControllerTest.java
index 1e68de5..175599a 100644
--- a/tests/robotests/src/com/android/settings/notification/RemoteVolumePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/RemoteVolumePreferenceControllerTest.java
@@ -29,10 +29,12 @@
 import android.media.session.MediaSessionManager;
 
 import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Answers;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
@@ -50,9 +52,9 @@
     private MediaSessionManager mMediaSessionManager;
     @Mock
     private MediaController mMediaController;
-    @Mock
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private ISessionController mStub;
-    @Mock
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private ISessionController mStub2;
     private MediaSession.Token mToken;
     private MediaSession.Token mToken2;
@@ -78,22 +80,30 @@
         mPlaybackInfo = new MediaController.PlaybackInfo(
                 MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE, 0, MAX_POS, CURRENT_POS, null);
         when(mMediaController.getPlaybackInfo()).thenReturn(mPlaybackInfo);
+        when(mMediaController.getSessionToken()).thenReturn(mToken);
     }
 
     @Test
-    public void isAvailable_containRemoteMedia_returnTrue() {
+    public void getActiveRemoteToken_containRemoteMedia_returnToken() {
         when(mMediaController.getPlaybackInfo()).thenReturn(
                 new MediaController.PlaybackInfo(MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE,
                         0, 0, 0, null));
-        assertThat(mController.isAvailable()).isTrue();
+        assertThat(mController.getActiveRemoteToken(mContext)).isEqualTo(mToken);
     }
 
     @Test
-    public void isAvailable_noRemoteMedia_returnFalse() {
+    public void getActiveRemoteToken_noRemoteMedia_returnNull() {
         when(mMediaController.getPlaybackInfo()).thenReturn(
                 new MediaController.PlaybackInfo(MediaController.PlaybackInfo.PLAYBACK_TYPE_LOCAL,
                         0, 0, 0, null));
-        assertThat(mController.isAvailable()).isFalse();
+        assertThat(mController.getActiveRemoteToken(mContext)).isNull();
+    }
+
+    @Test
+    public void isAvailable_returnAvailableUnsearchable() {
+        assertThat(mController.isAvailable()).isTrue();
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BasePreferenceController.AVAILABLE_UNSEARCHABLE);
     }
 
     @Test
@@ -122,17 +132,31 @@
     }
 
     @Test
-    public void getMaxSteps_controllerNull_returnZero() {
+    public void getMinValue_controllerNull_returnZero() {
         mController.mMediaController = null;
 
-        assertThat(mController.getMaxSteps()).isEqualTo(0);
+        assertThat(mController.getMin()).isEqualTo(0);
     }
 
     @Test
-    public void getMaxSteps_controllerExists_returnValue() {
+    public void getMinValue_controllerExists_returnValue() {
         mController.mMediaController = mMediaController;
 
-        assertThat(mController.getMaxSteps()).isEqualTo(MAX_POS);
+        assertThat(mController.getMin()).isEqualTo(0);
+    }
+
+    @Test
+    public void getMaxValue_controllerNull_returnZero() {
+        mController.mMediaController = null;
+
+        assertThat(mController.getMax()).isEqualTo(0);
+    }
+
+    @Test
+    public void getMaxValue_controllerExists_returnValue() {
+        mController.mMediaController = mMediaController;
+
+        assertThat(mController.getMax()).isEqualTo(MAX_POS);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java
index a9e74b7..2d54c38 100644
--- a/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java
@@ -106,8 +106,10 @@
     public void sliderMethods_handleNullPreference() {
         when(mHelper.getStreamVolume(mController.getAudioStream())).thenReturn(4);
         when(mHelper.getMaxVolume(mController.getAudioStream())).thenReturn(10);
+        when(mHelper.getMinVolume(mController.getAudioStream())).thenReturn(1);
 
-        assertThat(mController.getMaxSteps()).isEqualTo(10);
+        assertThat(mController.getMax()).isEqualTo(10);
+        assertThat(mController.getMin()).isEqualTo(1);
         assertThat(mController.getSliderPosition()).isEqualTo(4);
 
         mController.setSliderPosition(9);
@@ -123,11 +125,19 @@
     }
 
     @Test
-    public void getMaxSteps_passesAlongValue() {
+    public void getMaxValue_passesAlongValue() {
         when(mPreference.getMax()).thenReturn(6);
         mController.displayPreference(mScreen);
 
-        assertThat(mController.getMaxSteps()).isEqualTo(6);
+        assertThat(mController.getMax()).isEqualTo(6);
+    }
+
+    @Test
+    public void getMinValue_passesAlongValue() {
+        when(mPreference.getMin()).thenReturn(1);
+        mController.displayPreference(mScreen);
+
+        assertThat(mController.getMin()).isEqualTo(1);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeSoundSettingsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeSoundSettingsPreferenceControllerTest.java
deleted file mode 100644
index a08a4d7..0000000
--- a/tests/robotests/src/com/android/settings/notification/ZenModeSoundSettingsPreferenceControllerTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.notification;
-
-import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.Context;
-
-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;
-
-@RunWith(RobolectricTestRunner.class)
-public class ZenModeSoundSettingsPreferenceControllerTest {
-
-    private Context mContext;
-    private ZenModeSoundSettingsPreferenceController mController;
-    private static final String KEY_ZEN_MODE = "zen_mode";
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
-        mController = new ZenModeSoundSettingsPreferenceController(mContext, KEY_ZEN_MODE);
-    }
-
-    @Test
-    public void getAvailabilityStatus_available() {
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java b/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java
index be8d8bc..fd2e806 100644
--- a/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java
@@ -26,6 +26,7 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.Context;
+import android.net.Uri;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -81,12 +82,16 @@
     }
 
     @Test
-    public void onCreateView_adapterGetsDataset() {
+    public void onCreateView_countdownLatch_setup() {
         mPanelFragment.onCreateView(LayoutInflater.from(mContext),
                 new LinearLayout(mContext), null);
-        PanelSlicesAdapter adapter = mPanelFragment.mAdapter;
+        PanelSlicesLoaderCountdownLatch countdownLatch =
+                mPanelFragment.mPanelSlicesLoaderCountdownLatch;
+        for (Uri sliecUri: mFakePanelContent.getSlices()) {
+            countdownLatch.markSliceLoaded(sliecUri);
+        }
 
-        assertThat(adapter.getData()).containsAllIn(mFakePanelContent.getSlices());
+        assertThat(countdownLatch.isPanelReadyToLoad()).isTrue();
     }
 
     @Test
@@ -100,6 +105,16 @@
     }
 
     @Test
+    public void onDestroy_logCloseEvent() {
+        mPanelFragment.onDestroy();
+        verify(mFakeFeatureFactory.metricsFeatureProvider).action(
+                0,
+                SettingsEnums.PAGE_VISIBLE,
+                mFakePanelContent.getMetricsCategory(),
+                any(String.class),
+                0);    }
+
+    @Test
     public void panelSeeMoreClick_logsCloseEvent() {
         final View.OnClickListener listener = mPanelFragment.getSeeMoreListener();
 
diff --git a/tests/robotests/src/com/android/settings/panel/PanelSlicesAdapterTest.java b/tests/robotests/src/com/android/settings/panel/PanelSlicesAdapterTest.java
index 9795b55..14a7db9 100644
--- a/tests/robotests/src/com/android/settings/panel/PanelSlicesAdapterTest.java
+++ b/tests/robotests/src/com/android/settings/panel/PanelSlicesAdapterTest.java
@@ -23,41 +23,53 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
 
-import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.content.Intent;
 import android.net.Uri;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 
+import androidx.lifecycle.LiveData;
+import androidx.slice.Slice;
+
 import com.android.settings.R;
+import com.android.settings.slices.CustomSliceRegistry;
 import com.android.settings.testutils.FakeFeatureFactory;
 
 import org.junit.Before;
 import org.junit.runner.RunWith;
-import org.robolectric.Robolectric;
-
 import org.junit.Test;
-
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.android.controller.ActivityController;
 
-import java.util.Arrays;
+import java.util.ArrayList;
 import java.util.List;
 
 @RunWith(RobolectricTestRunner.class)
 public class PanelSlicesAdapterTest {
 
+    private static final Uri DATA_URI = CustomSliceRegistry.DATA_USAGE_SLICE_URI;
+
     private Context mContext;
     private PanelFragment mPanelFragment;
-    private FakePanelContent mFakePanelContent;
-    private FakeFeatureFactory mFakeFeatureFactory;
     private PanelFeatureProvider mPanelFeatureProvider;
+    private FakeFeatureFactory mFakeFeatureFactory;
+    private FakePanelContent mFakePanelContent;
+    private List<LiveData<Slice>> mData = new ArrayList<>();
+
+    @Mock
+    private LiveData<Slice> mLiveData;
+
+    private Slice mSlice;
 
     @Before
     public void setUp() {
+        MockitoAnnotations.initMocks(this);
         mContext = RuntimeEnvironment.application;
 
         mPanelFeatureProvider = spy(new PanelFeatureProviderImpl());
@@ -76,12 +88,22 @@
                                 .get()
                                 .getSupportFragmentManager()
                                 .findFragmentById(R.id.main_content));
+
+    }
+
+    private void constructTestLiveData(Uri uri) {
+        // Create a slice to return for the LiveData
+        mSlice = spy(new Slice());
+        doReturn(uri).when(mSlice).getUri();
+        when(mLiveData.getValue()).thenReturn(mSlice);
+        mData.add(mLiveData);
     }
 
     @Test
     public void onCreateViewHolder_returnsSliceRowViewHolder() {
+        constructTestLiveData(DATA_URI);
         final PanelSlicesAdapter adapter =
-                new PanelSlicesAdapter(mPanelFragment, mFakePanelContent);
+                new PanelSlicesAdapter(mPanelFragment, mData, 0 /* metrics category */);
         final ViewGroup view = new FrameLayout(mContext);
         final PanelSlicesAdapter.SliceRowViewHolder viewHolder =
                 adapter.onCreateViewHolder(view, 0);
@@ -90,23 +112,10 @@
     }
 
     @Test
-    public void onBindViewHolder_bindsSlice() {
-        final PanelSlicesAdapter adapter =
-                new PanelSlicesAdapter(mPanelFragment, mFakePanelContent);
-        final int position = 0;
-        final ViewGroup view = new FrameLayout(mContext);
-        final PanelSlicesAdapter.SliceRowViewHolder viewHolder =
-                adapter.onCreateViewHolder(view, 0 /* view type*/);
-
-        adapter.onBindViewHolder(viewHolder, position);
-
-        assertThat(viewHolder.sliceLiveData).isNotNull();
-    }
-
-    @Test
     public void nonMediaOutputIndicatorSlice_shouldAllowDividerAboveAndBelow() {
+        constructTestLiveData(DATA_URI);
         final PanelSlicesAdapter adapter =
-                new PanelSlicesAdapter(mPanelFragment, mFakePanelContent);
+                new PanelSlicesAdapter(mPanelFragment, mData, 0 /* metrics category */);
         final int position = 0;
         final ViewGroup view = new FrameLayout(mContext);
         final PanelSlicesAdapter.SliceRowViewHolder viewHolder =
@@ -120,32 +129,10 @@
 
     @Test
     public void mediaOutputIndicatorSlice_shouldNotAllowDividerAbove() {
-        PanelContent mediaOutputIndicatorSlicePanelContent = new PanelContent() {
-            @Override
-            public CharSequence getTitle() {
-                return "title";
-            }
-
-            @Override
-            public List<Uri> getSlices() {
-                return Arrays.asList(
-                        MEDIA_OUTPUT_INDICATOR_SLICE_URI
-                );
-            }
-
-            @Override
-            public Intent getSeeMoreIntent() {
-                return new Intent();
-            }
-
-            @Override
-            public int getMetricsCategory() {
-                return SettingsEnums.TESTING;
-            }
-        };
+        constructTestLiveData(MEDIA_OUTPUT_INDICATOR_SLICE_URI);
 
         final PanelSlicesAdapter adapter =
-                new PanelSlicesAdapter(mPanelFragment, mediaOutputIndicatorSlicePanelContent);
+                new PanelSlicesAdapter(mPanelFragment, mData, 0 /* metrics category */);
         final int position = 0;
         final ViewGroup view = new FrameLayout(mContext);
         final PanelSlicesAdapter.SliceRowViewHolder viewHolder =
diff --git a/tests/robotests/src/com/android/settings/panel/PanelSlicesLoaderCountdownLatchTest.java b/tests/robotests/src/com/android/settings/panel/PanelSlicesLoaderCountdownLatchTest.java
new file mode 100644
index 0000000..dd8a91f
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/panel/PanelSlicesLoaderCountdownLatchTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.panel;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+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;
+
+@RunWith(RobolectricTestRunner.class)
+public class PanelSlicesLoaderCountdownLatchTest {
+
+    private Context mContext;
+    private PanelSlicesLoaderCountdownLatch mSliceCountdownLatch;
+
+    private static final Uri[] URIS = new Uri[] {
+      Uri.parse("content://testUri"),
+      Uri.parse("content://wowUri"),
+      Uri.parse("content://boxTurtle")
+    };
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mSliceCountdownLatch = new PanelSlicesLoaderCountdownLatch(URIS.length);
+    }
+
+
+    @Test
+    public void hasLoaded_newObject_returnsFalse() {
+        assertThat(mSliceCountdownLatch.isSliceLoaded(URIS[0])).isFalse();
+    }
+
+    @Test
+    public void hasLoaded_markSliceLoaded_returnsTrue() {
+        mSliceCountdownLatch.markSliceLoaded(URIS[0]);
+
+        assertThat(mSliceCountdownLatch.isSliceLoaded(URIS[0])).isTrue();
+    }
+
+    @Test
+    public void markSliceLoaded_onlyCountsDownUniqueUris() {
+        for (int i = 0; i < URIS.length; i++) {
+            mSliceCountdownLatch.markSliceLoaded(URIS[0]);
+        }
+
+        assertThat(mSliceCountdownLatch.isPanelReadyToLoad()).isFalse();
+    }
+
+    @Test
+    public void areSlicesReadyToLoad_allSlicesLoaded_returnsTrue() {
+        for (int i = 0; i < URIS.length; i++) {
+            mSliceCountdownLatch.markSliceLoaded(URIS[i]);
+        }
+
+        assertThat(mSliceCountdownLatch.isPanelReadyToLoad()).isTrue();
+    }
+
+    @Test
+    public void areSlicesReadyToLoad_onlyReturnsTrueOnce() {
+        for (int i = 0; i < URIS.length; i++) {
+            mSliceCountdownLatch.markSliceLoaded(URIS[i]);
+        }
+
+        // Verify that it returns true once
+        assertThat(mSliceCountdownLatch.isPanelReadyToLoad()).isTrue();
+        // Verify the second call returns false without external state change
+        assertThat(mSliceCountdownLatch.isPanelReadyToLoad()).isFalse();
+    }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java b/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
index 1d5c3c2..fa15aa0 100644
--- a/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
+++ b/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
@@ -99,7 +99,7 @@
                 0,
                 SettingsEnums.PAGE_HIDE,
                 SettingsEnums.TESTING,
-                PanelLoggingContract.PanelClosedKeys.KEY_CLICKED_OUT,
+                PanelLoggingContract.PanelClosedKeys.KEY_OTHERS,
                 0
         );
     }
diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java
index a1db12c..c692f55 100644
--- a/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java
+++ b/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java
@@ -224,7 +224,7 @@
         initActivity(null);
 
         mFragment.onActivityResult(
-                ChooseLockGenericFragment.CHOOSE_LOCK_BEFORE_FINGERPRINT_REQUEST,
+                ChooseLockGenericFragment.CHOOSE_LOCK_BEFORE_BIOMETRIC_REQUEST,
                 BiometricEnrollBase.RESULT_FINISHED, null /* data */);
 
         assertThat(mActivity.isFinishing()).isTrue();
diff --git a/tests/robotests/src/com/android/settings/sim/PreferredSimDialogFragmentTest.java b/tests/robotests/src/com/android/settings/sim/PreferredSimDialogFragmentTest.java
new file mode 100644
index 0000000..0b85c37
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/sim/PreferredSimDialogFragmentTest.java
@@ -0,0 +1,122 @@
+/*
+ * 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.sim;
+
+import static com.android.settings.sim.SimDialogActivity.PREFERRED_PICK;
+import static com.android.settings.sim.SimDialogActivity.PREFERRED_SIM;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.DialogInterface;
+
+import androidx.appcompat.app.AlertDialog;
+
+import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowAlertDialogCompat.class)
+public class PreferredSimDialogFragmentTest extends
+        SimDialogFragmentTestBase<PreferredSimDialogFragment> {
+
+    @Override
+    public void setUp() {
+        super.setUp();
+        setDialogType(PREFERRED_PICK);
+        mFragment = spy(PreferredSimDialogFragment.newInstance());
+        doReturn(mSubscriptionManager).when(mFragment).getSubscriptionManager();
+    }
+
+    @Test
+    public void onCreateDialog_noSims_dismissed() {
+        when(mSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(anyInt()))
+                .thenReturn(null);
+        mIntent.putExtra(PREFERRED_SIM, 0);
+        startDialog();
+        verify(mFragment).dismiss();
+    }
+
+    @Test
+    public void onCreateDialog_oneSimWrongSlotArgument_dismissed() {
+        when(mSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(1)).thenReturn(null);
+        mIntent.putExtra(PREFERRED_SIM, 1);
+        startDialog();
+        verify(mFragment).dismiss();
+    }
+
+    @Test
+    public void onCreateDialog_twoSimsSelectFirst_correctMessage() {
+        mIntent.putExtra(PREFERRED_SIM, 0);
+
+        final AlertDialog alertDialog = startDialog();
+        final ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(alertDialog);
+        final String message = (String) shadowDialog.getMessage();
+        assertThat(message).contains(SIM1_NAME);
+        assertThat(message).doesNotContain(SIM2_NAME);
+    }
+
+    @Test
+    public void onCreateDialog_twoSimsSelectSecond_correctMessage() {
+        mIntent.putExtra(PREFERRED_SIM, 1);
+
+        final AlertDialog alertDialog = startDialog();
+        final ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(alertDialog);
+        final String message = (String) shadowDialog.getMessage();
+        assertThat(message).contains(SIM2_NAME);
+        assertThat(message).doesNotContain(SIM1_NAME);
+    }
+
+    @Test
+    public void onClick_yesClicked_callsOnSubscriptionSelected() {
+        mIntent.putExtra(PREFERRED_SIM, 0);
+
+        final AlertDialog alertDialog = startDialog();
+
+        final SimDialogActivity activity = (SimDialogActivity) spy(mFragment.getActivity());
+        doReturn(activity).when(mFragment).getActivity();
+        doNothing().when(activity).onSubscriptionSelected(anyInt(), anyInt());
+
+        mFragment.onClick(alertDialog, DialogInterface.BUTTON_POSITIVE);
+        verify(activity).onSubscriptionSelected(PREFERRED_PICK, SIM1_ID);
+    }
+
+    @Test
+    public void onClick_noClicked_doesNotCallOnSubscriptionSelected() {
+        mIntent.putExtra(PREFERRED_SIM, 0);
+
+        final AlertDialog alertDialog = startDialog();
+
+        final SimDialogActivity activity = (SimDialogActivity) spy(mFragment.getActivity());
+        doReturn(activity).when(mFragment).getActivity();
+        doNothing().when(activity).onSubscriptionSelected(anyInt(), anyInt());
+
+        mFragment.onClick(alertDialog, DialogInterface.BUTTON_NEGATIVE);
+        verify(activity, never()).onSubscriptionSelected(anyInt(), anyInt());
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/sim/SimDialogFragmentTestBase.java b/tests/robotests/src/com/android/settings/sim/SimDialogFragmentTestBase.java
new file mode 100644
index 0000000..904b831
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/sim/SimDialogFragmentTestBase.java
@@ -0,0 +1,76 @@
+/*
+ * 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.sim;
+
+import static com.android.settings.sim.SimDialogActivity.DIALOG_TYPE_KEY;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Intent;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+
+import androidx.appcompat.app.AlertDialog;
+
+import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
+
+import org.junit.Before;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.shadows.androidx.fragment.FragmentController;
+
+public abstract class SimDialogFragmentTestBase<T extends SimDialogFragment> {
+    protected static final int SIM1_ID = 111;
+    protected static final int SIM2_ID = 222;
+    protected static final String SIM1_NAME = "sim111";
+    protected static final String SIM2_NAME = "sim222";
+
+    @Mock
+    protected SubscriptionManager mSubscriptionManager;
+    @Mock
+    protected SubscriptionInfo mSim1;
+    @Mock
+    protected SubscriptionInfo mSim2;
+
+    protected T mFragment;
+    protected Intent mIntent;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mIntent = new Intent();
+
+        when(mSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(0)).thenReturn(mSim1);
+        when(mSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(1)).thenReturn(mSim2);
+
+        when(mSim1.getSubscriptionId()).thenReturn(SIM1_ID);
+        when(mSim1.getDisplayName()).thenReturn(SIM1_NAME);
+        when(mSim2.getSubscriptionId()).thenReturn(SIM2_ID);
+        when(mSim2.getDisplayName()).thenReturn(SIM2_NAME);
+    }
+
+    protected void setDialogType(int dialogType) {
+        mIntent.putExtra(DIALOG_TYPE_KEY, dialogType);
+    }
+
+    protected AlertDialog startDialog() {
+        final FragmentController controller = FragmentController.of(mFragment,
+                SimDialogActivity.class, mIntent);
+        controller.create(0 /* containerViewId */, null /* bundle */).start().visible();
+        return ShadowAlertDialogCompat.getLatestAlertDialog();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/sim/SimListDialogFragmentTest.java b/tests/robotests/src/com/android/settings/sim/SimListDialogFragmentTest.java
new file mode 100644
index 0000000..2b33ebe
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/sim/SimListDialogFragmentTest.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.sim;
+
+import static com.android.settings.sim.SimDialogActivity.DATA_PICK;
+import static com.android.settings.sim.SimDialogActivity.SMS_PICK;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.telephony.SubscriptionManager;
+
+import androidx.appcompat.app.AlertDialog;
+
+import com.android.settings.R;
+import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+
+import java.util.Arrays;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowAlertDialogCompat.class)
+public class SimListDialogFragmentTest extends SimDialogFragmentTestBase<SimListDialogFragment> {
+
+    @Test
+    public void onCreateDialog_noSubscriptions_dismissed() {
+        final int dialogType = DATA_PICK;
+        setDialogType(dialogType);
+        mFragment = spy(SimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_data,
+                false /* includeAskEveryTime */));
+        doReturn(null).when(mFragment).getCurrentSubscriptions();
+        startDialog();
+        verify(mFragment).dismiss();
+    }
+
+    @Test
+    public void onCreateDialog_twoSubscriptionsNoAskEveryTime_twoSubsForDisplay() {
+        final int dialogType = DATA_PICK;
+        setDialogType(dialogType);
+        mFragment = spy(SimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_data,
+                false /* includeAskEveryTime */));
+        doReturn(Arrays.asList(mSim1, mSim2)).when(mFragment).getCurrentSubscriptions();
+        // Avoid problems robolectric has with our real adapter.
+        doNothing().when(mFragment).setAdapter(any());
+        final AlertDialog alertDialog = startDialog();
+        assertThat(mFragment.mSubscriptions).hasSize(2);
+
+        final SimDialogActivity activity = (SimDialogActivity) spy(mFragment.getActivity());
+        doReturn(activity).when(mFragment).getActivity();
+        doNothing().when(activity).onSubscriptionSelected(anyInt(), anyInt());
+
+        mFragment.onClick(alertDialog, 1);
+        verify(activity).onSubscriptionSelected(dialogType, SIM2_ID);
+    }
+
+    @Test
+    public void onCreateDialog_twoSubscriptionsAskEveryTime_threeSubsForDisplay() {
+        final int dialogType = SMS_PICK;
+        setDialogType(dialogType);
+        mFragment = spy(SimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_sms,
+                true /* includeAskEveryTime */));
+        doReturn(Arrays.asList(mSim1, mSim2)).when(mFragment).getCurrentSubscriptions();
+        // Avoid problems robolectric has with our real adapter.
+        doNothing().when(mFragment).setAdapter(any());
+        final AlertDialog alertDialog = startDialog();
+        assertThat(mFragment.mSubscriptions).hasSize(3);
+        assertThat(mFragment.mSubscriptions.get(0)).isNull();
+
+        final SimDialogActivity activity = (SimDialogActivity) spy(mFragment.getActivity());
+        doReturn(activity).when(mFragment).getActivity();
+        doNothing().when(activity).onSubscriptionSelected(anyInt(), anyInt());
+
+        mFragment.onClick(alertDialog, 0);
+        verify(activity).onSubscriptionSelected(dialogType,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java b/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
index 1ea324d..4e62b03 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
@@ -191,8 +191,8 @@
                 .build();
         final ContentResolver resolver = mock(ContentResolver.class);
         doReturn(resolver).when(mContext).getContentResolver();
-        final int position = FakeSliderController.MAX_STEPS - 1;
-        final int oldPosition = FakeSliderController.MAX_STEPS;
+        final int position = FakeSliderController.MAX_VALUE - 1;
+        final int oldPosition = FakeSliderController.MAX_VALUE;
         mSearchFeatureProvider.getSearchIndexableResources().getProviderValues().clear();
         insertSpecialCase(FakeSliderController.class, key);
 
@@ -310,8 +310,8 @@
 
         // Insert Fake Slider into Database
         final String key = "key";
-        final int position = FakeSliderController.MAX_STEPS - 1;
-        final int oldPosition = FakeSliderController.MAX_STEPS;
+        final int position = FakeSliderController.MAX_VALUE - 1;
+        final int oldPosition = FakeSliderController.MAX_VALUE;
         mSearchFeatureProvider.getSearchIndexableResources().getProviderValues().clear();
         insertSpecialCase(FakeSliderController.class, key);
 
diff --git a/tests/robotests/src/com/android/settings/testutils/FakeSliderController.java b/tests/robotests/src/com/android/settings/testutils/FakeSliderController.java
index 9e65913..da9cd63 100644
--- a/tests/robotests/src/com/android/settings/testutils/FakeSliderController.java
+++ b/tests/robotests/src/com/android/settings/testutils/FakeSliderController.java
@@ -25,7 +25,7 @@
 
     public static final String AVAILABILITY_KEY = "fake_slider_availability_key";
 
-    public static final int MAX_STEPS = 9;
+    public static final int MAX_VALUE = 9;
 
     private static final String SETTING_KEY = "fake_slider_key";
 
@@ -44,8 +44,13 @@
     }
 
     @Override
-    public int getMaxSteps() {
-        return MAX_STEPS;
+    public int getMax() {
+        return MAX_VALUE;
+    }
+
+    @Override
+    public int getMin() {
+        return 0;
     }
 
     @Override
diff --git a/tests/robotests/src/com/android/settings/widget/SeekBarPreferenceTest.java b/tests/robotests/src/com/android/settings/widget/SeekBarPreferenceTest.java
index a675e02..0a1d5d8 100644
--- a/tests/robotests/src/com/android/settings/widget/SeekBarPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/widget/SeekBarPreferenceTest.java
@@ -18,12 +18,16 @@
 
 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.os.Parcelable;
 
 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;
 
@@ -39,9 +43,10 @@
 
     @Before
     public void setUp() {
+        MockitoAnnotations.initMocks(this);
         mContext = RuntimeEnvironment.application;
 
-        mSeekBarPreference = new SeekBarPreference(mContext);
+        mSeekBarPreference = spy(new SeekBarPreference(mContext));
         mSeekBarPreference.setMax(MAX);
         mSeekBarPreference.setMin(MIN);
         mSeekBarPreference.setProgress(PROGRESS);
@@ -59,4 +64,18 @@
         assertThat(preference.getMin()).isEqualTo(MIN);
         assertThat(preference.getProgress()).isEqualTo(PROGRESS);
     }
+
+    @Test
+    public void isSelectable_disabledByAdmin_returnTrue() {
+        when(mSeekBarPreference.isDisabledByAdmin()).thenReturn(true);
+
+        assertThat(mSeekBarPreference.isSelectable()).isTrue();
+    }
+
+    @Test
+    public void isSelectable_notDisabledByAdmin_returnFalse() {
+        when(mSeekBarPreference.isDisabledByAdmin()).thenReturn(false);
+
+        assertThat(mSeekBarPreference.isSelectable()).isFalse();
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java b/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java
index d7f8ef8..41d1bbe 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java
@@ -23,10 +23,13 @@
 import android.content.Intent;
 import android.net.wifi.WifiConfiguration;
 
+import com.android.settings.R;
 import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
 import com.android.settings.testutils.shadow.ShadowConnectivityManager;
 import com.android.settings.testutils.shadow.ShadowWifiManager;
 
+import com.google.android.setupcompat.util.WizardManagerHelper;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -72,7 +75,7 @@
     }
 
     @Test
-    public void onSubmit_shouldNotConnectToNetwork_whenConnectForCallerIsFalse() {
+    public void onSubmit_whenConnectForCallerIsFalse_shouldNotConnectToNetwork() {
         WifiDialogActivity activity =
                 Robolectric.buildActivity(
                         WifiDialogActivity.class,
@@ -88,4 +91,24 @@
 
         assertThat(ShadowWifiManager.get().savedWifiConfig).isNull();
     }
+
+    @Test
+    public void onSubmit_whenLaunchInSetupFlow_shouldBeLightThemeForWifiDialog() {
+        WifiDialogActivity activity =
+                Robolectric.buildActivity(
+                        WifiDialogActivity.class,
+                        new Intent()
+                                .putExtra(WifiDialogActivity.KEY_CONNECT_FOR_CALLER, false)
+                                .putExtra(WizardManagerHelper.EXTRA_IS_FIRST_RUN, true)
+                                .putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true))
+                        .setup().get();
+        WifiDialog dialog = (WifiDialog) ShadowAlertDialogCompat.getLatestAlertDialog();
+
+        assertThat(dialog).isNotNull();
+
+        activity.onSubmit(dialog);
+
+        assertThat(dialog.getContext().getThemeResId())
+                .isEqualTo(R.style.SuwAlertDialogThemeCompat_Light);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiDialogTest.java b/tests/robotests/src/com/android/settings/wifi/WifiDialogTest.java
index 4ce29aa..ed9b851 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiDialogTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiDialogTest.java
@@ -4,6 +4,7 @@
 
 import android.content.Context;
 
+import com.android.settings.R;
 import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
 import com.android.settings.wifi.WifiDialog.WifiDialogListener;
 import com.android.settingslib.wifi.AccessPoint;
@@ -41,4 +42,16 @@
         assertThat(modal.getContext().getThemeResId())
                 .isEqualTo(wifiDialog.getContext().getThemeResId());
     }
+
+    @Test
+    public void createModal_whenSetTheme_shouldBeCustomizedTheme() {
+        WifiDialog modal = WifiDialog.createModal(mContext, mListener, mockAccessPoint,
+                WifiConfigUiBase.MODE_CONNECT, R.style.SuwAlertDialogThemeCompat_Light);
+
+        WifiDialog wifiDialog = new WifiDialog(mContext, mListener, mockAccessPoint,
+                WifiConfigUiBase.MODE_CONNECT, R.style.SuwAlertDialogThemeCompat_Light,
+                        false /* hideSubmitButton */);
+        assertThat(modal.getContext().getThemeResId())
+                .isEqualTo(wifiDialog.getContext().getThemeResId());
+    }
 }
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 223e81b..2acfc4a 100644
--- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
@@ -289,17 +289,9 @@
         when(mockIconInjector.getIcon(anyInt())).thenReturn(new ColorDrawable());
 
         setupMockedPreferenceScreen();
-
-        // Disable saved network detail page feature for this test
-        FeatureFlagUtils.setEnabled(mContext, FeatureFlags.WIFI_DETAILS_SAVED_SCREEN, false);
-        when(mockAccessPoint.isActive()).thenReturn(true);
-
-        mController = newWifiDetailPreferenceController();
     }
 
     private void setUpForConnectedNetwork() {
-        // Enable saved network detail page feature for this test
-        FeatureFlagUtils.setEnabled(mContext, FeatureFlags.WIFI_DETAILS_SAVED_SCREEN, true);
         when(mockAccessPoint.isActive()).thenReturn(true);
         ArrayList list = new ArrayList<>();
         list.add(mockAccessPoint);
@@ -312,8 +304,6 @@
     }
 
     private void setUpForDisconnectedNetwork() {
-        // Enable saved network detail page feature for this test
-        FeatureFlagUtils.setEnabled(mContext, FeatureFlags.WIFI_DETAILS_SAVED_SCREEN, true);
         when(mockAccessPoint.isActive()).thenReturn(false);
         ArrayList list = new ArrayList<>();
         list.add(mockAccessPoint);
@@ -326,8 +316,6 @@
     }
 
     private void setUpForNotInRangeNetwork() {
-        // Enable saved network detail page feature for this test
-        FeatureFlagUtils.setEnabled(mContext, FeatureFlags.WIFI_DETAILS_SAVED_SCREEN, true);
         when(mockAccessPoint.isActive()).thenReturn(false);
         ArrayList list = new ArrayList<>();
         list.add(mockAccessPoint);
@@ -397,6 +385,7 @@
 
     @Test
     public void isAvailable_shouldAlwaysReturnTrue() {
+        setUpForConnectedNetwork();
         mController.displayPreference(mockScreen);
 
         assertThat(mController.isAvailable()).isTrue();
@@ -404,19 +393,13 @@
 
     @Test
     public void securityPreference_stringShouldBeSet() {
+        setUpForConnectedNetwork();
         displayAndResume();
 
         verify(mockSecurityPref).setSummary(SECURITY);
     }
 
     @Test
-    public void latestWifiInfo_shouldBeFetchedInDisplayPreference() {
-        displayAndResume();
-
-        verify(mockWifiManager, times(1)).getConnectionInfo();
-    }
-
-    @Test
     public void latestWifiInfo_shouldBeFetchedInDisplayPreferenceForConnectedNetwork() {
         setUpForConnectedNetwork();
 
@@ -444,13 +427,6 @@
     }
 
     @Test
-    public void latestNetworkInfo_shouldBeFetchedInDisplayPreference() {
-        displayAndResume();
-
-        verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class));
-    }
-
-    @Test
     public void latestNetworkInfo_shouldBeFetchedInDisplayPreferenceForConnectedNetwork() {
         setUpForConnectedNetwork();
 
@@ -479,6 +455,7 @@
 
     @Test
     public void networkCallback_shouldBeRegisteredOnResume() {
+        setUpForConnectedNetwork();
         displayAndResume();
 
         verify(mockConnectivityManager, times(1)).registerNetworkCallback(
@@ -487,6 +464,7 @@
 
     @Test
     public void networkCallback_shouldBeUnregisteredOnPause() {
+        setUpForConnectedNetwork();
         displayAndResume();
         mController.onPause();
 
@@ -495,15 +473,6 @@
     }
 
     @Test
-    public void entityHeader_shouldHaveIconSet() {
-        Drawable expectedIcon = mockIconInjector.getIcon(LEVEL);
-
-        displayAndResume();
-
-        verify(mockHeaderController).setIcon(expectedIcon);
-    }
-
-    @Test
     public void entityHeader_shouldHaveIconSetForConnectedNetwork() {
         setUpForConnectedNetwork();
         Drawable expectedIcon = mockIconInjector.getIcon(LEVEL);
@@ -534,6 +503,7 @@
 
     @Test
     public void entityHeader_shouldHaveLabelSetToTitle() {
+        setUpForConnectedNetwork();
         String label = "title";
         when(mockAccessPoint.getTitle()).thenReturn(label);
 
@@ -544,6 +514,7 @@
 
     @Test
     public void entityHeader_shouldHaveSummarySet() {
+        setUpForConnectedNetwork();
         String summary = "summary";
         when(mockAccessPoint.getSettingsSummary()).thenReturn(summary);
 
@@ -553,13 +524,6 @@
     }
 
     @Test
-    public void signalStrengthPref_shouldHaveIconSet() {
-        displayAndResume();
-
-        verify(mockSignalStrengthPref).setIcon(any(Drawable.class));
-    }
-
-    @Test
     public void signalStrengthPref_shouldHaveIconSetForConnectedNetwork() {
         setUpForConnectedNetwork();
 
@@ -587,16 +551,6 @@
     }
 
     @Test
-    public void signalStrengthPref_shouldHaveDetailTextSet() {
-        String expectedStrength =
-                mContext.getResources().getStringArray(R.array.wifi_signal)[LEVEL];
-
-        displayAndResume();
-
-        verify(mockSignalStrengthPref).setSummary(expectedStrength);
-    }
-
-    @Test
     public void signalStrengthPref_shouldHaveDetailTextSetForConnectedNetwork() {
         setUpForConnectedNetwork();
         String expectedStrength =
@@ -628,16 +582,8 @@
     }
 
     @Test
-    public void linkSpeedPref_shouldHaveDetailTextSet() {
-        String expectedLinkSpeed = mContext.getString(R.string.tx_link_speed, TX_LINK_SPEED);
-
-        displayAndResume();
-
-        verify(mockTxLinkSpeedPref).setSummary(expectedLinkSpeed);
-    }
-
-    @Test
     public void linkSpeedPref_shouldNotShowIfNotSet() {
+        setUpForConnectedNetwork();
         when(mockWifiInfo.getTxLinkSpeedMbps()).thenReturn(WifiInfo.LINK_SPEED_UNKNOWN);
 
         displayAndResume();
@@ -677,16 +623,8 @@
     }
 
     @Test
-    public void rxLinkSpeedPref_shouldHaveDetailTextSet() {
-        String expectedLinkSpeed = mContext.getString(R.string.rx_link_speed, RX_LINK_SPEED);
-
-        displayAndResume();
-
-        verify(mockRxLinkSpeedPref).setSummary(expectedLinkSpeed);
-    }
-
-    @Test
     public void rxLinkSpeedPref_shouldNotShowIfNotSet() {
+        setUpForConnectedNetwork();
         when(mockWifiInfo.getRxLinkSpeedMbps()).thenReturn(WifiInfo.LINK_SPEED_UNKNOWN);
 
         displayAndResume();
@@ -726,41 +664,32 @@
     }
 
     @Test
-    public void ssidPref_shouldHaveDetailTextSet() {
+    public void ssidPref_shouldHaveDetailTextSetForPasspointR1() {
+        setUpForConnectedNetwork();
         when(mockAccessPoint.isPasspoint()).thenReturn(true);
         when(mockAccessPoint.isOsuProvider()).thenReturn(false);
 
         displayAndResume();
 
         verify(mockSsidPref, times(1)).setSummary(SSID);
-
-        when(mockAccessPoint.isPasspoint()).thenReturn(false);
-        when(mockAccessPoint.isOsuProvider()).thenReturn(true);
-
-        displayAndResume();
-
-        verify(mockSsidPref, times(2)).setSummary(SSID);
+        verify(mockSsidPref, times(1)).setVisible(true);
     }
 
     @Test
-    public void ssidPref_shouldShowIfPasspointOrOsu() {
-        when(mockAccessPoint.isPasspoint()).thenReturn(true);
-        when(mockAccessPoint.isOsuProvider()).thenReturn(false);
-
-        displayAndResume();
-
-        verify(mockSsidPref, times(1)).setVisible(true);
-
+    public void ssidPref_shouldHaveDetailTextSetForPasspointR2() {
+        setUpForConnectedNetwork();
         when(mockAccessPoint.isPasspoint()).thenReturn(false);
         when(mockAccessPoint.isOsuProvider()).thenReturn(true);
 
         displayAndResume();
 
-        verify(mockSsidPref, times(2)).setVisible(true);
+        verify(mockSsidPref, times(1)).setSummary(SSID);
+        verify(mockSsidPref, times(1)).setVisible(true);
     }
 
     @Test
     public void ssidPref_shouldNotShowIfNotPasspoint() {
+        setUpForConnectedNetwork();
         when(mockAccessPoint.isPasspoint()).thenReturn(false);
         when(mockAccessPoint.isOsuProvider()).thenReturn(false);
 
@@ -770,13 +699,6 @@
     }
 
     @Test
-    public void macAddressPref_shouldHaveDetailTextSet() {
-        displayAndResume();
-
-        verify(mockMacAddressPref).setSummary(MAC_ADDRESS);
-    }
-
-    @Test
     public void macAddressPref_shouldVisibleForConnectedNetwork() {
         setUpForConnectedNetwork();
 
@@ -813,15 +735,6 @@
     }
 
     @Test
-    public void ipAddressPref_shouldHaveDetailTextSet() {
-        mLinkProperties.addLinkAddress(Constants.IPV4_ADDR);
-
-        displayAndResume();
-
-        verify(mockIpAddressPref).setSummary(Constants.IPV4_ADDR.getAddress().getHostAddress());
-    }
-
-    @Test
     public void ipAddressPref_shouldHaveDetailTextSetForConnectedNetwork() {
         setUpForConnectedNetwork();
         mLinkProperties.addLinkAddress(Constants.IPV4_ADDR);
@@ -842,18 +755,6 @@
     }
 
     @Test
-    public void gatewayAndSubnet_shouldHaveDetailTextSet() {
-        mLinkProperties.addLinkAddress(Constants.IPV4_ADDR);
-        mLinkProperties.addRoute(Constants.IPV4_DEFAULT);
-        mLinkProperties.addRoute(Constants.IPV4_SUBNET);
-
-        displayAndResume();
-
-        verify(mockSubnetPref).setSummary("255.255.255.128");
-        verify(mockGatewayPref).setSummary("192.0.2.127");
-    }
-
-    @Test
     public void gatewayAndSubnet_shouldHaveDetailTextSetForConnectedNetwork() {
         setUpForConnectedNetwork();
         mLinkProperties.addLinkAddress(Constants.IPV4_ADDR);
@@ -877,20 +778,6 @@
     }
 
     @Test
-    public void dnsServersPref_shouldHaveDetailTextSet() throws UnknownHostException {
-        mLinkProperties.addDnsServer(InetAddress.getByAddress(new byte[] {8, 8, 4, 4}));
-        mLinkProperties.addDnsServer(InetAddress.getByAddress(new byte[] {8, 8, 8, 8}));
-        mLinkProperties.addDnsServer(Constants.IPV6_DNS);
-
-        displayAndResume();
-
-        verify(mockDnsPref).setSummary(
-                "8.8.4.4\n" +
-                        "8.8.8.8\n" +
-                        Constants.IPV6_DNS.getHostAddress());
-    }
-
-    @Test
     public void dnsServersPref_shouldHaveDetailTextSetForConnectedNetwork()
             throws UnknownHostException {
         setUpForConnectedNetwork();
@@ -918,20 +805,7 @@
     }
 
     @Test
-    public void noCurrentNetwork_shouldFinishActivity() {
-        // If WifiManager#getCurrentNetwork() returns null, then the network is neither connected
-        // nor connecting and WifiStateMachine has not reached L2ConnectedState.
-        when(mockWifiManager.getCurrentNetwork()).thenReturn(null);
-
-        displayAndResume();
-
-        verify(mockActivity).finish();
-    }
-
-    @Test
     public void noCurrentNetwork_shouldNotFinishActivityForConnectedNetwork() {
-        // For new feature for display detail page for saved network for disconnected network,
-        // mNetwork may be null, do finish activity
         setUpForConnectedNetwork();
         when(mockWifiManager.getCurrentNetwork()).thenReturn(null);
 
@@ -942,6 +816,7 @@
 
     @Test
     public void noLinkProperties_allIpDetailsHidden() {
+        setUpForConnectedNetwork();
         when(mockConnectivityManager.getLinkProperties(mockNetwork)).thenReturn(null);
         reset(mockIpv6Category, mockIpAddressPref, mockSubnetPref, mockGatewayPref, mockDnsPref);
 
@@ -1009,6 +884,7 @@
 
     @Test
     public void onLinkPropertiesChanged_updatesFields() {
+        setUpForConnectedNetwork();
         displayAndResume();
 
         InOrder inOrder = inOrder(mockIpAddressPref, mockGatewayPref, mockSubnetPref,
@@ -1065,6 +941,7 @@
 
     @Test
     public void onCapabilitiesChanged_callsRefreshIfNecessary() {
+        setUpForConnectedNetwork();
         NetworkCapabilities nc = makeNetworkCapabilities();
         when(mockConnectivityManager.getNetworkCapabilities(mockNetwork))
                 .thenReturn(new NetworkCapabilities(nc));
@@ -1115,10 +992,11 @@
     }
 
     @Test
-    public void canForgetNetwork_noNetwork() {
+    public void canForgetNetwork_shouldInvisibleIfWithoutConfiguration() {
+        setUpForConnectedNetwork();
         when(mockAccessPoint.getConfig()).thenReturn(null);
-
         mController = newWifiDetailPreferenceController();
+
         displayAndResume();
 
         verify(mockButtonsPref).setButton1Visible(false);
@@ -1126,6 +1004,7 @@
 
     @Test
     public void canForgetNetwork_ephemeral() {
+        setUpForConnectedNetwork();
         when(mockWifiInfo.isEphemeral()).thenReturn(true);
         when(mockAccessPoint.getConfig()).thenReturn(null);
 
@@ -1136,6 +1015,7 @@
 
     @Test
     public void canForgetNetwork_saved() {
+        setUpForConnectedNetwork();
         displayAndResume();
 
         verify(mockButtonsPref).setButton1Visible(true);
@@ -1143,6 +1023,7 @@
 
     @Test
     public void canForgetNetwork_lockedDown() {
+        setUpForConnectedNetwork();
         lockDownNetwork();
 
         displayAndResume();
@@ -1151,7 +1032,8 @@
     }
 
     @Test
-    public void canShareNetwork_noNetwork() {
+    public void canShareNetwork_shouldInvisibleIfWithoutConfiguration() {
+        setUpForConnectedNetwork();
         when(mockAccessPoint.getConfig()).thenReturn(null);
 
         displayAndResume();
@@ -1161,11 +1043,13 @@
 
     @Test
     public void canModifyNetwork_saved() {
+        setUpForConnectedNetwork();
         assertThat(mController.canModifyNetwork()).isTrue();
     }
 
     @Test
     public void canModifyNetwork_lockedDown() {
+        setUpForConnectedNetwork();
         lockDownNetwork();
 
         assertThat(mController.canModifyNetwork()).isFalse();
@@ -1196,6 +1080,7 @@
 
     @Test
     public void forgetNetwork_ephemeral() {
+        setUpForConnectedNetwork();
         String ssid = "ssid";
         when(mockWifiInfo.isEphemeral()).thenReturn(true);
         when(mockWifiInfo.getSSID()).thenReturn(ssid);
@@ -1210,6 +1095,7 @@
 
     @Test
     public void forgetNetwork_saved() {
+        setUpForConnectedNetwork();
         mockWifiConfig.networkId = 5;
 
         mController.displayPreference(mockScreen);
@@ -1222,6 +1108,7 @@
 
     @Test
     public void forgetNetwork_v1_Passpoint() {
+        setUpForConnectedNetwork();
         FeatureFlagPersistent.setEnabled(mContext, FeatureFlags.NETWORK_INTERNET_V2, false);
 
         mockWifiConfig.networkId = 5;
@@ -1237,6 +1124,7 @@
 
     @Test
     public void forgetNetwork_PasspointV2_shouldShowDialog() {
+        setUpForConnectedNetwork();
         final WifiDetailPreferenceController spyController = spy(mController);
 
         mockWifiConfig.networkId = 5;
@@ -1254,6 +1142,8 @@
 
     @Test
     public void networkStateChangedIntent_shouldRefetchInfo() {
+        setUpForConnectedNetwork();
+
         displayAndResume();
 
         verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class));
@@ -1268,6 +1158,7 @@
     @Test
     public void networkStateChangedIntent_shouldRefetchInfoForConnectedNetwork() {
         setUpForConnectedNetwork();
+
         displayAndResume();
 
         verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class));
@@ -1281,6 +1172,8 @@
 
     @Test
     public void rssiChangedIntent_shouldRefetchInfo() {
+        setUpForConnectedNetwork();
+
         displayAndResume();
 
         verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class));
@@ -1307,16 +1200,6 @@
     }
 
     @Test
-    public void networkDisconnectedState_shouldFinishActivity() {
-        displayAndResume();
-
-        when(mockConnectivityManager.getNetworkInfo(any(Network.class))).thenReturn(null);
-        mContext.sendBroadcast(new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION));
-
-        verify(mockActivity).finish();
-    }
-
-    @Test
     public void networkDisconnectedState_shouldNotFinishActivityForConnectedNetwork() {
         setUpForConnectedNetwork();
 
@@ -1329,15 +1212,6 @@
     }
 
     @Test
-    public void networkOnLost_shouldFinishActivity() {
-        displayAndResume();
-
-        mCallbackCaptor.getValue().onLost(mockNetwork);
-
-        verify(mockActivity).finish();
-    }
-
-    @Test
     public void networkOnLost_shouldNotFinishActivityForConnectedNetwork() {
         setUpForConnectedNetwork();
 
@@ -1350,6 +1224,7 @@
 
     @Test
     public void ipv6AddressPref_shouldHaveHostAddressTextSet() {
+        setUpForConnectedNetwork();
         mLinkProperties.addLinkAddress(Constants.IPV6_LINKLOCAL);
         mLinkProperties.addLinkAddress(Constants.IPV6_GLOBAL1);
         mLinkProperties.addLinkAddress(Constants.IPV6_GLOBAL2);
@@ -1366,6 +1241,7 @@
 
     @Test
     public void ipv6AddressPref_shouldNotBeSelectable() {
+        setUpForConnectedNetwork();
         mLinkProperties.addLinkAddress(Constants.IPV6_GLOBAL2);
 
         displayAndResume();
@@ -1375,6 +1251,8 @@
 
     @Test
     public void captivePortal_shouldShowSignInButton() {
+        setUpForConnectedNetwork();
+
         InOrder inOrder = inOrder(mockButtonsPref);
 
         displayAndResume();
@@ -1396,6 +1274,8 @@
 
     @Test
     public void testSignInButton_shouldStartCaptivePortalApp() {
+        setUpForConnectedNetwork();
+
         displayAndResume();
 
         ArgumentCaptor<OnClickListener> captor = ArgumentCaptor.forClass(OnClickListener.class);
@@ -1428,23 +1308,25 @@
     }
 
     @Test
-    public void testRefreshRssiViews_shouldNotUpdateIfLevelIsSame() {
+    public void testRefreshRssiViews_shouldNotUpdateIfLevelIsSameForConnectedNetwork() {
+        setUpForConnectedNetwork();
         displayAndResume();
 
         mContext.sendBroadcast(new Intent(WifiManager.RSSI_CHANGED_ACTION));
 
-        verify(mockAccessPoint, times(2)).getLevel();
+        verify(mockAccessPoint, times(3)).getLevel();
         verify(mockIconInjector, times(1)).getIcon(anyInt());
     }
 
     @Test
-    public void testRefreshRssiViews_shouldUpdateOnLevelChange() {
+    public void testRefreshRssiViews_shouldUpdateOnLevelChangeForConnectedNetwork() {
+        setUpForConnectedNetwork();
         displayAndResume();
 
         when(mockAccessPoint.getLevel()).thenReturn(0);
         mContext.sendBroadcast(new Intent(WifiManager.RSSI_CHANGED_ACTION));
 
-        verify(mockAccessPoint, times(2)).getLevel();
+        verify(mockAccessPoint, times(4)).getLevel();
         verify(mockIconInjector, times(2)).getIcon(anyInt());
     }
 
@@ -1462,6 +1344,26 @@
 
     @Test
     public void testRedrawIconForHeader_shouldEnlarge() {
+        setUpForConnectedNetwork();
+        ArgumentCaptor<BitmapDrawable> drawableCaptor =
+                ArgumentCaptor.forClass(BitmapDrawable.class);
+        Drawable original = mContext.getDrawable(Utils.getWifiIconResource(LEVEL)).mutate();
+        when(mockIconInjector.getIcon(anyInt())).thenReturn(original);
+
+        displayAndResume();
+
+        verify(mockHeaderController, times(1)).setIcon(drawableCaptor.capture());
+
+        int expectedSize = mContext.getResources().getDimensionPixelSize(
+                R.dimen.wifi_detail_page_header_image_size);
+        BitmapDrawable icon = drawableCaptor.getValue();
+        assertThat(icon.getMinimumWidth()).isEqualTo(expectedSize);
+        assertThat(icon.getMinimumHeight()).isEqualTo(expectedSize);
+    }
+
+    @Test
+    public void testRedrawIconForHeader_shouldEnlargeForDisconnectedNetwork() {
+        setUpForDisconnectedNetwork();
         ArgumentCaptor<BitmapDrawable> drawableCaptor =
                 ArgumentCaptor.forClass(BitmapDrawable.class);
         Drawable original = mContext.getDrawable(Utils.getWifiIconResource(LEVEL)).mutate();
@@ -1480,6 +1382,7 @@
 
     @Test
     public void testRedrawIconForHeader_shouldNotEnlargeIfNotVectorDrawable() {
+        setUpForConnectedNetwork();
         ArgumentCaptor<ColorDrawable> drawableCaptor =
                 ArgumentCaptor.forClass(ColorDrawable.class);
 
diff --git a/tests/robotests/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettingsTest.java
index 746456e..cda4005 100644
--- a/tests/robotests/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettingsTest.java
@@ -17,47 +17,23 @@
 package com.android.settings.wifi.savedaccesspoints;
 
 import static com.google.common.truth.Truth.assertThat;
-
 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.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiManager;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
-import com.android.settings.core.FeatureFlags;
-import com.android.settings.development.featureflags.FeatureFlagPersistent;
-import com.android.settings.wifi.WifiConfigController;
-import com.android.settings.wifi.WifiDialog;
 import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.wifi.AccessPoint;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.util.ReflectionHelpers;
 
 @RunWith(RobolectricTestRunner.class)
 public class SavedAccessPointsWifiSettingsTest {
 
     @Mock
-    private WifiManager mWifiManager;
-    @Mock
-    private WifiDialog mWifiDialog;
-    @Mock
-    private WifiConfigController mConfigController;
-    @Mock
-    private WifiConfiguration mWifiConfiguration;
-    @Mock
-    private AccessPoint mAccessPoint;
-    @Mock
     private SubscribedAccessPointsPreferenceController mSubscribedApController;
     @Mock
     private SavedAccessPointsPreferenceController mSavedApController;
@@ -73,45 +49,6 @@
                 .use(SubscribedAccessPointsPreferenceController.class);
         doReturn(mSavedApController).when(mSettings)
                 .use(SavedAccessPointsPreferenceController.class);
-
-        ReflectionHelpers.setField(mSettings, "mWifiManager", mWifiManager);
-
-        when(mWifiDialog.getController()).thenReturn(mConfigController);
-        when(mConfigController.getConfig()).thenReturn(mWifiConfiguration);
-    }
-
-    @Test
-    public void onForget_isPasspointConfig_shouldRefreshAPList() {
-        FeatureFlagPersistent.setEnabled(RuntimeEnvironment.application,
-                FeatureFlags.NETWORK_INTERNET_V2, false);
-        when(mAccessPoint.isPasspointConfig()).thenReturn(true);
-        ReflectionHelpers.setField(mSettings, "mSelectedAccessPoint", mAccessPoint);
-
-        mSettings.onForget(null);
-
-        verify(mSavedApController).postRefreshSavedAccessPoints();
-    }
-
-    @Test
-    public void onForget_isPasspointConfig_shouldRefreshSubscribedAPList() {
-        FeatureFlagPersistent.setEnabled(RuntimeEnvironment.application,
-                FeatureFlags.NETWORK_INTERNET_V2, true);
-        when(mAccessPoint.isPasspointConfig()).thenReturn(true);
-        ReflectionHelpers.setField(mSettings, "mSelectedAccessPoint", mAccessPoint);
-
-        mSettings.onForget(null);
-
-        verify(mSubscribedApController).postRefreshSubscribedAccessPoints();
-    }
-
-    @Test
-    public void onForget_shouldInvokeForgetApi() {
-        ReflectionHelpers.setField(mSettings, "mSelectedAccessPoint", mAccessPoint);
-        when(mAccessPoint.getConfig()).thenReturn(mWifiConfiguration);
-
-        mSettings.onForget(mWifiDialog);
-
-        verify(mWifiManager).forget(mWifiConfiguration.networkId, mSavedApController);
     }
 
     @Test