Merge "Update links to Scanning Settings" into sc-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 6a4b8d5..cb53a02 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -107,6 +107,7 @@
     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
     <uses-permission android:name="android.permission.READ_DREAM_STATE" />
     <uses-permission android:name="android.permission.READ_DREAM_SUPPRESSION" />
+    <uses-permission android:name="android.permission.MANAGE_APP_HIBERNATION" />
 
     <application android:label="@string/settings_label"
             android:icon="@drawable/ic_launcher_settings"
@@ -1233,7 +1234,6 @@
 
         <activity android:name=".applications.InstalledAppOpenByDefaultActivity"
                   android:label="@string/application_info_label"
-                  android:permission="android.permission.OPEN_APP_OPEN_BY_DEFAULT_SETTINGS"
                   android:exported="true">
             <intent-filter android:priority="1">
                 <action android:name="com.android.settings.APP_OPEN_BY_DEFAULT_SETTINGS" />
@@ -1490,6 +1490,7 @@
         <activity android:name=".applications.specialaccess.deviceadmin.DeviceAdminAdd"
                   android:label="@string/device_admin_add_title"
                   android:exported="true"
+                  android:theme="@style/Theme.SubSettings"
                   android:clearTaskOnLaunch="true">
             <intent-filter>
                 <action android:name="android.app.action.ADD_DEVICE_ADMIN" />
@@ -1971,7 +1972,7 @@
                 <category android:name="com.android.settings.SHORTCUT" />
             </intent-filter>
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
-                android:value="com.android.settings.deviceinfo.StorageSettings" />
+                android:value="com.android.settings.deviceinfo.StorageDashboardFragment" />
             <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
                 android:value="true" />
         </activity>
diff --git a/res/drawable/ic_files_go_round.xml b/res/drawable/ic_files_go_round.xml
new file mode 100644
index 0000000..2025b00
--- /dev/null
+++ b/res/drawable/ic_files_go_round.xml
@@ -0,0 +1,121 @@
+<!--
+    Copyright (C) 2021 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"
+    xmlns:aapt="http://schemas.android.com/aapt"
+    android:width="32dp"
+    android:height="32dp"
+    android:viewportWidth="192"
+    android:viewportHeight="192">
+  <path
+      android:pathData="M96,96m-88,0a88,88 0,1 1,176 0a88,88 0,1 1,-176 0"
+      android:fillColor="#FFFFFF"/>
+  <path
+      android:pathData="M96,183c-48.43,0 -87.72,-39.13 -87.99,-87.5C8.01,95.67 8,95.83 8,96c0,48.6 39.4,88 88,88s88,-39.4 88,-88c0,-0.17 -0.01,-0.33 -0.01,-0.5C183.72,143.87 144.43,183 96,183z"
+      android:fillColor="#263238"
+      android:fillAlpha="0.2"/>
+  <path
+      android:pathData="M96,9c48.43,0 87.72,39.13 87.99,87.5c0,-0.17 0.01,-0.33 0.01,-0.5c0,-48.6 -39.4,-88 -88,-88S8,47.4 8,96c0,0.17 0.01,0.33 0.01,0.5C8.28,48.13 47.57,9 96,9z"
+      android:fillColor="#FFFFFF"
+      android:fillAlpha="0.2"/>
+  <path
+      android:pathData="M85.09,59.18H44.18c-4.52,0 -8.18,3.66 -8.18,8.18v40.91v2.05v-0.35c0,-1.08 0.43,-2.13 1.2,-2.89L85.09,59.18z"
+      android:fillColor="#0F9D58"/>
+  <path
+      android:pathData="M85.09,59.18H44.18c-4.52,0 -8.18,3.66 -8.18,8.18v40.91v2.05v-0.35c0,-1.08 0.43,-2.13 1.2,-2.89L85.09,59.18z">
+    <aapt:attr name="android:fillColor">
+      <gradient
+          android:startY="110.3181"
+          android:startX="60.5458"
+          android:endY="59.182"
+          android:endX="60.5458"
+          android:type="linear">
+        <item android:offset="0" android:color="#33263238"/>
+        <item android:offset="1" android:color="#00263238"/>
+      </gradient>
+    </aapt:attr>
+  </path>
+  <path
+      android:pathData="M37.2,106.39c-0.77,0.77 -1.2,1.81 -1.2,2.89v0.35v0.33c0,-1.08 0.43,-2.13 1.2,-2.89l47.89,-47.89h-0.68L37.2,106.39z"
+      android:fillColor="#263238"
+      android:fillAlpha="0.2"/>
+  <path
+      android:pathData="M44.18,59.86h39.55l0.68,-0.68H44.18c-4.52,0 -8.18,3.66 -8.18,8.18v0.68C36,63.53 39.66,59.86 44.18,59.86z"
+      android:fillColor="#FFFFFF"
+      android:fillAlpha="0.2"/>
+  <path
+      android:pathData="M147.82,143.73H44.18c-4.52,0 -8.18,-3.66 -8.18,-8.18v-25.58c0,-1.08 0.43,-2.13 1.2,-2.89l57.6,-57.6c0.77,-0.77 1.81,-1.2 2.89,-1.2h50.12c4.52,0 8.18,3.66 8.18,8.18v79.09C156,140.06 152.34,143.73 147.82,143.73z"
+      android:fillColor="#4285F4"/>
+  <path
+      android:pathData="M156,135.55l0,-29.32L98.05,48.27l-0.31,0c-1.11,0 -2.17,0.45 -2.94,1.25L37.2,107.07c-0.77,0.77 -1.2,1.81 -1.2,2.89v0.35l33.41,33.41l78.41,0C152.34,143.73 156,140.06 156,135.55z">
+    <aapt:attr name="android:fillColor">
+      <gradient
+          android:startY="78.2732"
+          android:startX="66.0008"
+          android:endY="153.6034"
+          android:endX="141.331"
+          android:type="linear">
+        <item android:offset="0" android:color="#281A237E"/>
+        <item android:offset="1" android:color="#051A237E"/>
+      </gradient>
+    </aapt:attr>
+  </path>
+  <path
+      android:pathData="M147.82,143.05H44.18c-4.52,0 -8.18,-3.66 -8.18,-8.18v0.68c0,4.52 3.66,8.18 8.18,8.18h103.64c4.52,0 8.18,-3.66 8.18,-8.18v-0.68C156,139.38 152.34,143.05 147.82,143.05z"
+      android:fillColor="#1A237E"
+      android:fillAlpha="0.2"/>
+  <path
+      android:pathData="M147.82,48.27H98.05c-0.6,0 -1.14,0.27 -1.51,0.68h51.29c4.52,0 8.18,3.66 8.18,8.18v-0.68C156,51.94 152.34,48.27 147.82,48.27z"
+      android:fillColor="#FFFFFF"
+      android:fillAlpha="0.2"/>
+  <path
+      android:pathData="M94.8,49.47l-57.6,57.6c-0.77,0.77 -1.2,1.81 -1.2,2.89v0.35v0c0,-1.13 0.92,-2.05 2.05,-2.05h49.77c4.52,0 8.18,-3.66 8.18,-8.18l0,-49.77c0,-1.13 0.92,-2.05 2.05,-2.05l0,0l-0.35,0C96.61,48.27 95.57,48.7 94.8,49.47z"
+      android:fillColor="#DB4437"/>
+  <path
+      android:pathData="M97.69,48.27c-0.27,0 -0.54,0.03 -0.8,0.08C97.15,48.3 97.42,48.27 97.69,48.27l0.35,0c-1.34,0 -2.55,0.72 -3.21,1.85c0.43,-0.42 0.95,-0.73 1.5,-0.93c0.37,-0.55 0.99,-0.92 1.7,-0.92L97.69,48.27z"
+      android:strokeAlpha="0.2"
+      android:fillColor="#3E2723"
+      android:fillAlpha="0.2"/>
+  <path
+      android:pathData="M96,99.41c0,4.52 -3.66,8.18 -8.18,8.18H38.05c-0.85,0 -1.57,0.51 -1.88,1.25c-0.1,0.36 -0.16,0.74 -0.16,1.13v0.35c0,-1.13 0.92,-2.05 2.05,-2.05h49.77c4.52,0 8.18,-3.66 8.18,-8.18"
+      android:fillColor="#3E2723"
+      android:fillAlpha="0.2"/>
+  <path
+      android:pathData="M36,110.32L36,110.32c0,-1.62 1.05,-3.06 2.6,-3.55L74.95,95.2c3.79,-1.21 6.77,-4.18 7.97,-7.97l11.57,-36.35c0.49,-1.55 1.93,-2.6 3.55,-2.6l0,0h-0.35c-1.08,0 -2.13,0.43 -2.89,1.2l-57.6,57.6c-0.77,0.77 -1.2,1.81 -1.2,2.89L36,110.32z"
+      android:fillColor="#F4B400"/>
+  <path
+      android:pathData="M94.84,49.44c-0.14,0.24 -0.26,0.48 -0.35,0.75L82.92,86.54c-1.21,3.79 -4.18,6.77 -7.97,7.97L38.6,106.08c-0.27,0.09 -0.52,0.21 -0.76,0.35l-0.64,0.64c-0.77,0.77 -1.2,1.81 -1.2,2.89l0,0.35c0,-1.62 1.05,-3.06 2.6,-3.55L74.95,95.2c3.79,-1.21 6.77,-4.18 7.97,-7.97l11.57,-36.35c0.49,-1.55 1.93,-2.6 3.55,-2.6h-0.35C96.63,48.27 95.6,48.69 94.84,49.44z"
+      android:fillColor="#BF360C"
+      android:fillAlpha="0.3"/>
+  <path
+      android:pathData="M39,105.95l55.36,-55.36l0.13,-0.4c0.09,-0.27 0.21,-0.52 0.35,-0.75c-0.01,0.01 -0.03,0.02 -0.04,0.03l-56.96,56.96c0.24,-0.14 0.49,-0.27 0.76,-0.35L39,105.95z"
+      android:strokeAlpha="0.2"
+      android:fillColor="#FFFFFF"
+      android:fillAlpha="0.2"/>
+  <path
+      android:pathData="M36,109.97v25.58c0,4.52 3.66,8.18 8.18,8.18h103.64c4.52,0 8.18,-3.66 8.18,-8.18V56.45c0,-4.52 -3.66,-8.18 -8.18,-8.18H97.69c-1.08,0 -2.13,0.43 -2.89,1.2l-9.71,9.71H44.18c-4.52,0 -8.18,3.66 -8.18,8.18v40.91L36,109.97">
+    <aapt:attr name="android:fillColor">
+      <gradient
+          android:gradientRadius="115.3882"
+          android:centerX="72.364"
+          android:centerY="59.4093"
+          android:type="radial">
+        <item android:offset="0.0029046" android:color="#19FFFFFF"/>
+        <item android:offset="1" android:color="#00FFFFFF"/>
+      </gradient>
+    </aapt:attr>
+  </path>
+</vector>
diff --git a/res/drawable/ic_homepage_search.xml b/res/drawable/ic_homepage_search.xml
index 3895b6b..3da1cc7 100644
--- a/res/drawable/ic_homepage_search.xml
+++ b/res/drawable/ic_homepage_search.xml
@@ -20,7 +20,7 @@
         android:height="24dp"
         android:viewportWidth="24"
         android:viewportHeight="24"
-        android:tint="?android:attr/colorAccent">
+        android:tint="?android:attr/textColorSecondary">
     <path
         android:fillColor="#FF000000"
         android:pathData="M20.49,19l-5.73,-5.73C15.53,12.2 16,10.91 16,9.5C16,5.91 13.09,3 9.5,3S3,5.91 3,9.5C3,13.09 5.91,16 9.5,16c1.41,0 2.7,-0.47 3.77,-1.24L19,20.49L20.49,19zM5,9.5C5,7.01 7.01,5 9.5,5S14,7.01 14,9.5S11.99,14 9.5,14S5,11.99 5,9.5z"/>
diff --git a/res/drawable/ic_refresh_24dp.xml b/res/drawable/ic_refresh_24dp.xml
deleted file mode 100644
index 9b78fcd..0000000
--- a/res/drawable/ic_refresh_24dp.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2021 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24"
-        android:viewportHeight="24"
-        android:tint="?android:attr/colorAccent">
-    <path
-        android:fillColor="@android:color/white"
-        android:pathData="M13,9v2h7V4h-2v2.74C16.53,5.07 14.4,4 12,4c-2.21,0 -4.21,0.9 -5.66,2.34S4,9.79 4,12c0,4.42 3.58,8 8,8 2.21,0 4.21,-0.9 5.66,-2.34l-1.42,-1.42C15.15,17.33 13.65,18 12,18c-3.31,0 -6,-2.69 -6,-6 0,-1.65 0.67,-3.15 1.76,-4.24C8.85,6.67 10.35,6 12,6c2.21,0 4.15,1.21 5.19,3H13z"/>
-</vector>
diff --git a/res/drawable/ic_repair_24dp.xml b/res/drawable/ic_repair_24dp.xml
new file mode 100644
index 0000000..da351fc
--- /dev/null
+++ b/res/drawable/ic_repair_24dp.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="?android:attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/black"
+      android:pathData="M12,5c3.53,0 6.44,2.61 6.93,6h2.02c-0.5,-4.5 -4.31,-8 -8.95,-8c-4.97,0 -9,4.03 -9,9c0,3.48 1.98,6.5 4.87,8H5v2h6v-6H9v2.33C6.64,17.2 5,14.79 5,12C5,8.13 8.13,5 12,5z"/>
+  <path
+      android:fillColor="@android:color/black"
+      android:pathData="M22.16,16.5c0,1.93 -1.57,3.5 -3.5,3.5c-0.41,0 -0.8,-0.08 -1.16,-0.21l-2.34,2.33L13.04,20l2.33,-2.34c-0.13,-0.36 -0.21,-0.75 -0.21,-1.16c0,-1.93 1.57,-3.5 3.5,-3.5c0.58,0 1.12,0.16 1.6,0.41l-2.7,2.7l1.49,1.49l2.7,-2.7C22,15.38 22.16,15.92 22.16,16.5z"/>
+</vector>
diff --git a/res/drawable/ic_trash_can.xml b/res/drawable/ic_trash_can.xml
new file mode 100644
index 0000000..ed4a4cb
--- /dev/null
+++ b/res/drawable/ic_trash_can.xml
@@ -0,0 +1,26 @@
+<!--
+    Copyright (C) 2021 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+  <path
+      android:pathData="M15,3V4H20V6H19V19C19,20.1 18.1,21 17,21H7C5.9,21 5,20.1 5,19V6H4V4H9V3H15ZM7,19H17V6H7V19ZM9,8H11V17H9V8ZM15,8H13V17H15V8Z"
+      android:fillColor="#5F6368"
+      android:fillType="evenOdd"/>
+</vector>
diff --git a/res/layout-land/confirm_lock_pattern.xml b/res/layout-land/confirm_lock_pattern.xml
index 1fd6824..1126052 100644
--- a/res/layout-land/confirm_lock_pattern.xml
+++ b/res/layout-land/confirm_lock_pattern.xml
@@ -48,13 +48,13 @@
                     android:src="@drawable/ic_enterprise" />
 
                 <TextView
-                    android:id="@+id/headerText"
+                    android:id="@+id/suc_layout_title"
                     style="@style/SudGlifHeaderTitle"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content" />
 
                 <TextView
-                    android:id="@+id/sud_layout_description"
+                    android:id="@+id/sud_layout_subtitle"
                     style="@style/SudDescription.Glif"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
diff --git a/res/layout-land/confirm_lock_pattern_normal.xml b/res/layout-land/confirm_lock_pattern_normal.xml
index 7a59894..2a9103f 100644
--- a/res/layout-land/confirm_lock_pattern_normal.xml
+++ b/res/layout-land/confirm_lock_pattern_normal.xml
@@ -48,14 +48,14 @@
                     android:src="@drawable/ic_lock" />
 
                 <TextView
-                    android:id="@+id/headerText"
+                    android:id="@+id/suc_layout_title"
                     style="@style/SudGlifHeaderTitle"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content" />
 
                 <TextView
                     style="@style/SudDescription.Glif"
-                    android:id="@+id/sud_layout_description"
+                    android:id="@+id/sud_layout_subtitle"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
                     android:layout_marginStart="?attr/sudMarginStart"
diff --git a/res/layout-land/udfps_enroll_enrolling_land.xml b/res/layout-land/udfps_enroll_enrolling_land.xml
new file mode 100644
index 0000000..7ccd396
--- /dev/null
+++ b/res/layout-land/udfps_enroll_enrolling_land.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2021 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.
+-->
+
+<com.google.android.setupdesign.GlifLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/setup_wizard_layout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout="@layout/sud_glif_blank_template"
+    style="?attr/fingerprint_layout_theme">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="horizontal"
+        android:clipToPadding="false"
+        android:clipChildren="false">
+
+        <!-- Both texts are kept as separate text views so it doesn't jump around in portrait.
+            See layouts/fingerprint_enroll_enrolling_base.xml. -->
+        <LinearLayout
+            android:layout_width="0dp"
+            android:layout_weight="1"
+            android:layout_height="match_parent"
+            android:layout_marginStart="?attr/sudMarginStart"
+            android:layout_marginBottom="@dimen/sud_content_frame_padding_bottom"
+            android:clipChildren="false"
+            android:clipToPadding="false"
+            android:orientation="vertical">
+
+            <ScrollView
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:clipChildren="false"
+                android:clipToPadding="false"
+                android:fillViewport="true">
+
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="vertical"
+                    android:clipChildren="false"
+                    android:clipToPadding="false">
+
+                    <ImageView
+                        android:id="@+id/sud_layout_icon"
+                        style="@style/SudGlifIcon"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="?attr/sudGlifHeaderGravity"
+                        android:layout_marginStart="0dp"
+                        android:layout_marginEnd="0dp"
+                        android:src="@drawable/ic_fingerprint_header" />
+
+                    <TextView
+                        android:id="@+id/suc_layout_title"
+                        style="@style/SudGlifHeaderTitle"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginStart="0dp"
+                        android:layout_marginEnd="0dp" />
+
+                    <TextView
+                        style="@style/SudDescription.Glif"
+                        android:id="@+id/sud_layout_subtitle"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"/>
+
+                    <Space
+                        android:layout_width="0dp"
+                        android:layout_height="0dp"
+                        android:layout_weight="1" />
+
+                </LinearLayout>
+
+            </ScrollView>
+
+        </LinearLayout>
+
+    </LinearLayout>
+</com.google.android.setupdesign.GlifLayout>
\ No newline at end of file
diff --git a/res/layout-land/udfps_enroll_find_sensor_land.xml b/res/layout-land/udfps_enroll_find_sensor_land.xml
new file mode 100644
index 0000000..6335afb
--- /dev/null
+++ b/res/layout-land/udfps_enroll_find_sensor_land.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2021 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.
+-->
+
+<com.google.android.setupdesign.GlifLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/setup_wizard_layout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout="@layout/sud_glif_blank_template"
+    style="?attr/fingerprint_layout_theme">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="horizontal"
+        android:clipToPadding="false"
+        android:clipChildren="false">
+
+        <LinearLayout
+            android:layout_width="0dp"
+            android:layout_weight="1"
+            android:layout_height="match_parent"
+            android:layout_marginStart="?attr/sudMarginStart"
+            android:layout_marginBottom="@dimen/sud_content_frame_padding_bottom"
+            android:clipChildren="false"
+            android:clipToPadding="false"
+            android:orientation="vertical">
+
+            <ScrollView
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:clipChildren="false"
+                android:clipToPadding="false"
+                android:fillViewport="true">
+
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="vertical"
+                    android:clipChildren="false"
+                    android:clipToPadding="false">
+
+                    <ImageView
+                        android:id="@+id/sud_layout_icon"
+                        style="@style/SudGlifIcon"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="?attr/sudGlifHeaderGravity"
+                        android:layout_marginStart="0dp"
+                        android:layout_marginEnd="0dp"
+                        android:src="@drawable/ic_fingerprint_header" />
+
+                    <TextView
+                        android:id="@+id/suc_layout_title"
+                        style="@style/SudGlifHeaderTitle"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginStart="0dp"
+                        android:layout_marginEnd="0dp" />
+
+                    <TextView
+                        android:id="@+id/sud_layout_subtitle"
+                        style="@style/SudDescription.Glif"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"/>
+
+                    <Space
+                        android:layout_width="0dp"
+                        android:layout_height="0dp"
+                        android:layout_weight="1" />
+
+                </LinearLayout>
+
+            </ScrollView>
+
+        </LinearLayout>
+
+    </LinearLayout>
+
+</com.google.android.setupdesign.GlifLayout>
\ No newline at end of file
diff --git a/res/layout/app_authentication_item.xml b/res/layout/app_authentication_item.xml
index 423722e..16d6fbd 100644
--- a/res/layout/app_authentication_item.xml
+++ b/res/layout/app_authentication_item.xml
@@ -26,7 +26,8 @@
         android:layout_width="24dp"
         android:layout_height="24dp"/>
 
-    <LinearLayout
+    <RelativeLayout
+        android:id="@+id/app_details"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:layout_toRightOf="@id/app_icon"
@@ -44,16 +45,18 @@
         <TextView
             android:id="@+id/number_of_uris"
             style="@style/AppAuthenticationPolicyNumberOfUrisText"
+            android:layout_below="@id/app_name"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:visibility="gone"/>
 
         <androidx.recyclerview.widget.RecyclerView
             android:id="@+id/uris"
+            android:layout_below="@id/app_name"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"/>
 
-    </LinearLayout>
+    </RelativeLayout>
 
     <ImageView
         android:id="@+id/expand"
diff --git a/res/layout/app_launch_progress.xml b/res/layout/app_launch_progress.xml
new file mode 100644
index 0000000..28fe406
--- /dev/null
+++ b/res/layout/app_launch_progress.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+
+<ProgressBar
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@android:style/Widget.Material.ProgressBar.Horizontal"
+    android:id="@+id/scan_links_progressbar"
+    android:paddingTop="8dp"
+    android:paddingStart="24dp"
+    android:paddingEnd="24dp"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"/>
\ No newline at end of file
diff --git a/res/layout/app_launch_verified_links_title.xml b/res/layout/app_launch_verified_links_title.xml
new file mode 100644
index 0000000..a230edc
--- /dev/null
+++ b/res/layout/app_launch_verified_links_title.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:gravity="center"
+        android:paddingStart="?android:attr/dialogPreferredPadding"
+        android:paddingEnd="?android:attr/dialogPreferredPadding"
+        android:paddingTop="@*android:dimen/dialog_padding_top_material">
+
+        <TextView
+            android:id="@+id/dialog_title"
+            android:singleLine="true"
+            android:ellipsize="end"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textAlignment="center"
+            style="?android:attr/windowTitleStyle" />
+
+        <TextView
+            android:paddingTop="12dp"
+            android:id="@+id/dialog_message"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            style="@style/TextAppearance.DialogMessage" />
+    </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/confirm_lock_pattern_base.xml b/res/layout/confirm_lock_pattern_base.xml
index 895bb8a..bac2689 100644
--- a/res/layout/confirm_lock_pattern_base.xml
+++ b/res/layout/confirm_lock_pattern_base.xml
@@ -42,13 +42,13 @@
                 android:src="@drawable/ic_enterprise" />
 
             <TextView
-                android:id="@+id/headerText"
+                android:id="@+id/suc_layout_title"
                 style="@style/SudGlifHeaderTitle"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content" />
 
             <TextView
-                android:id="@+id/sud_layout_description"
+                android:id="@+id/sud_layout_subtitle"
                 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 7c1502d..29783dd 100644
--- a/res/layout/confirm_lock_pattern_normal_base.xml
+++ b/res/layout/confirm_lock_pattern_normal_base.xml
@@ -41,14 +41,14 @@
                 android:src="@drawable/ic_lock" />
 
             <TextView
-                android:id="@+id/headerText"
+                android:id="@+id/suc_layout_title"
                 style="@style/SudGlifHeaderTitle"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content" />
 
             <TextView
                 style="@style/SudDescription.Glif"
-                android:id="@+id/sud_layout_description"
+                android:id="@+id/sud_layout_subtitle"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginStart="?attr/sudMarginStart"
diff --git a/res/layout/horizontal_preference.xml b/res/layout/horizontal_preference.xml
index 9358cff..e50fc3f 100644
--- a/res/layout/horizontal_preference.xml
+++ b/res/layout/horizontal_preference.xml
@@ -22,7 +22,7 @@
     android:layout_height="wrap_content"
     android:minHeight="?android:attr/listPreferredItemHeightSmall"
     android:orientation="horizontal"
-    android:paddingStart="@dimen/preference_no_icon_padding_start"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
     android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
 
     <TextView
diff --git a/res/layout/more_settings_button.xml b/res/layout/more_settings_button.xml
new file mode 100644
index 0000000..4bbe119
--- /dev/null
+++ b/res/layout/more_settings_button.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<LinearLayout
+      xmlns:android="http://schemas.android.com/apk/res/android"
+      xmlns:settings="http://schemas.android.com/apk/res-auto"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:orientation="vertical">
+
+      <Button
+         android:id="@+id/button"
+         android:layout_width="wrap_content"
+         android:layout_height="wrap_content"
+         android:layout_gravity="center_horizontal"
+         android:layout_marginTop="20dip"
+         android:layout_marginBottom="20dip"
+         style="@style/ActionPrimaryButton"
+         settings:allowDividerBelow="true"
+         android:gravity="center" />
+
+</LinearLayout>
diff --git a/res/layout/one_handed_header.xml b/res/layout/one_handed_header.xml
index 2104e40..3fa8183 100644
--- a/res/layout/one_handed_header.xml
+++ b/res/layout/one_handed_header.xml
@@ -21,7 +21,7 @@
     <ImageView
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:scaleType="centerCrop"
+        android:scaleType="centerInside"
         android:cropToPadding="true"
         android:src="@drawable/one_handed_guideline"
         android:contentDescription="@null" />
diff --git a/res/layout/preference_widget_info.xml b/res/layout/preference_widget_info.xml
new file mode 100644
index 0000000..39c2aca
--- /dev/null
+++ b/res/layout/preference_widget_info.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+
+<ImageView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/settings_button"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_gravity="center"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:background="?android:attr/selectableItemBackground"
+    android:scaleType="center"
+    android:src="@drawable/ic_info_outline_24"
+    android:contentDescription="@string/settings_button" />
\ No newline at end of file
diff --git a/res/layout/search_bar.xml b/res/layout/search_bar.xml
index 63f1c95..7cdf04d 100644
--- a/res/layout/search_bar.xml
+++ b/res/layout/search_bar.xml
@@ -19,10 +19,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:layout_marginTop="@dimen/search_bar_margin"
-    android:layout_marginStart="@dimen/search_bar_margin"
-    android:layout_marginEnd="@dimen/search_bar_margin"
-    android:layout_marginBottom="@dimen/search_bar_margin_bottom">
+    android:layout_margin="@dimen/search_bar_margin">
 
     <com.google.android.material.card.MaterialCardView
         android:id="@+id/search_bar"
@@ -34,7 +31,7 @@
             android:id="@+id/search_action_bar"
             android:layout_width="match_parent"
             android:layout_height="@dimen/search_bar_height"
-            android:layout_marginStart="-2dp"
+            android:paddingStart="4dp"
             android:background="@drawable/search_bar_selected_background"
             android:contentInsetStartWithNavigation="@dimen/search_bar_content_inset"
             android:navigationIcon="@drawable/ic_homepage_search">
@@ -43,16 +40,11 @@
                 style="@style/TextAppearance.SearchBar"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
+                android:paddingStart="-4dp"
                 android:layout_gravity="start"
                 android:text="@string/search_menu"/>
         </Toolbar>
     </com.google.android.material.card.MaterialCardView>
 
-   <ImageView
-        android:id="@+id/account_avatar"
-        android:layout_width="@dimen/avatar_length"
-        android:layout_height="@dimen/avatar_length"
-        android:layout_gravity="center_vertical"
-        android:contentDescription="@string/search_bar_account_avatar_content_description"/>
 </LinearLayout>
 
diff --git a/res/layout/settings_homepage_container.xml b/res/layout/settings_homepage_container.xml
index d9bcb83..4fd62fd 100644
--- a/res/layout/settings_homepage_container.xml
+++ b/res/layout/settings_homepage_container.xml
@@ -65,34 +65,26 @@
             android:orientation="vertical"
             app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed">
 
-            <LinearLayout
-                android:id="@+id/contextual_suggestion_content"
+            <ImageView
+                android:id="@+id/account_avatar"
+                android:layout_width="@dimen/avatar_length"
+                android:layout_height="@dimen/avatar_length"
+                android:layout_marginTop="@dimen/avatar_margin_top"
+                android:layout_marginEnd="@dimen/avatar_margin_end"
+                android:layout_gravity="end"
+                android:visibility="invisible"
+                android:accessibilityTraversalAfter="@id/homepage_title"
+                android:contentDescription="@string/search_bar_account_avatar_content_description"/>
+
+            <TextView
+                android:id="@+id/homepage_title"
+                android:text="@string/settings_label"
+                style="@style/HomepageTitleText"/>
+
+            <FrameLayout
+                android:id="@+id/suggestion_content"
                 android:layout_width="match_parent"
-                android:layout_height="@dimen/suggestion_height"
-                android:paddingHorizontal="@dimen/suggestion_padding_horizontal"
-                android:paddingVertical="@dimen/suggestion_padding_vertical"
-                android:orientation="vertical"
-                android:gravity="bottom"
-                android:visibility="gone">
-
-                <TextView
-                    android:id="@+id/suggestion_title"
-                    android:layout_width="match_parent"
-                    android:layout_height="0dp"
-                    android:layout_weight="1"
-                    android:text="@string/settings_label"
-                    style="@style/ContextualSuggestionText"/>
-
-                <Button
-                    android:id="@+id/suggestion_button"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="@dimen/suggestion_button_margin_top"
-                    android:paddingHorizontal="@dimen/suggestion_button_padding_horizontal"
-                    android:visibility="gone"
-                    style="@style/ActionPrimaryButton"/>
-
-            </LinearLayout>
+                android:layout_height="wrap_content"/>
 
             <include layout="@layout/search_bar"/>
 
diff --git a/res/layout/supported_links_dialog_item.xml b/res/layout/supported_links_dialog_item.xml
new file mode 100644
index 0000000..bbd2857
--- /dev/null
+++ b/res/layout/supported_links_dialog_item.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+
+<CheckedTextView
+     xmlns:android="http://schemas.android.com/apk/res/android"
+     android:id="@android:id/text1"
+     android:layout_width="match_parent"
+     android:layout_height="wrap_content"
+     android:minHeight="?android:attr/listPreferredItemHeightSmall"
+     android:ellipsize="marquee"
+     android:gravity="center_vertical"
+     android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+     android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+     android:textAlignment="viewStart"
+     android:textAppearance="?android:attr/textAppearanceListItemSmall"
+     android:textColor="?android:attr/textColorAlertDialogListItem"
+     android:drawableLeft="?android:attr/listChoiceIndicatorMultiple" />
+
diff --git a/res/layout/verified_links_widget.xml b/res/layout/verified_links_widget.xml
new file mode 100644
index 0000000..322ddd5
--- /dev/null
+++ b/res/layout/verified_links_widget.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="match_parent"
+    android:orientation="horizontal">
+
+    <include layout="@layout/preference_widget_info"
+             android:id="@+id/verified_links_widget" />
+</LinearLayout>
\ No newline at end of file
diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml
index 4eb0afd..b2f9a89 100644
--- a/res/values-night/colors.xml
+++ b/res/values-night/colors.xml
@@ -21,7 +21,7 @@
     <color name="homepage_support_background">#3F5FBD</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>
+    <color name="search_bar_background">@*android:color/material_grey_900</color>
     <!-- Dialog background color. -->
     <color name="dialog_background">@*android:color/material_grey_800</color>
     <color name="notification_importance_selection_bg">@*android:color/material_grey_800</color>
diff --git a/res/values/config.xml b/res/values/config.xml
index 984906f..5a8f636 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -509,4 +509,20 @@
 
     <!-- Cell broacast receiver package name -->
     <string name="config_cell_broadcast_receiver_package" translatable="false">com.android.cellbroadcastreceiver.module</string>
+
+    <!-- TODO(b/174964885): These media Uri are not defined in framework yet. Replace with framework defined variables once it's available. -->
+    <!-- Media Uri to view images storage category. -->
+    <string name="config_images_storage_category_uri" translatable="false">content://com.android.providers.media.documents/root/images_root</string>
+
+    <!-- Media Uri to view videos storage category. -->
+    <string name="config_videos_storage_category_uri" translatable="false">content://com.android.providers.media.documents/root/videos_root</string>
+
+    <!-- Media Uri to view audios storage category. -->
+    <string name="config_audios_storage_category_uri" translatable="false">content://com.android.providers.media.documents/root/audio_root</string>
+
+    <!-- Media Uri to view documents & other storage category. -->
+    <string name="config_documents_and_other_storage_category_uri" translatable="false">content://com.android.providers.media.documents/root/documents_root</string>
+
+    <!-- Whether to show Smart Storage toggle -->
+    <bool name="config_show_smart_storage_toggle">true</bool>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 0ee39cd..e0e0219 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -131,25 +131,21 @@
     <dimen name="switchbar_subsettings_margin_start">72dp</dimen>
     <dimen name="switchbar_subsettings_margin_end">16dp</dimen>
 
-    <!-- Search bar and avatar -->
-    <dimen name="search_bar_margin">24dp</dimen>
-    <dimen name="search_bar_margin_bottom">16dp</dimen>
-    <dimen name="search_bar_height">48dp</dimen>
-    <dimen name="search_bar_text_size">16sp</dimen>
-    <dimen name="search_bar_card_elevation">2dp</dimen>
-    <dimen name="search_bar_content_inset">64dp</dimen>
-    <dimen name="avatar_length">@dimen/search_bar_height</dimen>
+    <!-- Search bar -->
+    <dimen name="search_bar_margin">16dp</dimen>
+    <dimen name="search_bar_height">52dp</dimen>
+    <dimen name="search_bar_text_size">20sp</dimen>
+    <dimen name="search_bar_corner_radius">28dp</dimen>
+    <dimen name="search_bar_content_inset">56dp</dimen>
 
-    <!-- Contextual suggestions -->
-    <dimen name="suggestion_height">232dp</dimen>
-    <dimen name="suggestion_padding_horizontal">24dp</dimen>
-    <dimen name="suggestion_padding_vertical">8dp</dimen>
-    <dimen name="suggestion_button_margin_top">16dp</dimen>
-    <dimen name="suggestion_button_padding_horizontal">24dp</dimen>
+    <!-- Avatar -->
+    <dimen name="avatar_length">48dp</dimen>
+    <dimen name="avatar_margin_top">56dp</dimen>
+    <dimen name="avatar_margin_end">24dp</dimen>
 
-    <!-- Tool bar text -->
-    <dimen name="tool_bar_max_text_size">36sp</dimen>
-    <dimen name="tool_bar_min_text_size">24sp</dimen>
+    <!-- Homepage title -->
+    <dimen name="homepage_title_margin_bottom">8dp</dimen>
+    <dimen name="homepage_title_margin_horizontal">24dp</dimen>
 
     <!-- Dimensions for Wifi Assistant Card -->
     <dimen name="wifi_assistant_padding_top_bottom">16dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 8ced85c..05b07e5 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -684,6 +684,11 @@
     </plurals>
     <!-- Location settings, loading the number of apps which have location permission [CHAR LIMIT=30] -->
     <string name="location_settings_loading_app_permission_stats">Loading\u2026</string>
+    <!-- Location settings footer warning text [CHAR LIMIT=NONE] -->
+    <string name="location_settings_footer">
+        Location may use sources like GPS, Wi\u2011Fi, mobile networks, and sensors to help estimate
+        your device\u2019s location.
+    </string>
 
     <!-- Main Settings screen setting option title for the item to take you to the accounts screen [CHAR LIMIT=22] -->
     <string name="account_settings_title">Accounts</string>
@@ -839,6 +844,8 @@
     <string name="security_settings_face_settings_use_face_for_apps">App sign-in \u0026 payments</string>
     <!-- Title for a category shown for the face settings page, followed by items that the user can toggle on/off to require/disable. -->
     <string name="security_settings_face_settings_require_category">Requirements for face unlock</string>
+    <!-- Title for a category shown for the face settings page, followed by items that the user can toggle on/off to require/disable. [CHAR LIMIT=50] -->
+    <string name="security_settings_face_settings_preferences_category">When using face unlock</string>
     <!-- Text shown on a toggle which disables/enables face unlock, depending if the user's eyes are open. [CHAR LIMIT=30] -->
     <string name="security_settings_face_settings_require_attention">Require eyes to be open</string>
     <!-- Text shown on the details of a toggle which disables/enables face unlock, depending if the user's eyes are open. [CHAR LIMIT=70] -->
@@ -849,6 +856,8 @@
     <string name="security_settings_face_settings_require_confirmation_details">When using face unlock in apps, always require confirmation step</string>
     <!-- Button text in face settings which removes the user's faces from the device [CHAR LIMIT=20] -->
     <string name="security_settings_face_settings_remove_face_data">Delete face data</string>
+    <!-- Button text in face settings which removes the user's face model from the device [CHAR LIMIT=40] -->
+    <string name="security_settings_face_settings_remove_face_model">Delete face model</string>
     <!-- Button text in face settings which lets the user enroll their face [CHAR LIMIT=40] -->
     <string name="security_settings_face_settings_enroll">Set up face unlock</string>
     <!-- Text shown in face settings explaining what your face can be used for. [CHAR LIMIT=NONE] -->
@@ -861,6 +870,10 @@
     <string name="security_settings_face_settings_remove_dialog_title">Delete face data?</string>
     <!-- Dialog contents shown when the user removes an enrollment [CHAR LIMIT=NONE] -->
     <string name="security_settings_face_settings_remove_dialog_details">The face data used by face unlock will be permanently and securely deleted. After removal, you will need your PIN, pattern, or password to unlock your phone, sign in to apps, and confirm payments.</string>
+    <!-- Dialog title shown when the user chooses to delete an existing enrolled face model. [CHAR LIMIT=35] -->
+    <string name="security_settings_face_settings_remove_model_dialog_title">Delete face model?</string>
+    <!-- Dialog contents shown when the user chooses to delete an existing enrolled face model. [CHAR LIMIT=NONE] -->
+    <string name="security_settings_face_settings_remove_model_dialog_details">Your face model will be permanently and securely deleted.\n\nAfter deletion, you will need your fingerprint, PIN, pattern, or password to unlock your phone or for authentication in apps.</string>
     <!-- Subtitle shown for contextual setting face enrollment [CHAR LIMIT=NONE] -->
     <string name="security_settings_face_settings_context_subtitle">Use face unlock to unlock your phone</string>
 
@@ -1064,6 +1077,25 @@
     <!-- Button to confirm the last removing the last fingerprint. [CHAR LIMIT=20]-->
     <string name="fingerprint_last_delete_confirm">Yes, remove</string>
 
+    <!-- Title of the combined biometrics settings screen. [CHAR LIMIT=40] -->
+    <string name="security_settings_biometrics_title">Face \u0026 fingerprint unlock</string>
+    <!-- Summary of the current biometrics setting when no biometrics have been enrolled. [CHAR LIMIT=50] -->
+    <string name="security_settings_biometrics_summary_none">Tap to set up</string>
+    <!-- Summary of the current biometrics setting when the user has enrolled a face but no fingerprint. [CHAR LIMIT=50] -->
+    <string name="security_settings_biometrics_summary_face">Face only</string>
+    <!-- Summary of the current biometrics setting when the user has enrolled a fingerprint but no face. [CHAR LIMIT=50] -->
+    <string name="security_settings_biometrics_summary_fingerprint">Fingerprint only</string>
+    <!-- Summary of the current biometrics setting when the user has enrolled both a face and a fingerprint. [CHAR LIMIT=50] -->
+    <string name="security_settings_biometrics_summary_both">Face and fingerprint</string>
+    <!-- Description shown on the combined biometrics settings screen. [CHAR LIMIT=NONE] -->
+    <string name="security_settings_biometrics_description">When you set up face and fingerprint unlock, your phone will ask for your fingerprint when you wear a mask or are in a dark area</string>
+    <!-- Title of a section on the biometrics settings screen for setting up different types of authentication. [CHAR LIMIT=50] -->
+    <string name="security_settings_biometrics_types_category">Ways to unlock</string>
+    <!-- Title of a section on the biometrics settings screen for adjusting authentication preferences. [CHAR LIMIT=50] -->
+    <string name="security_settings_biometrics_preferences_category">Use face or fingerprint for</string>
+    <!-- Title of a section on the biometrics settings screen for adjusting authentication preferences. [CHAR LIMIT=50] -->
+    <string name="security_settings_biometrics_preference_use_with_apps">Authentication in apps</string>
+
     <!-- Title of the preferences category for preference items to control encryption -->
     <string name="crypt_keeper_settings_title">Encryption</string>
 
@@ -1328,15 +1360,15 @@
     <string name="face_unlock_title">You can unlock your phone using your face. For security, this option requires a backup screen lock.</string>
 
     <!-- Title for preference that guides the user through creating a backup unlock pattern for biometrics unlock [CHAR LIMIT=45]-->
-    <string name="biometrics_unlock_set_unlock_pattern">Biometrics + Pattern</string>
+    <string name="biometrics_unlock_set_unlock_pattern">Pattern \u2022 Face \u2022 Fingerprint</string>
     <!-- Title for preference that guides the user through creating a backup unlock PIN for biometrics unlock [CHAR LIMIT=45]-->
-    <string name="biometrics_unlock_set_unlock_pin">Biometrics + PIN</string>
+    <string name="biometrics_unlock_set_unlock_pin">PIN \u2022 Face \u2022 Fingerprint</string>
     <!-- Title for preference that guides the user through creating a backup unlock password for biometrics unlock [CHAR LIMIT=45]-->
-    <string name="biometrics_unlock_set_unlock_password">Biometrics + Password</string>
+    <string name="biometrics_unlock_set_unlock_password">Password \u2022 Face \u2022 Fingerprint</string>
     <!-- Title for preference that guides the user to skip face unlock setup [CHAR LIMIT=60]-->
-    <string name="biometrics_unlock_skip_biometrics">Continue without biometrics</string>
+    <string name="biometrics_unlock_skip_biometrics">Continue without face or fingerprint</string>
     <!-- Message shown in screen lock picker while setting up the new screen lock with biometrics option. [CHAR LIMIT=NONE] -->
-    <string name="biometrics_unlock_title">You can unlock your phone using your biometrics. For security, this option requires a backup screen lock.</string>
+    <string name="biometrics_unlock_title">You can unlock your phone using your face or fingerprint. For security, this option requires a backup screen lock.</string>
 
     <!-- Summary for preference that has been disabled by because of the DevicePolicyAdmin, or because device encryption is enabled, or because there are credentials in the credential storage [CHAR LIMIT=50] -->
     <string name="unlock_set_unlock_disabled_summary">Disabled by admin, encryption policy, or
@@ -2314,6 +2346,8 @@
     <string name="wifi_details_title">Network details</string>
     <!-- Wifi details preference title to display router IP subnet mask -->
     <string name="wifi_details_subnet_mask">Subnet mask</string>
+    <!-- Wifi details preference title to display wifi type info [CHAR LIMIT=50]-->
+    <string name="wifi_type_title">TYPE</string>
     <!-- Wifi details preference title to display router DNS info -->
     <string name="wifi_details_dns">DNS</string>
     <!-- Wifi details preference category title for IPv6 information -->
@@ -2349,6 +2383,12 @@
     <string name="wifi_gateway">Gateway</string>
     <!-- Label for the network prefix of the network [CHAR LIMIT=25]-->
     <string name="wifi_network_prefix_length">Network prefix length</string>
+    <!-- Summary for the WiFi Type WIFI_STANDARD_11AX [CHAR LIMIT=50]-->
+    <string name="wifi_type_11AX">Wi\u2011Fi 6</string>
+    <!-- Summary for the WiFi Type WIFI_STANDARD_11AC [CHAR LIMIT=50]-->
+    <string name="wifi_type_11AC">Wi\u2011Fi 5</string>
+    <!-- Summary for the WiFi Type WIFI_STANDARD_11N  [CHAR LIMIT=50]-->
+    <string name="wifi_type_11N">Wi\u2011Fi 4</string>
 
     <!-- Wi-Fi p2p / Wi-Fi Direct settings -->
     <!-- Used in the 1st-level settings screen to launch Wi-fi Direct settings [CHAR LIMIT=25] -->
@@ -2959,6 +2999,8 @@
     <string name="wallpaper_settings_title">Wallpaper</string>
     <!-- Styles & Wallpapers settings title [CHAR LIMIT=30] -->
     <string name="style_and_wallpaper_settings_title">Styles &amp; wallpapers</string>
+    <!-- Summary for the top level Styles & wallpapers Settings [CHAR LIMIT=NONE]-->
+    <string name="wallpaper_dashboard_summary">Colors, app grid</string>
     <!-- Wallpaper settings summary when default wallpaper is used [CHAR LIMIT=NONE] -->
     <string name="wallpaper_settings_summary_default">Default</string>
     <!-- Wallpaper settings summary when wallpaper has been updated [CHAR LIMIT=NONE] -->
@@ -3398,22 +3440,6 @@
     <!-- Section header above list of external storage devices [CHAR LIMIT=30]-->
     <string name="storage_external_title">Portable storage</string>
 
-    <!-- Label for the settings activity for controlling apps that can schedule alarms [CHAR LIMIT=30] -->
-    <string name="alarms_and_reminders_label">Alarms and reminders</string>
-    <!-- Label for the switch to toggler the permission for scheduling alarms [CHAR LIMIT=50] -->
-    <string name="alarms_and_reminders_switch_title">Allow to set alarms or reminders</string>
-    <!-- Title for the setting screen for controlling apps that can schedule alarms [CHAR LIMIT=30] -->
-    <string name="alarms_and_reminders_title">Alarms and reminders</string>
-    <!-- Description that appears below the alarms_and_reminders switch [CHAR LIMIT=NONE] -->
-    <string name="alarms_and_reminders_footer_title">
-        Allow this app to schedule alarms or other timing based events.
-        This will allow the app to wake up and run even when you are not using the device.
-        Note that revoking this permission may cause the app to malfunction, specifically any alarms
-        that the app has scheduled will no longer work.
-    </string>
-    <!-- Keywords for setting screen for controlling apps that can schedule alarms [CHAR LIMIT=100] -->
-    <string name="keywords_alarms_and_reminders">schedule, alarm, reminder, event</string>
-
     <!-- Summary of a single storage volume, constrasting available and total storage space. [CHAR LIMIT=48]-->
     <string name="storage_volume_summary"><xliff:g id="used" example="1.2GB">%1$s</xliff:g> used of <xliff:g id="total" example="32GB">%2$s</xliff:g></string>
     <!-- Summary of a single storage volume used space. [CHAR LIMIT=24] -->
@@ -4079,6 +4105,18 @@
 
     <!-- [CHAR LIMIT=60] Date&Time settings screen, toggle button title -->
     <string name="location_time_zone_detection_toggle_title">Use location to set time zone</string>
+    <!-- [CHAR LIMIT=60] Date&Time settings screen, title of the dialog shown when user tries to
+         enable GeoTZ when Location toggle is off. -->
+    <string name="location_time_zone_detection_location_is_off_dialog_title">Device location needed</string>
+    <!-- [CHAR LIMIT=NONE] Date&Time settings screen, message on the dialog shown when user tries to
+         enable GeoTZ when Location toggle is off. -->
+    <string name="location_time_zone_detection_location_is_off_dialog_message">To set the time zone using your location, turn on location, then update time zone settings</string>
+    <!-- [CHAR LIMIT=30] Date&Time settings screen, button on a dialog shown when user tries to
+    enable GeoTZ, but Location toggle is off, which leads to Location settings page. -->
+    <string name="location_time_zone_detection_location_is_off_dialog_ok_button">Location settings</string>
+    <!-- [CHAR LIMIT=30] Date&Time settings screen, button on a dialog shown when user tries to
+     enable GeoTZ, but Location toggle is off, which closes the dialog. -->
+    <string name="location_time_zone_detection_location_is_off_dialog_cancel_button">Cancel</string>
     <!-- [CHAR LIMIT=NONE] Location settings screen, summary when location time zone detection is not
          applicable due to other settings like the "automatic time zone detection enabled" setting
          being set to "off". -->
@@ -5065,7 +5103,7 @@
     <!-- Title for the accessibility magnification switch shortcut dialog. [CHAR LIMIT=48] -->
     <string name="accessibility_magnification_switch_shortcut_title">Switch to accessibility button?</string>
     <!-- Message for the accessibility magnification switch shortcut dialog. [CHAR LIMIT=none] -->
-    <string name="accessibility_magnification_switch_shortcut_message">Using triple-tap to magnify part of the screen causes typing and other delays.\n\nThe accessibility button floats on your screen over other apps. Tap it to magnify.</string>
+    <string name="accessibility_magnification_switch_shortcut_message">Using triple-tap to magnify part of your screen causes typing and other delays.\n\nThe accessibility button floats on your screen over other apps. Tap it to magnify.</string>
     <!-- Title for the switch shortcut button in accessibility switch shortcut dialog to change the config shortcut value. [CHAR LIMIT=45] -->
     <string name="accessibility_magnification_switch_shortcut_positive_button">Switch to accessibility button</string>
     <!-- Title for the cancel button in accessibility switch shortcut dialog to keep the config shortcut value. [CHAR LIMIT=54] -->
@@ -5805,6 +5843,8 @@
     <string name="history_details_title">History details</string>
     <!-- Preference title for advanced battery usage [CHAR LIMIT=40] -->
     <string name="advanced_battery_preference_title">View battery usage</string>
+    <!-- Preference summary for advanced battery usage [CHAR LIMIT=40] -->
+    <string name="advanced_battery_preference_summary">View usage for past 24 hours</string>
 
     <!-- Activity title for battery usage details for an app. or power consumer -->
     <string name="battery_details_title">Battery usage</string>
@@ -5941,7 +5981,7 @@
     <string name="battery_auto_restriction_summary">Detect when apps drain battery</string>
 
     <!-- Summary for battery manager when it is on -->
-    <string name="battery_manager_on" product="default">On / Detecting when apps drain battery</string>
+    <string name="battery_manager_summary">Detecting when apps drain battery</string>
 
     <!-- Summary for battery manager when it is off -->
     <string name="battery_manager_off">Off</string>
@@ -6207,6 +6247,9 @@
     <!-- Battery saver: Label for preference to indicate there is a routine based schedule [CHAR_LIMIT=40] -->
     <string name="battery_saver_auto_routine">Based on your routine</string>
 
+    <!-- Battery saver: Summary for preference to indicate there is a routine based schedule [CHAR_LIMIT=40] -->
+    <string name="battery_saver_pref_auto_routine_summary">Will turn on based on your routine</string>
+
     <!-- Battery saver: Label for preference to indicate there is a percentage based schedule [CHAR_LIMIT=40] -->
     <string name="battery_saver_auto_percentage">Based on percentage</string>
 
@@ -6398,6 +6441,10 @@
 
     <!-- Title of preference to enter the VPN settings activity -->
     <string name="vpn_settings_title">VPN</string>
+    <!-- Title of preference to enter the VPN settings activity [CHAR LIMIT=30] -->
+    <string name="vpn_settings_insecure_single">Not secure</string>
+    <!-- Title of preference to enter the VPN settings activity [CHAR LIMIT=30] -->
+    <string name="vpn_settings_insecure_multiple"><xliff:g id="vpn_count" example="1">%d</xliff:g> not secure</string>
 
     <!-- Title of Adaptive connectivity. Adaptive connectivity is a feature which automatically manages network connections for better battery life and performance. [CHAR LIMIT=60] -->
     <string name="adaptive_connectivity_title">Adaptive connectivity</string>
@@ -6570,7 +6617,7 @@
 
     <!-- Message displayed to let the user know that some of the options are disabled by admin. [CHAR LIMIT=NONE] -->
     <string name="admin_disabled_other_options">Other options are disabled by your admin</string>
-    <string name="admin_more_details">More details</string>
+    <string name="admin_more_details">Learn more</string>
     <string name="notification_log_title">Notification log</string>
 
     <string name="notification_history_title">Notification history</string>
@@ -7272,6 +7319,12 @@
     <!-- Summary for the emergency info preference [CHAR LIMIT=40] -->
     <string name="emergency_info_summary">Info &amp; contacts for <xliff:g id="user_name" example="Jason">%1$s</xliff:g></string>
 
+    <!-- Button label for opening an arbitrary app [CHAR LIMIT=60] -->
+    <string name="open_app_button">Open <xliff:g id="app_name" example="Safety">%1$s</xliff:g></string>
+
+    <!-- Title for more settings button, clicking this button will open a new page containing more settings related to current page. [CHAR LIMIT=60] -->
+    <string name="more_settings_button">More Settings</string>
+
     <!-- Application Restrictions screen title [CHAR LIMIT=45] -->
     <string name="application_restrictions">Allow apps and content</string>
     <!-- Applications with restrictions header [CHAR LIMIT=45] -->
@@ -7771,10 +7824,10 @@
     <string name="app_and_notification_dashboard_summary">Recent apps, default apps</string>
     <!-- Toast shown when an app in the work profile attempts to open notification settings. The apps in the work profile cannot access notification settings. [CHAR LIMIT=NONE] -->
     <string name="notification_settings_work_profile">Notification access is not available for apps in the work profile.</string>
-    <!-- Title for setting tile leading to account settings [CHAR LIMIT=40]-->
-    <string name="account_dashboard_title">Accounts</string>
-    <!-- Summary for account settings tiles when there is no accounts on device [CHAR LIMIT=NONE]-->
-    <string name="account_dashboard_default_summary">No accounts added</string>
+    <!-- Title for setting tile leading to saved autofill passwords, autofill, and account settings [CHAR LIMIT=40]-->
+    <string name="account_dashboard_title">Passwords and accounts</string>
+    <!-- Summary for setting tile leading to saved autofill passwords, autofill, and account settings [CHAR LIMIT=NONE]-->
+    <string name="account_dashboard_default_summary">Saved passwords, autofill, synced accounts</string>
     <!-- Title for setting tile leading to setting UI which allows user set default app to
     handle actions such as open web page, making phone calls, default SMS apps [CHAR  LIMIT=40]-->
     <string name="app_default_dashboard_title">Default apps</string>
@@ -8394,6 +8447,9 @@
     <!-- Configure Notifications Settings title. [CHAR LIMIT=30] -->
     <string name="configure_notification_settings">Notifications</string>
 
+    <!-- Summary for the top level Notifications Settings [CHAR LIMIT=NONE]-->
+    <string name="notification_dashboard_summary">Notification history, conversations</string>
+
     <!-- notification header - settings for conversation type notifications -->
     <string name="conversation_notifs_category">Conversation</string>
 
@@ -10529,6 +10585,9 @@
     <!-- Summary for Display settings, explaining a few important settings under it [CHAR LIMIT=NONE]-->
     <string name="display_dashboard_summary_with_style">Styles, wallpapers, screen timeout, font size</string>
 
+    <!-- Summary for the top level Display Settings [CHAR LIMIT=NONE]-->
+    <string name="display_dashboard_summary_2">Screen timeout, font size</string>
+
     <!-- Summary for Display settings, explaining a few important settings under it [CHAR LIMIT=NONE]-->
     <string name="display_dashboard_nowallpaper_summary">Sleep, font size</string>
 
@@ -11227,6 +11286,9 @@
     <!-- Preference title for "Safety & emergency" settings page [CHAR LIMIT=60]-->
     <string name="emergency_settings_preference_title">Safety &amp; emergency</string>
 
+    <!-- Summary for the top level Safety & emergency Settings [CHAR LIMIT=NONE]-->
+    <string name="emergency_dashboard_summary">Emergency SOS, medical info, alerts</string>
+
     <!-- Title text for edge to edge navigation [CHAR LIMIT=60] -->
     <string name="edge_to_edge_navigation_title">Gesture navigation</string>
     <!-- Summary text for edge to edge navigation [CHAR LIMIT=NONE] -->
@@ -11280,8 +11342,8 @@
 
     <!-- Title text for swiping downwards on the bottom of the screen for notifications [CHAR LIMIT=60]-->
     <string name="swipe_bottom_to_notifications_title">Swipe for notifications</string>
-    <!-- Summary text for swiping downwards on the bottom of the screen for notifications [CHAR LIMIT=80]-->
-    <string name="swipe_bottom_to_notifications_summary">Swipe down on the bottom edge of the screen to show your notifications</string>
+    <!-- Summary text for swiping downwards on the bottom of the screen for notifications [CHAR LIMIT=NONE]-->
+    <string name="swipe_bottom_to_notifications_summary">Swipe down on the bottom edge of the screen to show your notifications.\nYou can\'t use one-handed mode when this feature is turned on.</string>
 
     <!-- Preference and settings suggestion title text for one handed [CHAR LIMIT=60] -->
     <string name="one_handed_title">One-Handed mode</string>
@@ -11669,6 +11731,12 @@
     <string name="autofill_app">Autofill service</string>
     <!-- Preference category for showing auto-fill services with saved passwords. [CHAR LIMIT=60] -->
     <string name="autofill_passwords">Passwords</string>
+    <!-- Summary for passwords settings that shows how many passwords are saved for each autofill
+         service. [CHAR LIMIT=NONE] -->
+    <plurals name="autofill_passwords_count">
+        <item quantity="one"><xliff:g id="count">%1$d</xliff:g> password</item>
+        <item quantity="other"><xliff:g id="count">%1$d</xliff:g> passwords</item>
+    </plurals>
     <!-- Keywords for the auto-fill feature. [CHAR LIMIT=NONE] -->
     <string name="autofill_keywords">auto, fill, autofill, password</string>
 
@@ -12741,6 +12809,12 @@
     <!-- Power menu setting privacy no secure screen lock set [CHAR_LIMIT=NONE] -->
     <string name="power_menu_privacy_not_secure">To use, first set a screen lock</string>
 
+    <!-- Power menu setting use long press power to invoke assistant. [CHAR_LIMIT=NONE] -->
+    <string name="power_menu_long_press_for_assist">Hold for Assistant</string>
+
+    <!-- Power menu setting use log press power to invoke assistant summary. [CHAR_LIMIT=NONE] -->
+    <string name="power_menu_long_press_for_assist_summary">Trigger the Assistant by holding the power button</string>
+
     <!-- Device controls toggle name [CHAR LIMIT=60] -->
     <string name="device_controls_setting_toggle">Show device controls</string>
 
@@ -12912,10 +12986,12 @@
     <string name="category_name_brightness">Brightness</string>
     <!-- Lock screen category name in Display Settings [CHAR LIMIT=none] -->
     <string name="category_name_lock_display">Lock Display</string>
-    <!-- Visibility category name in Display Settings [CHAR LIMIT=none] -->
-    <string name="category_name_visibility">Visibility</string>
+    <!-- Appearance category name in Display Settings [CHAR LIMIT=none] -->
+    <string name="category_name_appearance">Appearance</string>
     <!-- Color category name in Display Settings [CHAR LIMIT=none] -->
     <string name="category_name_color">Color</string>
+    <!-- Name of Other display controls category in Display Settings [CHAR LIMIT=none] -->
+    <string name="category_name_display_controls">Other Display Controls</string>
     <!-- Others category name [CHAR LIMIT=none] -->
     <string name="category_name_others">Others</string>
     <!-- General category name [CHAR LIMIT=none] -->
@@ -12999,4 +13075,7 @@
 
     <!-- Summary for toggle controlling whether notifications are shown when an app pastes from clipboard. [CHAR LIMIT=NONE] -->
     <string name="show_clip_access_notification_summary">Show a message when apps access text, images, or other content you\u2019ve copied</string>
+
+    <!-- All apps screen title, entry name on Apps page for the user to go to the all apps page. [CHAR LIMIT=30] -->
+    <string name="all_apps">All apps</string>
 </resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 0d773f1..8ca72db 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -310,6 +310,7 @@
     <style name="TextAppearance.SearchBar"
            parent="@*android:style/TextAppearance.DeviceDefault.Widget.Toolbar.Subtitle">
         <item name="android:textSize">@dimen/search_bar_text_size</item>
+        <item name="android:textColor">?android:attr/textColorTertiary</item>
         <item name="android:singleLine">true</item>
     </style>
 
@@ -418,7 +419,6 @@
     </style>
 
     <style name="ActionPrimaryButton" parent="android:Widget.DeviceDefault.Button.Colored"/>
-
     <style name="ActionSecondaryButton" parent="android:Widget.DeviceDefault.Button"/>
 
     <style name="LockPatternContainerStyle">
@@ -481,11 +481,8 @@
     </style>
 
     <style name="SearchBarStyle">
-        <item name="android:layout_marginEnd">@dimen/search_bar_margin</item>
-        <item name="cardCornerRadius">34dp</item>
-        <item name="enforceMaterialTheme">true</item>
-        <item name="cardElevation">3dp</item>
-        <item name="shapeAppearance">@null</item>
+        <item name="cardCornerRadius">@dimen/search_bar_corner_radius</item>
+        <item name="cardElevation">0dp</item>
     </style>
 
     <style name="ConditionCardBorderlessButton"
@@ -789,13 +786,11 @@
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
     </style>
 
-    <style name="ContextualSuggestionText"
-           parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
-        <item name="android:autoSizeTextType">uniform</item>
-        <item name="android:autoSizeMaxTextSize">@dimen/tool_bar_max_text_size</item>
-        <item name="android:autoSizeMinTextSize">@dimen/tool_bar_min_text_size</item>
-        <item name="android:maxLines">3</item>
-        <item name="android:gravity">bottom</item>
+    <style name="HomepageTitleText" parent="ToolbarText">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_marginBottom">@dimen/homepage_title_margin_bottom</item>
+        <item name="android:layout_marginHorizontal">@dimen/homepage_title_margin_horizontal</item>
     </style>
 
     <style name="RequestManageCredentialsButtonPanel">
@@ -883,16 +878,7 @@
         <item name="android:textColor">?android:attr/textColorSecondary</item>
     </style>
 
-    <style name="ToolbarText.Collapsed"
-           parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
-    </style>
-
-    <style name="ToolbarText"
-           parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
-        <item name="android:textSize">@dimen/tool_bar_max_text_size</item>
-    </style>
-
-    <style name="ToolbarText.MoreThanTwoLines">
-        <item name="android:textSize">@dimen/tool_bar_min_text_size</item>
-    </style>
+    <style name="ToolbarText.Collapsed" parent="CollapsingToolbarTitle.Collapsed"/>
+    <style name="ToolbarText" parent="CollapsingToolbarTitle"/>
+    <style name="ToolbarText.MoreThanTwoLines" parent="CollapsingToolbarTitle.MoreThanTwoLines"/>
 </resources>
diff --git a/res/values/themes.xml b/res/values/themes.xml
index bed02c8..d7b3257 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -23,10 +23,7 @@
         <item name="android:windowIsFloating">true</item>
     </style>
 
-    <style name="Theme.SettingsBase" parent="@android:style/Theme.DeviceDefault.Settings" />
-
     <style name="Theme.Settings" parent="Theme.SettingsBase">
-        <item name="preferenceTheme">@style/PreferenceTheme</item>
         <item name="android:clipToPadding">false</item>
         <item name="android:clipChildren">false</item>
         <item name="android:listPreferredItemHeight">72dip</item>
diff --git a/res/xml/accounts_dashboard_settings.xml b/res/xml/accounts_dashboard_settings.xml
index d2affc7..c50eca4 100644
--- a/res/xml/accounts_dashboard_settings.xml
+++ b/res/xml/accounts_dashboard_settings.xml
@@ -22,27 +22,57 @@
     settings:keywords="@string/keywords_accounts">
 
     <PreferenceCategory
-        android:key="dashboard_tile_placeholder"
-        android:order="30"/>
+        android:key="passwords_category"
+        android:order="10"
+        android:persistent="false"
+        android:title="@string/autofill_passwords"
+        settings:controller="com.android.settings.applications.autofill.PasswordsPreferenceController"
+        settings:keywords="@string/autofill_keywords" />
 
-    <SwitchPreference
-        android:key="auto_sync_account_data"
-        android:title="@string/auto_sync_account_title"
-        android:summary="@string/auto_sync_account_summary"
-        android:order="102"
-        settings:allowDividerAbove="true"/>
+    <PreferenceCategory
+        android:key="default_service_category"
+        android:order="20"
+        android:title="@string/autofill_app">
 
-    <SwitchPreference
-        android:key="auto_sync_work_account_data"
-        android:title="@string/account_settings_menu_auto_sync_work"
-        android:summary="@string/auto_sync_account_summary"
-        settings:forWork="true"
-        android:order="103"/>
+        <com.android.settings.widget.GearPreference
+            android:fragment="com.android.settings.applications.defaultapps.DefaultAutofillPicker"
+            android:key="default_autofill_main"
+            android:title="@string/autofill_app"
+            settings:keywords="@string/autofill_keywords">
+            <extra
+                android:name="for_work"
+                android:value="false" />
+        </com.android.settings.widget.GearPreference>
+    </PreferenceCategory>
 
-    <SwitchPreference
-        android:key="auto_sync_personal_account_data"
-        android:title="@string/account_settings_menu_auto_sync_personal"
-        android:summary="@string/auto_sync_account_summary"
-        android:order="104"/>
+    <PreferenceCategory
+        android:key="accounts_category"
+        android:order="100"
+        android:title="@string/account_settings">
+
+        <PreferenceCategory
+            android:key="dashboard_tile_placeholder"
+            android:order="130"/>
+
+        <SwitchPreference
+            android:key="auto_sync_account_data"
+            android:title="@string/auto_sync_account_title"
+            android:summary="@string/auto_sync_account_summary"
+            android:order="202"
+            settings:allowDividerAbove="true"/>
+
+        <SwitchPreference
+            android:key="auto_sync_work_account_data"
+            android:title="@string/account_settings_menu_auto_sync_work"
+            android:summary="@string/auto_sync_account_summary"
+            settings:forWork="true"
+            android:order="203"/>
+
+        <SwitchPreference
+            android:key="auto_sync_personal_account_data"
+            android:title="@string/account_settings_menu_auto_sync_personal"
+            android:summary="@string/auto_sync_account_summary"
+            android:order="204"/>
+    </PreferenceCategory>
 
 </PreferenceScreen>
diff --git a/res/xml/accounts_personal_dashboard_settings.xml b/res/xml/accounts_personal_dashboard_settings.xml
index db57e3d..3d88cf9 100644
--- a/res/xml/accounts_personal_dashboard_settings.xml
+++ b/res/xml/accounts_personal_dashboard_settings.xml
@@ -23,20 +23,50 @@
     settings:keywords="@string/keywords_accounts">
 
     <PreferenceCategory
-        android:key="dashboard_tile_placeholder"
-        android:order="30"/>
+        android:key="passwords_category"
+        android:order="10"
+        android:persistent="false"
+        android:title="@string/autofill_passwords"
+        settings:controller="com.android.settings.applications.autofill.PasswordsPreferenceController"
+        settings:keywords="@string/autofill_keywords" />
 
-    <SwitchPreference
-        android:key="auto_sync_account_data"
-        android:title="@string/auto_sync_account_title"
-        android:summary="@string/auto_sync_account_summary"
+    <PreferenceCategory
+        android:key="default_service_category"
+        android:order="20"
+        android:title="@string/autofill_app">
+
+        <com.android.settings.widget.GearPreference
+            android:fragment="com.android.settings.applications.defaultapps.DefaultAutofillPicker"
+            android:key="default_autofill_main"
+            android:title="@string/autofill_app"
+            settings:keywords="@string/autofill_keywords">
+            <extra
+                android:name="for_work"
+                android:value="false" />
+        </com.android.settings.widget.GearPreference>
+    </PreferenceCategory>
+
+    <PreferenceCategory
+        android:key="accounts_category"
         android:order="100"
-        settings:allowDividerAbove="true"/>
+        android:title="@string/account_settings">
 
-    <SwitchPreference
-        android:key="auto_sync_personal_account_data"
-        android:title="@string/account_settings_menu_auto_sync_personal"
-        android:summary="@string/auto_sync_account_summary"
-        android:order="110"/>
+        <PreferenceCategory
+            android:key="dashboard_tile_placeholder"
+            android:order="130"/>
+
+        <SwitchPreference
+            android:key="auto_sync_account_data"
+            android:title="@string/auto_sync_account_title"
+            android:summary="@string/auto_sync_account_summary"
+            android:order="200"
+            settings:allowDividerAbove="true"/>
+
+        <SwitchPreference
+            android:key="auto_sync_personal_account_data"
+            android:title="@string/account_settings_menu_auto_sync_personal"
+            android:summary="@string/auto_sync_account_summary"
+            android:order="210"/>
+    </PreferenceCategory>
 
 </PreferenceScreen>
diff --git a/res/xml/accounts_work_dashboard_settings.xml b/res/xml/accounts_work_dashboard_settings.xml
index b27357d..29e71e2 100644
--- a/res/xml/accounts_work_dashboard_settings.xml
+++ b/res/xml/accounts_work_dashboard_settings.xml
@@ -23,20 +23,50 @@
     settings:keywords="@string/keywords_accounts">
 
     <PreferenceCategory
-        android:key="dashboard_tile_placeholder"
-        android:order="30"/>
+        android:key="passwords_category"
+        android:order="10"
+        android:persistent="false"
+        android:title="@string/autofill_passwords"
+        settings:controller="com.android.settings.applications.autofill.PasswordsPreferenceController"
+        settings:keywords="@string/autofill_keywords" />
 
-    <SwitchPreference
-        android:key="auto_sync_account_data"
-        android:title="@string/auto_sync_account_title"
-        android:summary="@string/auto_sync_account_summary"
+    <com.android.settings.widget.WorkOnlyCategory
+        android:key="autofill_work_app_defaults"
+        android:order="30"
+        android:title="@string/default_for_work">
+
+        <com.android.settings.widget.GearPreference
+            android:fragment="com.android.settings.applications.defaultapps.DefaultAutofillPicker"
+            android:key="default_autofill_work"
+            android:title="@string/autofill_app"
+            settings:searchable="false">
+            <extra
+                android:name="for_work"
+                android:value="true" />
+        </com.android.settings.widget.GearPreference>
+    </com.android.settings.widget.WorkOnlyCategory>
+
+    <PreferenceCategory
+        android:key="accounts_category"
         android:order="100"
-        settings:allowDividerAbove="true"/>
+        android:title="@string/account_settings">
 
-    <SwitchPreference
-        android:key="auto_sync_work_account_data"
-        android:title="@string/account_settings_menu_auto_sync_work"
-        android:summary="@string/auto_sync_account_summary"
-        android:order="110"/>
+        <PreferenceCategory
+            android:key="dashboard_tile_placeholder"
+            android:order="130"/>
+
+        <SwitchPreference
+            android:key="auto_sync_account_data"
+            android:title="@string/auto_sync_account_title"
+            android:summary="@string/auto_sync_account_summary"
+            android:order="200"
+            settings:allowDividerAbove="true"/>
+
+        <SwitchPreference
+            android:key="auto_sync_work_account_data"
+            android:title="@string/account_settings_menu_auto_sync_work"
+            android:summary="@string/auto_sync_account_summary"
+            android:order="210"/>
+    </PreferenceCategory>
 
 </PreferenceScreen>
diff --git a/res/xml/apps.xml b/res/xml/apps.xml
index cefb67a..68b5c9a 100644
--- a/res/xml/apps.xml
+++ b/res/xml/apps.xml
@@ -23,7 +23,7 @@
 
     <Preference
         android:key="all_app_infos"
-        android:title="@string/applications_settings"
+        android:title="@string/all_apps"
         android:summary="@string/summary_placeholder"
         android:order="-999"
         android:fragment="com.android.settings.applications.manageapplications.ManageApplications"
diff --git a/res/xml/default_autofill_picker_settings.xml b/res/xml/default_autofill_picker_settings.xml
deleted file mode 100644
index 392f733..0000000
--- a/res/xml/default_autofill_picker_settings.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2018 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<PreferenceScreen
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:settings="http://schemas.android.com/apk/res-auto"
-    android:key="default_autofill_picker"
-    android:title="@string/autofill_app"
-    settings:keywords="@string/autofill_keywords">
-
-  <PreferenceCategory
-      android:key="passwords_category"
-      android:persistent="false"
-      android:title="@string/autofill_passwords"
-      settings:controller="com.android.settings.applications.autofill.PasswordsPreferenceController" >
-  </PreferenceCategory>
-
-  <PreferenceCategory
-      android:key="default_service_category"
-      android:title="@string/autofill_app">
-
-    <!-- TODO(b/169455298): Fix the redundant title. -->
-    <com.android.settings.widget.GearPreference
-        android:key="default_autofill_main"
-        android:title="@string/autofill_app"
-        android:fragment="com.android.settings.applications.defaultapps.DefaultAutofillPicker"
-        settings:searchable="false"
-        settings:keywords="@string/autofill_keywords">
-      <extra android:name="for_work" android:value="false" />
-    </com.android.settings.widget.GearPreference>
-  </PreferenceCategory>
-
-
-  <com.android.settings.widget.WorkOnlyCategory
-      android:key="autofill_work_app_defaults"
-      android:title="@string/default_for_work">
-
-    <com.android.settings.widget.GearPreference
-        android:key="default_autofill_work"
-        android:title="@string/autofill_app"
-        android:fragment="com.android.settings.applications.defaultapps.DefaultAutofillPicker"
-        settings:searchable="false"
-        settings:keywords="@string/autofill_keywords">
-      <extra android:name="for_work" android:value="true" />
-    </com.android.settings.widget.GearPreference>
-  </com.android.settings.widget.WorkOnlyCategory>
-</PreferenceScreen>
diff --git a/res/xml/display_settings_v2.xml b/res/xml/display_settings_v2.xml
index 0b43914..50879da 100644
--- a/res/xml/display_settings_v2.xml
+++ b/res/xml/display_settings_v2.xml
@@ -59,7 +59,7 @@
     </PreferenceCategory>
 
     <PreferenceCategory
-        android:title="@string/category_name_visibility">
+        android:title="@string/category_name_appearance">
 
         <com.android.settings.display.darkmode.DarkModePreference
             android:key="dark_ui_mode"
@@ -102,7 +102,7 @@
     </PreferenceCategory>
 
     <PreferenceCategory
-        android:title="@string/category_name_general">
+        android:title="@string/category_name_display_controls">
 
         <SwitchPreference
             android:key="auto_rotate"
diff --git a/res/xml/emergency_settings.xml b/res/xml/emergency_settings.xml
index 28ae8b1..80d6ac0 100644
--- a/res/xml/emergency_settings.xml
+++ b/res/xml/emergency_settings.xml
@@ -32,6 +32,13 @@
         android:order="100"
         android:fragment="com.android.settings.emergency.EmergencyGestureSettings"
         settings:controller="com.android.settings.emergency.EmergencyGestureEntrypointPreferenceController" />
+    <com.android.settingslib.widget.LayoutPreference
+        android:key="more_settings"
+        android:layout="@layout/more_settings_button"
+        android:order="180"
+        android:selectable="false"
+        settings:allowDividerBelow="true"
+        settings:controller="com.android.settings.emergency.MoreSettingsPreferenceController" />
     <com.android.settingslib.RestrictedPreference
         android:key="app_and_notif_cell_broadcast_settings"
         android:title="@string/cell_broadcast_settings"
diff --git a/res/xml/installed_app_launch_settings.xml b/res/xml/installed_app_launch_settings.xml
index b777949..d631e56 100644
--- a/res/xml/installed_app_launch_settings.xml
+++ b/res/xml/installed_app_launch_settings.xml
@@ -16,31 +16,59 @@
 
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:title="@string/launch_by_default">
 
-    <PreferenceCategory android:key="app_launch_domain_links"
-                        android:title="@string/app_launch_domain_links_title">
+    <com.android.settingslib.widget.MainSwitchPreference
+        android:key="open_by_default_supported_links"
+        android:title="@string/app_launch_open_domain_urls_title"/>
 
-        <Preference
-            android:key="app_link_state"
-            android:summary="@string/summary_placeholder"
-            android:title="@string/app_launch_open_domain_urls_title"/>
+    <com.android.settingslib.widget.TopIntroPreference
+        android:key="open_by_default_top_intro"
+        android:title="@string/app_launch_top_intro_message"/>
 
-        <com.android.settings.applications.AppDomainsPreference
-            android:key="app_launch_supported_domain_urls"
-            android:title="@string/app_launch_supported_domain_urls_title"
-            android:dependency="app_link_state"
-        />
+    <PreferenceCategory
+        android:layout="@layout/preference_category_no_label"
+        android:key="open_by_default_main_category"
+        settings:searchable="false">
+
+        <PreferenceCategory
+            android:title="@string/app_launch_links_category">
+
+            <com.android.settings.applications.intentpicker.VerifiedLinksPreference
+                android:key="open_by_default_verified_links"
+                android:title="@string/summary_placeholder"
+                android:order="-100"
+                settings:searchable="false"/>
+
+            <PreferenceCategory
+                android:layout="@layout/preference_category_no_label"
+                android:key="open_by_default_selected_links_category"
+                android:order="100"
+                settings:searchable="false"/>
+
+            <Preference
+                android:key="open_by_default_add_link"
+                android:title="@string/app_launch_add_link"
+                android:order="300"
+                android:icon="@drawable/ic_add_24dp"/>
+
+        </PreferenceCategory>
+
+        <PreferenceCategory android:key="app_launch_other_defaults"
+                            android:title="@string/app_launch_other_defaults_title">
+
+            <com.android.settings.applications.ClearDefaultsPreference
+                android:key="app_launch_clear_defaults"
+                android:selectable="false"/>
+
+        </PreferenceCategory>
+
+        <com.android.settingslib.widget.FooterPreference
+            android:key="open_by_default_footer"
+            android:selectable="false"
+            settings:allowDividerAbove="true"
+            settings:searchable="false"/>
 
     </PreferenceCategory>
-
-    <PreferenceCategory android:key="app_launch_other_defaults"
-                        android:title="@string/app_launch_other_defaults_title">
-
-        <com.android.settings.applications.ClearDefaultsPreference
-            android:key="app_launch_clear_defaults"
-            android:selectable="false"/>
-
-    </PreferenceCategory>
-
 </PreferenceScreen>
diff --git a/res/xml/language_and_input.xml b/res/xml/language_and_input.xml
index 50968d9..d7b8364 100644
--- a/res/xml/language_and_input.xml
+++ b/res/xml/language_and_input.xml
@@ -54,12 +54,6 @@
             android:persistent="false"
             android:fragment="com.android.settings.inputmethod.SpellCheckersSettings" />
 
-        <Preference
-            android:key="default_autofill"
-            android:title="@string/autofill_app"
-            android:fragment="com.android.settings.applications.defaultapps.AutofillPicker"
-            settings:keywords="@string/autofill_keywords" />
-
         <!-- User dictionary preference title and fragment will be set programmatically. -->
         <Preference
             android:key="key_user_dictionary_settings"
diff --git a/res/xml/location_settings.xml b/res/xml/location_settings.xml
index 93f30e5..3b87ae4 100644
--- a/res/xml/location_settings.xml
+++ b/res/xml/location_settings.xml
@@ -76,9 +76,8 @@
 
     </PreferenceCategory>
 
-    <PreferenceCategory
+    <com.android.settingslib.widget.FooterPreference
+        android:title="@string/location_settings_footer"
         android:key="location_footer"
-        android:layout="@layout/preference_category_no_label"
-        settings:allowDividerAbove="false"
-        settings:controller="com.android.settings.location.LocationFooterPreferenceController"/>
+        android:selectable="false"/>
 </PreferenceScreen>
diff --git a/res/xml/location_settings_personal.xml b/res/xml/location_settings_personal.xml
index 0e971d6..0307a85 100644
--- a/res/xml/location_settings_personal.xml
+++ b/res/xml/location_settings_personal.xml
@@ -53,9 +53,8 @@
         android:fragment="com.android.settings.location.LocationServices"
         settings:controller="com.android.settings.location.LocationServicesPreferenceController"/>
 
-    <PreferenceCategory
+    <com.android.settingslib.widget.FooterPreference
+        android:title="@string/location_settings_footer"
         android:key="location_footer"
-        android:layout="@layout/preference_category_no_label"
-        settings:allowDividerAbove="false"
-        settings:controller="com.android.settings.location.LocationFooterPreferenceController"/>
+        android:selectable="false"/>
 </PreferenceScreen>
diff --git a/res/xml/location_settings_workprofile.xml b/res/xml/location_settings_workprofile.xml
index c3efcbe..5ec3e1b 100644
--- a/res/xml/location_settings_workprofile.xml
+++ b/res/xml/location_settings_workprofile.xml
@@ -61,9 +61,8 @@
         android:fragment="com.android.settings.location.LocationServicesForWork"
         settings:controller="com.android.settings.location.LocationServicesForWorkPreferenceController"/>
 
-    <PreferenceCategory
+    <com.android.settingslib.widget.FooterPreference
+        android:title="@string/location_settings_footer"
         android:key="location_footer"
-        android:layout="@layout/preference_category_no_label"
-        settings:allowDividerAbove="false"
-        settings:controller="com.android.settings.location.LocationFooterPreferenceController"/>
+        android:selectable="false"/>
 </PreferenceScreen>
diff --git a/res/xml/network_provider_internet.xml b/res/xml/network_provider_internet.xml
index bb7117d..4c760aa 100644
--- a/res/xml/network_provider_internet.xml
+++ b/res/xml/network_provider_internet.xml
@@ -98,7 +98,7 @@
         android:order="10"
         android:fragment="com.android.settings.datausage.DataSaverSummary"/>
 
-    <com.android.settingslib.RestrictedPreference
+    <com.android.settings.vpn2.VpnInfoPreference
         android:fragment="com.android.settings.vpn2.VpnSettings"
         android:key="vpn_settings"
         android:title="@string/vpn_settings_title"
diff --git a/res/xml/power_menu_settings.xml b/res/xml/power_menu_settings.xml
index c7fba71..bfe9c20 100644
--- a/res/xml/power_menu_settings.xml
+++ b/res/xml/power_menu_settings.xml
@@ -20,6 +20,13 @@
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:title="@string/power_menu_setting_name">
 
+    <SwitchPreference
+        android:key="gesture_power_menu_long_press_for_assist"
+        android:title="@string/power_menu_long_press_for_assist"
+        android:summary="@string/power_menu_long_press_for_assist_summary"
+        settings:controller="com.android.settings.gestures.LongPressPowerButtonPreferenceController"
+        />
+
     <Preference
         android:key="gesture_global_actions_panel_summary"
         android:title="@string/cards_passes_sentence"
diff --git a/res/xml/smart_battery_detail.xml b/res/xml/smart_battery_detail.xml
index 2d36119..c2b3d1f 100644
--- a/res/xml/smart_battery_detail.xml
+++ b/res/xml/smart_battery_detail.xml
@@ -22,11 +22,6 @@
     android:title="@string/smart_battery_manager_title"
     settings:searchable="false">
 
-    <com.android.settingslib.widget.MainSwitchPreference
-        android:key="smart_battery"
-        android:title="@string/adaptive_battery_main_switch_title"
-        settings:controller="com.android.settings.fuelgauge.SmartBatteryPreferenceController"/>
-
     <com.android.settings.widget.VideoPreference
         android:key="auto_awesome_battery"
         android:title="@string/summary_placeholder"
@@ -35,6 +30,13 @@
         settings:controller="com.android.settings.widget.VideoPreferenceController"/>
 
     <SwitchPreference
+        android:key="smart_battery"
+        android:title="@string/smart_battery_title"
+        android:summary="@string/smart_battery_summary"
+        settings:controller="com.android.settings.fuelgauge.SmartBatteryPreferenceController"
+        settings:allowDividerAbove="true"/>
+
+    <SwitchPreference
         android:key="auto_restriction"
         android:title="@string/battery_auto_restriction_title"
         android:summary="@string/battery_auto_restriction_summary"
diff --git a/res/xml/storage_dashboard_fragment.xml b/res/xml/storage_dashboard_fragment.xml
index b49228e..9bca65a 100644
--- a/res/xml/storage_dashboard_fragment.xml
+++ b/res/xml/storage_dashboard_fragment.xml
@@ -21,68 +21,79 @@
     android:orderingFromXml="false">
     <com.android.settingslib.widget.SettingsSpinnerPreference
         android:key="storage_spinner"
-        android:order="-2"
+        android:order="1"
         settings:searchable="false"
         settings:controller="com.android.settings.deviceinfo.storage.StorageSelectionPreferenceController"/>
     <com.android.settingslib.widget.UsageProgressBarPreference
         android:key="storage_summary"
-        android:order="-1"
+        android:order="2"
         settings:searchable="false"
-        settings:controller="com.android.settings.deviceinfo.storage.StorageUsageProgressBarPreferenceController"/>
-    <Preference
-        android:key="free_up_space"
-        android:order="0"
-        android:title="@string/storage_free_up_space_title"
-        android:summary="@string/storage_free_up_space_summary"
-        settings:allowDividerAbove="true"/>
+        settings:controller="com.android.settings.deviceinfo.storage.StorageUsageProgressBarPreferenceController"
+        settings:allowDividerBelow="true"/>
     <com.android.settings.widget.PrimarySwitchPreference
         android:fragment="com.android.settings.deletionhelper.AutomaticStorageManagerSettings"
         android:key="toggle_asm"
         android:title="@string/automatic_storage_manager_preference_title"
         android:icon="@drawable/ic_storage"
-        android:order="1"
+        android:order="3"
         settings:allowDividerAbove="true"
-        settings:allowDividerBelow="true"
-        settings:controller="com.android.settings.deviceinfo.storage.AutomaticStorageManagementSwitchPreferenceController" />
+        settings:controller="com.android.settings.deviceinfo.storage.AutomaticStorageManagementSwitchPreferenceController"/>
+    <Preference
+        android:key="free_up_space"
+        android:order="4"
+        android:title="@string/storage_free_up_space_title"
+        android:summary="@string/storage_free_up_space_summary"
+        settings:allowDividerAbove="true"
+        android:icon="@drawable/ic_files_go_round"/>
+    <!-- Preference order 100~200 are 'ONLY' for storage category preferences below. -->
+    <Preference
+        android:key="pref_public_storage"
+        android:title="@string/storage_files"
+        android:icon="@drawable/ic_folder_vd_theme_24"
+        android:order="100"/>
     <com.android.settings.deviceinfo.StorageItemPreference
-        android:key="pref_photos_videos"
-        android:title="@string/storage_photos_videos"
+        android:key="pref_images"
+        android:title="@string/storage_images"
         android:icon="@drawable/ic_photo_library"
-        settings:allowDividerAbove="true"
-        android:order="2" />
+        android:order="101"/>
     <com.android.settings.deviceinfo.StorageItemPreference
-        android:key="pref_music_audio"
-        android:title="@string/storage_music_audio"
+        android:key="pref_videos"
+        android:title="@string/storage_videos"
+        android:icon="@drawable/ic_local_movies"
+        android:order="102"/>
+    <com.android.settings.deviceinfo.StorageItemPreference
+        android:key="pref_audios"
+        android:title="@string/storage_audios"
         android:icon="@drawable/ic_media_stream"
-        android:order="3" />
+        android:order="103"/>
+    <com.android.settings.deviceinfo.StorageItemPreference
+        android:key="pref_apps"
+        android:title="@string/storage_apps"
+        android:icon="@drawable/ic_storage_apps"
+        android:order="104"/>
     <com.android.settings.deviceinfo.StorageItemPreference
         android:key="pref_games"
         android:title="@string/storage_games"
         android:icon="@drawable/ic_videogame_vd_theme_24"
-        android:order="4" />
+        android:order="105"/>
     <com.android.settings.deviceinfo.StorageItemPreference
-        android:key="pref_movies"
-        android:title="@string/storage_movies_tv"
-        android:icon="@drawable/ic_local_movies"
-        android:order="5" />
-    <com.android.settings.deviceinfo.StorageItemPreference
-        android:key="pref_other_apps"
-        android:title="@string/storage_other_apps"
-        android:icon="@drawable/ic_storage_apps"
-        android:order="6" />
-    <com.android.settings.deviceinfo.StorageItemPreference
-        android:key="pref_files"
-        android:title="@string/storage_files"
+        android:key="pref_documents_and_other"
+        android:title="@string/storage_documents_and_other"
         android:icon="@drawable/ic_folder_vd_theme_24"
-        android:order="7"
-        settings:keywords="@string/keywords_storage_files"/>
+        android:order="106"/>
     <com.android.settings.deviceinfo.StorageItemPreference
         android:key="pref_system"
-        android:title="@string/storage_detail_system"
+        android:title="@string/storage_system"
         android:icon="@drawable/ic_system_update"
-        android:order="100" />
+        android:order="107"/>
+    <com.android.settings.deviceinfo.StorageItemPreference
+        android:key="pref_trash"
+        android:title="@string/storage_trash"
+        android:icon="@drawable/ic_trash_can"
+        android:order="108"/>
+    <!-- Preference order 100~200 are 'ONLY' for storage category preferences above. -->
     <PreferenceCategory
         android:key="pref_secondary_users"
         android:title="@string/storage_other_users"
-        android:order="200" />
+        android:order="201" />
 </PreferenceScreen>
diff --git a/res/xml/swipe_bottom_to_notification_settings.xml b/res/xml/swipe_bottom_to_notification_settings.xml
index bec774b..2a75c14 100644
--- a/res/xml/swipe_bottom_to_notification_settings.xml
+++ b/res/xml/swipe_bottom_to_notification_settings.xml
@@ -20,11 +20,13 @@
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:title="@string/swipe_bottom_to_notifications_title">
 
-    <com.android.settings.widget.VideoPreference
-        android:title="@string/swipe_bottom_to_notifications_title"
-        settings:animation="@raw/gesture_fingerprint_swipe"
-        settings:preview="@drawable/gesture_fingerprint_swipe"
-        settings:controller="com.android.settings.widget.VideoPreferenceController"/>
+    <com.android.settingslib.widget.LayoutPreference
+        android:key="one_handed_header"
+        android:layout="@layout/one_handed_header"
+        android:persistent="false"
+        android:selectable="false"
+        settings:allowDividerBelow="false"
+        settings:searchable="false"/>
 
     <SwitchPreference
         android:key="gesture_swipe_bottom_to_notification"
diff --git a/res/xml/tether_prefs.xml b/res/xml/tether_prefs.xml
index 37194d9..d86f420 100644
--- a/res/xml/tether_prefs.xml
+++ b/res/xml/tether_prefs.xml
@@ -49,9 +49,9 @@
         android:summary="@string/ethernet_tethering_subtext"
         settings:keywords="@string/keywords_hotspot_tethering" />
 
-    <Preference
+    <com.android.settingslib.widget.FooterPreference
         android:key="disabled_on_data_saver"
-        android:summary="@string/tether_settings_disabled_on_data_saver"
+        android:title="@string/tether_settings_disabled_on_data_saver"
         android:selectable="false"
-        settings:allowDividerAbove="true" />
+        settings:searchable="false"/>
 </PreferenceScreen>
diff --git a/res/xml/top_level_settings.xml b/res/xml/top_level_settings.xml
index 78dfe9b..725390e 100644
--- a/res/xml/top_level_settings.xml
+++ b/res/xml/top_level_settings.xml
@@ -78,7 +78,7 @@
         android:summary="@string/summary_placeholder"
         android:icon="@drawable/ic_homepage_storage"
         android:order="-60"
-        android:fragment="com.android.settings.deviceinfo.StorageSettings"
+        android:fragment="com.android.settings.deviceinfo.StorageDashboardFragment"
         settings:controller="com.android.settings.deviceinfo.TopLevelStoragePreferenceController"/>
 
     <Preference
diff --git a/res/xml/top_level_settings_grouped.xml b/res/xml/top_level_settings_grouped.xml
index 704a106..df935d0 100644
--- a/res/xml/top_level_settings_grouped.xml
+++ b/res/xml/top_level_settings_grouped.xml
@@ -59,7 +59,7 @@
         settings:controller="com.android.settings.fuelgauge.TopLevelBatteryPreferenceController"/>
 
     <com.android.settings.homepage.HomepagePreference
-        android:fragment="com.android.settings.deviceinfo.StorageSettings"
+        android:fragment="com.android.settings.deviceinfo.StorageDashboardFragment"
         android:icon="@drawable/ic_homepage_storage_v2"
         android:key="top_level_storage"
         android:order="-100"
diff --git a/res/xml/wifi_network_details_fragment2.xml b/res/xml/wifi_network_details_fragment2.xml
index 181b799..cb24a8f 100644
--- a/res/xml/wifi_network_details_fragment2.xml
+++ b/res/xml/wifi_network_details_fragment2.xml
@@ -101,6 +101,11 @@
             android:key="ip_details_category"
             android:title="@string/wifi_setup_detail">
         <Preference
+                android:key="type"
+                android:title="@string/wifi_type_title"
+                android:selectable="false"
+                settings:enableCopying="true"/>
+        <Preference
                 android:key="ssid"
                 android:title="@string/wifi_advanced_ssid_title"
                 android:selectable="false"
diff --git a/src/com/android/settings/accessibility/ReduceBrightColorsPreferenceController.java b/src/com/android/settings/accessibility/ReduceBrightColorsPreferenceController.java
index 82b3a64..bfe61b7 100644
--- a/src/com/android/settings/accessibility/ReduceBrightColorsPreferenceController.java
+++ b/src/com/android/settings/accessibility/ReduceBrightColorsPreferenceController.java
@@ -18,8 +18,8 @@
 
 import android.content.Context;
 import android.hardware.display.ColorDisplayManager;
-import android.provider.Settings;
 
+import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
 
 /** PreferenceController that shows the Reduce Bright Colors summary */
@@ -32,8 +32,8 @@
 
     @Override
     public CharSequence getSummary() {
-        return AccessibilityUtil.getSummary(mContext,
-                Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED);
+        return mContext.getText(
+                R.string.reduce_bright_colors_preference_summary);
     }
 
     @Override
diff --git a/src/com/android/settings/accessibility/ShortcutPreference.java b/src/com/android/settings/accessibility/ShortcutPreference.java
index a9b542a..cff9117 100644
--- a/src/com/android/settings/accessibility/ShortcutPreference.java
+++ b/src/com/android/settings/accessibility/ShortcutPreference.java
@@ -63,7 +63,7 @@
         super(context, attrs);
         setLayoutResource(R.layout.accessibility_shortcut_secondary_action);
         setWidgetLayoutResource(R.layout.preference_widget_primary_switch);
-        setIconSpaceReserved(true);
+        setIconSpaceReserved(false);
     }
 
     @Override
diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
index cf9c08b..be6b141 100644
--- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
@@ -488,7 +488,7 @@
         // Show the "Settings" menu as if it were a preference screen.
         mSettingsPreference = new Preference(getPrefContext());
         mSettingsPreference.setTitle(mSettingsTitle);
-        mSettingsPreference.setIconSpaceReserved(true);
+        mSettingsPreference.setIconSpaceReserved(false);
         mSettingsPreference.setIntent(mSettingsIntent);
 
         final PreferenceCategory generalCategory = findPreference(KEY_GENERAL_CATEGORY);
diff --git a/src/com/android/settings/accessibility/TurnScreenDarkerFragment.java b/src/com/android/settings/accessibility/TurnScreenDarkerFragment.java
index ad4bd56..0e0a600 100644
--- a/src/com/android/settings/accessibility/TurnScreenDarkerFragment.java
+++ b/src/com/android/settings/accessibility/TurnScreenDarkerFragment.java
@@ -94,8 +94,6 @@
         if (ColorDisplayManager.isColorTransformAccelerated(getContext())) {
             mToggleInversionPreference.setSummary(AccessibilityUtil.getSummary(
                     getContext(), Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED));
-            mReduceBrightColorsPreference.setSummary(AccessibilityUtil.getSummary(
-                    getContext(), Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED));
             getPreferenceScreen().removePreference(experimentalCategory);
         } else {
             // Move following preferences to experimental category if device don't supports HWC
diff --git a/src/com/android/settings/accounts/AccountDashboardFragment.java b/src/com/android/settings/accounts/AccountDashboardFragment.java
index 7b50b46..9e232f4 100644
--- a/src/com/android/settings/accounts/AccountDashboardFragment.java
+++ b/src/com/android/settings/accounts/AccountDashboardFragment.java
@@ -27,6 +27,8 @@
 
 import com.android.settings.R;
 import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.applications.defaultapps.DefaultAutofillPreferenceController;
+import com.android.settings.applications.defaultapps.DefaultWorkAutofillPreferenceController;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
@@ -68,14 +70,22 @@
 
     @Override
     protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+        final List<AbstractPreferenceController> controllers = new ArrayList<>();
+        buildAutofillPreferenceControllers(context, controllers);
         final String[] authorities = getIntent().getStringArrayExtra(EXTRA_AUTHORITIES);
-        return buildPreferenceControllers(context, this /* parent */, authorities);
+        buildAccountPreferenceControllers(context, this /* parent */, authorities, controllers);
+        return controllers;
     }
 
-    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
-            SettingsPreferenceFragment parent, String[] authorities) {
-        final List<AbstractPreferenceController> controllers = new ArrayList<>();
+    static void buildAutofillPreferenceControllers(
+            Context context, List<AbstractPreferenceController> controllers) {
+        controllers.add(new DefaultAutofillPreferenceController(context));
+        controllers.add(new DefaultWorkAutofillPreferenceController(context));
+    }
 
+    private static void buildAccountPreferenceControllers(
+            Context context, SettingsPreferenceFragment parent, String[] authorities,
+            List<AbstractPreferenceController> controllers) {
         final AccountPreferenceController accountPrefController =
                 new AccountPreferenceController(context, parent, authorities,
                         ProfileSelectFragment.ProfileType.ALL);
@@ -86,7 +96,6 @@
         controllers.add(new AutoSyncDataPreferenceController(context, parent));
         controllers.add(new AutoSyncPersonalDataPreferenceController(context, parent));
         controllers.add(new AutoSyncWorkDataPreferenceController(context, parent));
-        return controllers;
     }
 
     public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
@@ -95,8 +104,11 @@
                 @Override
                 public List<AbstractPreferenceController> createPreferenceControllers(
                         Context context) {
-                    return buildPreferenceControllers(
-                            context, null /* parent */, null /* authorities*/);
+                    final List<AbstractPreferenceController> controllers = new ArrayList<>();
+                    buildAccountPreferenceControllers(
+                            context, null /* parent */, null /* authorities*/, controllers);
+                    buildAutofillPreferenceControllers(context, controllers);
+                    return controllers;
                 }
 
                 @Override
diff --git a/src/com/android/settings/accounts/AccountPersonalDashboardFragment.java b/src/com/android/settings/accounts/AccountPersonalDashboardFragment.java
index f29326e..c97c886 100644
--- a/src/com/android/settings/accounts/AccountPersonalDashboardFragment.java
+++ b/src/com/android/settings/accounts/AccountPersonalDashboardFragment.java
@@ -18,6 +18,8 @@
 
 import static android.provider.Settings.EXTRA_AUTHORITIES;
 
+import static com.android.settings.accounts.AccountDashboardFragment.buildAutofillPreferenceControllers;
+
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 
@@ -61,14 +63,16 @@
 
     @Override
     protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+        final List<AbstractPreferenceController> controllers = new ArrayList<>();
+        buildAutofillPreferenceControllers(context, controllers);
         final String[] authorities = getIntent().getStringArrayExtra(EXTRA_AUTHORITIES);
-        return buildPreferenceControllers(context, this /* parent */, authorities);
+        buildAccountPreferenceControllers(context, this /* parent */, authorities, controllers);
+        return controllers;
     }
 
-    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
-            SettingsPreferenceFragment parent, String[] authorities) {
-        final List<AbstractPreferenceController> controllers = new ArrayList<>();
-
+    private static void buildAccountPreferenceControllers(
+            Context context, SettingsPreferenceFragment parent, String[] authorities,
+            List<AbstractPreferenceController> controllers) {
         final AccountPreferenceController accountPrefController =
                 new AccountPreferenceController(context, parent, authorities,
                         ProfileSelectFragment.ProfileType.PERSONAL);
@@ -78,7 +82,6 @@
         controllers.add(accountPrefController);
         controllers.add(new AutoSyncDataPreferenceController(context, parent));
         controllers.add(new AutoSyncPersonalDataPreferenceController(context, parent));
-        return controllers;
     }
 
     // TODO: b/141601408. After featureFlag settings_work_profile is launched, unmark this
@@ -88,6 +91,7 @@
 //                @Override
 //                public List<AbstractPreferenceController> createPreferenceControllers(
 //                        Context context) {
+//                    ..Add autofill here too..
 //                    return buildPreferenceControllers(
 //                            context, null /* parent */, null /* authorities*/);
 //                }
diff --git a/src/com/android/settings/accounts/AccountPreferenceController.java b/src/com/android/settings/accounts/AccountPreferenceController.java
index ff5bc78..64c2d13 100644
--- a/src/com/android/settings/accounts/AccountPreferenceController.java
+++ b/src/com/android/settings/accounts/AccountPreferenceController.java
@@ -75,11 +75,12 @@
 
     private static final String TAG = "AccountPrefController";
 
-    private static final int ORDER_ACCOUNT_PROFILES = 1;
+    private static final int ORDER_ACCOUNT_PROFILES = 101;
     private static final int ORDER_LAST = 1002;
     private static final int ORDER_NEXT_TO_LAST = 1001;
     private static final int ORDER_NEXT_TO_NEXT_TO_LAST = 1000;
 
+    private static final String PREF_KEY_ACCOUNTS = "accounts_category";
     private static final String PREF_KEY_ADD_ACCOUNT = "add_account";
     private static final String PREF_KEY_REMOVE_PROFILE = "remove_profile";
     private static final String PREF_KEY_WORK_PROFILE_SETTING = "work_profile_setting";
@@ -348,8 +349,10 @@
             }
         }
         final PreferenceScreen screen = mFragment.getPreferenceScreen();
-        if (screen != null) {
-            screen.addPreference(preferenceGroup);
+        final PreferenceGroup accounts =
+                screen == null ? null : screen.findPreference(PREF_KEY_ACCOUNTS);
+        if (accounts != null) {
+            accounts.addPreference(preferenceGroup);
         }
         profileData.preferenceGroup = preferenceGroup;
         if (userInfo.isEnabled()) {
diff --git a/src/com/android/settings/accounts/AccountWorkProfileDashboardFragment.java b/src/com/android/settings/accounts/AccountWorkProfileDashboardFragment.java
index 853c66b..4e6515b 100644
--- a/src/com/android/settings/accounts/AccountWorkProfileDashboardFragment.java
+++ b/src/com/android/settings/accounts/AccountWorkProfileDashboardFragment.java
@@ -18,6 +18,8 @@
 
 import static android.provider.Settings.EXTRA_AUTHORITIES;
 
+import static com.android.settings.accounts.AccountDashboardFragment.buildAutofillPreferenceControllers;
+
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 
@@ -61,14 +63,16 @@
 
     @Override
     protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+        final List<AbstractPreferenceController> controllers = new ArrayList<>();
+        buildAutofillPreferenceControllers(context, controllers);
         final String[] authorities = getIntent().getStringArrayExtra(EXTRA_AUTHORITIES);
-        return buildPreferenceControllers(context, this /* parent */, authorities);
+        buildAccountPreferenceControllers(context, this /* parent */, authorities, controllers);
+        return controllers;
     }
 
-    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
-            SettingsPreferenceFragment parent, String[] authorities) {
-        final List<AbstractPreferenceController> controllers = new ArrayList<>();
-
+    private static void buildAccountPreferenceControllers(
+            Context context, SettingsPreferenceFragment parent, String[] authorities,
+            List<AbstractPreferenceController> controllers) {
         final AccountPreferenceController accountPrefController =
                 new AccountPreferenceController(context, parent, authorities,
                         ProfileSelectFragment.ProfileType.WORK);
@@ -78,7 +82,6 @@
         controllers.add(accountPrefController);
         controllers.add(new AutoSyncDataPreferenceController(context, parent));
         controllers.add(new AutoSyncWorkDataPreferenceController(context, parent));
-        return controllers;
     }
 
     // TODO: b/141601408. After featureFlag settings_work_profile is launched, unmark this
@@ -88,6 +91,7 @@
 //                @Override
 //                public List<AbstractPreferenceController> createPreferenceControllers(
 //                        Context context) {
+//                    ..Add autofill here too..
 //                    return buildPreferenceControllers(
 //                            context, null /* parent */, null /* authorities*/);
 //                }
diff --git a/src/com/android/settings/accounts/AvatarViewMixin.java b/src/com/android/settings/accounts/AvatarViewMixin.java
index 7eb8cab..c4ab55a 100644
--- a/src/com/android/settings/accounts/AvatarViewMixin.java
+++ b/src/com/android/settings/accounts/AvatarViewMixin.java
@@ -17,7 +17,6 @@
 package com.android.settings.accounts;
 
 import android.accounts.Account;
-import android.app.ActivityManager;
 import android.app.settings.SettingsEnums;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -65,14 +64,23 @@
     private final Context mContext;
     private final ImageView mAvatarView;
     private final MutableLiveData<Bitmap> mAvatarImage;
-    private final ActivityManager mActivityManager;
 
     @VisibleForTesting
     String mAccountName;
 
+    /**
+     * @return true if the avatar icon is supported.
+     */
+    public static boolean isAvatarSupported(Context context) {
+        if (!context.getResources().getBoolean(R.bool.config_show_avatar_in_homepage)) {
+            Log.d(TAG, "Feature disabled by config. Skipping");
+            return false;
+        }
+        return true;
+    }
+
     public AvatarViewMixin(SettingsHomepageActivity activity, ImageView avatarView) {
         mContext = activity.getApplicationContext();
-        mActivityManager = mContext.getSystemService(ActivityManager.class);
         mAvatarView = avatarView;
         mAvatarView.setOnClickListener(v -> {
             Intent intent;
@@ -117,14 +125,6 @@
 
     @OnLifecycleEvent(Lifecycle.Event.ON_START)
     public void onStart() {
-        if (!mContext.getResources().getBoolean(R.bool.config_show_avatar_in_homepage)) {
-            Log.d(TAG, "Feature disabled by config. Skipping");
-            return;
-        }
-        if (mActivityManager.isLowRamDevice()) {
-            Log.d(TAG, "Feature disabled on low ram device. Skipping");
-            return;
-        }
         if (hasAccount()) {
             loadAccount();
         } else {
diff --git a/src/com/android/settings/accounts/TopLevelAccountEntryPreferenceController.java b/src/com/android/settings/accounts/TopLevelAccountEntryPreferenceController.java
index 7cd746f..174ef0f 100644
--- a/src/com/android/settings/accounts/TopLevelAccountEntryPreferenceController.java
+++ b/src/com/android/settings/accounts/TopLevelAccountEntryPreferenceController.java
@@ -17,19 +17,11 @@
 package com.android.settings.accounts;
 
 import android.content.Context;
-import android.icu.text.ListFormatter;
-import android.os.UserHandle;
-import android.text.BidiFormatter;
-import android.text.TextUtils;
 import android.util.FeatureFlagUtils;
 
 import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.core.FeatureFlags;
-import com.android.settingslib.accounts.AuthenticatorHelper;
-
-import java.util.ArrayList;
-import java.util.List;
 
 public class TopLevelAccountEntryPreferenceController extends BasePreferenceController {
     public TopLevelAccountEntryPreferenceController(Context context, String preferenceKey) {
@@ -47,29 +39,6 @@
         if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.SILKY_HOME)) {
             return null;
         }
-
-        final AuthenticatorHelper authHelper = new AuthenticatorHelper(mContext,
-                UserHandle.of(UserHandle.myUserId()), null /* OnAccountsUpdateListener */);
-        final String[] types = authHelper.getEnabledAccountTypes();
-        final BidiFormatter bidiFormatter = BidiFormatter.getInstance();
-        final List<CharSequence> summaries = new ArrayList<>();
-
-        if (types == null || types.length == 0) {
-            summaries.add(mContext.getString(R.string.account_dashboard_default_summary));
-        } else {
-            // Show up to 3 account types, ignore any null value
-            int accountToAdd = Math.min(3, types.length);
-
-            for (int i = 0; i < types.length && accountToAdd > 0; i++) {
-                final CharSequence label = authHelper.getLabelForType(mContext, types[i]);
-                if (TextUtils.isEmpty(label)) {
-                    continue;
-                }
-
-                summaries.add(bidiFormatter.unicodeWrap(label));
-                accountToAdd--;
-            }
-        }
-        return ListFormatter.getInstance().format(summaries);
+        return mContext.getString(R.string.account_dashboard_default_summary);
     }
 }
diff --git a/src/com/android/settings/applications/AppLaunchSettings.java b/src/com/android/settings/applications/AppLaunchSettings.java
deleted file mode 100644
index 86bc7ed..0000000
--- a/src/com/android/settings/applications/AppLaunchSettings.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2015 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.applications;
-
-import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
-import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
-
-import android.app.settings.SettingsEnums;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.util.ArraySet;
-import android.view.View;
-import android.view.View.OnClickListener;
-
-import androidx.appcompat.app.AlertDialog;
-import androidx.preference.Preference;
-
-import com.android.settings.R;
-import com.android.settings.Utils;
-import com.android.settings.core.SubSettingLauncher;
-import com.android.settingslib.applications.AppUtils;
-
-public class AppLaunchSettings extends AppInfoWithHeader implements OnClickListener,
-        Preference.OnPreferenceChangeListener {
-    private static final String TAG = "AppLaunchSettings";
-    private static final String KEY_APP_LINK_STATE = "app_link_state";
-    private static final String KEY_SUPPORTED_DOMAIN_URLS = "app_launch_supported_domain_urls";
-    private static final String KEY_CLEAR_DEFAULTS = "app_launch_clear_defaults";
-    private static final String FRAGMENT_OPEN_SUPPORTED_LINKS =
-            "com.android.settings.applications.OpenSupportedLinks";
-
-    private PackageManager mPm;
-
-    private boolean mIsBrowser;
-    private boolean mHasDomainUrls;
-    private Preference mAppLinkState;
-    private AppDomainsPreference mAppDomainUrls;
-    private ClearDefaultsPreference mClearDefaultsPreference;
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        addPreferencesFromResource(R.xml.installed_app_launch_settings);
-        mAppDomainUrls = (AppDomainsPreference) findPreference(KEY_SUPPORTED_DOMAIN_URLS);
-        mClearDefaultsPreference = (ClearDefaultsPreference) findPreference(KEY_CLEAR_DEFAULTS);
-        mAppLinkState = findPreference(KEY_APP_LINK_STATE);
-        mAppLinkState.setOnPreferenceClickListener(preference -> {
-            final Bundle args = new Bundle();
-            args.putString(ARG_PACKAGE_NAME, mPackageName);
-            args.putInt(ARG_PACKAGE_UID, mUserId);
-
-            new SubSettingLauncher(this.getContext())
-                    .setDestination(FRAGMENT_OPEN_SUPPORTED_LINKS)
-                    .setArguments(args)
-                    .setSourceMetricsCategory(SettingsEnums.APPLICATIONS_APP_LAUNCH)
-                    .setTitleRes(-1)
-                    .launch();
-            return true;
-        });
-
-        mPm = getActivity().getPackageManager();
-
-        mIsBrowser = AppUtils.isBrowserApp(this.getContext(), mPackageName, UserHandle.myUserId());
-        mHasDomainUrls =
-                (mAppEntry.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
-
-        if (!mIsBrowser) {
-            CharSequence[] entries = getEntries(mPackageName);
-            mAppDomainUrls.setTitles(entries);
-            mAppDomainUrls.setValues(new int[entries.length]);
-            mAppLinkState.setEnabled(mHasDomainUrls);
-        } else {
-            // Browsers don't show the app-link prefs
-            mAppLinkState.setShouldDisableView(true);
-            mAppLinkState.setEnabled(false);
-            mAppDomainUrls.setShouldDisableView(true);
-            mAppDomainUrls.setEnabled(false);
-        }
-    }
-
-    private int linkStateToResourceId(int state) {
-        switch (state) {
-            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS:
-                return R.string.app_link_open_always; // Always
-            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER:
-                return R.string.app_link_open_never; // Never
-            default:
-                return R.string.app_link_open_ask; // Ask
-        }
-    }
-
-    private CharSequence[] getEntries(String packageName) {
-        ArraySet<String> result = Utils.getHandledDomains(mPm, packageName);
-        return result.toArray(new CharSequence[result.size()]);
-    }
-
-    private void setAppLinkStateSummary() {
-        final int state = mPm.getIntentVerificationStatusAsUser(mPackageName,
-                UserHandle.myUserId());
-        mAppLinkState.setSummary(linkStateToResourceId(state));
-    }
-
-    @Override
-    protected boolean refreshUi() {
-        if (mHasDomainUrls) {
-            //Update the summary after return from the OpenSupportedLinks
-            setAppLinkStateSummary();
-        }
-        mClearDefaultsPreference.setPackageName(mPackageName);
-        mClearDefaultsPreference.setAppEntry(mAppEntry);
-        return true;
-    }
-
-    @Override
-    protected AlertDialog createDialog(int id, int errorCode) {
-        // No dialogs for preferred launch settings.
-        return null;
-    }
-
-    @Override
-    public void onClick(View v) {
-        // Nothing to do
-    }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        // actual updates are handled by the app link dropdown callback
-        return true;
-    }
-
-    @Override
-    public int getMetricsCategory() {
-        return SettingsEnums.APPLICATIONS_APP_LAUNCH;
-    }
-}
diff --git a/src/com/android/settings/applications/ClearDefaultsPreference.java b/src/com/android/settings/applications/ClearDefaultsPreference.java
index f946636..0952b9c 100644
--- a/src/com/android/settings/applications/ClearDefaultsPreference.java
+++ b/src/com/android/settings/applications/ClearDefaultsPreference.java
@@ -117,7 +117,7 @@
                 if (mUsbManager != null) {
                     final int userId = UserHandle.myUserId();
                     mPm.clearPackagePreferredActivities(mPackageName);
-                    if (isDefaultBrowser(mPackageName)) {
+                    if (AppUtils.isDefaultBrowser(getContext(), mPackageName)) {
                         mPm.setDefaultBrowserPackageNameAsUser(null, userId);
                     }
                     try {
@@ -141,7 +141,7 @@
 
         TextView autoLaunchView = (TextView) view.findViewById(R.id.auto_launch);
         boolean autoLaunchEnabled = AppUtils.hasPreferredActivities(mPm, mPackageName)
-                || isDefaultBrowser(mPackageName)
+                || AppUtils.isDefaultBrowser(getContext(), mPackageName)
                 || AppUtils.hasUsbDefaults(mUsbManager, mPackageName);
         if (!autoLaunchEnabled && !hasBindAppWidgetPermission) {
             resetLaunchDefaultsUi(autoLaunchView);
@@ -185,11 +185,6 @@
         return true;
     }
 
-    private boolean isDefaultBrowser(String packageName) {
-        final String defaultBrowser = mPm.getDefaultBrowserPackageNameAsUser(UserHandle.myUserId());
-        return packageName.equals(defaultBrowser);
-    }
-
     private void resetLaunchDefaultsUi(TextView autoLaunchView) {
         autoLaunchView.setText(R.string.auto_launch_disable_text);
         // Disable clear activities button
diff --git a/src/com/android/settings/applications/HibernatedAppsPreferenceController.java b/src/com/android/settings/applications/HibernatedAppsPreferenceController.java
index 40cbb2e..4088d3a 100644
--- a/src/com/android/settings/applications/HibernatedAppsPreferenceController.java
+++ b/src/com/android/settings/applications/HibernatedAppsPreferenceController.java
@@ -20,15 +20,19 @@
 
 import static com.android.settings.Utils.PROPERTY_APP_HIBERNATION_ENABLED;
 
+import android.apphibernation.AppHibernationManager;
 import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.provider.DeviceConfig;
 
 import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
 
+import java.util.List;
+
 /**
  * A preference controller handling the logic for updating summary of hibernated apps.
- * TODO(b/181172051): add intent to launch Auto Revoke UI in app_and_notification.xml
  */
 public final class HibernatedAppsPreferenceController extends BasePreferenceController {
     private static final String TAG = "HibernatedAppsPrefController";
@@ -39,7 +43,8 @@
 
     @Override
     public int getAvailabilityStatus() {
-        return isHibernationEnabled() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
+        return isHibernationEnabled() && getNumHibernated() > 0
+                ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
     }
 
     @Override
@@ -50,8 +55,27 @@
     }
 
     private int getNumHibernated() {
-        //TODO(b/181172051): hook into hibernation service to get the number of hibernated apps.
-        return 0;
+        final PackageManager pm = mContext.getPackageManager();
+        final AppHibernationManager ahm = mContext.getSystemService(AppHibernationManager.class);
+        final List<String> hibernatedPackages = ahm.getHibernatingPackagesForUser();
+        int numHibernated = hibernatedPackages.size();
+
+        // Also need to count packages that are auto revoked but not hibernated.
+        final List<PackageInfo> packages = pm.getInstalledPackages(
+                PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.GET_PERMISSIONS);
+        for (PackageInfo pi : packages) {
+            final String packageName = pi.packageName;
+            if (!hibernatedPackages.contains(packageName) && pi.requestedPermissions != null) {
+                for (String perm : pi.requestedPermissions) {
+                    if ((pm.getPermissionFlags(perm, packageName, mContext.getUser())
+                            & PackageManager.FLAG_PERMISSION_AUTO_REVOKED) != 0) {
+                        numHibernated++;
+                        break;
+                    }
+                }
+            }
+        }
+        return numHibernated;
     }
 
     private static boolean isHibernationEnabled() {
diff --git a/src/com/android/settings/applications/InstalledAppOpenByDefaultActivity.java b/src/com/android/settings/applications/InstalledAppOpenByDefaultActivity.java
index cd30d79..799389e 100644
--- a/src/com/android/settings/applications/InstalledAppOpenByDefaultActivity.java
+++ b/src/com/android/settings/applications/InstalledAppOpenByDefaultActivity.java
@@ -19,6 +19,7 @@
 import android.content.Intent;
 
 import com.android.settings.SettingsActivity;
+import com.android.settings.applications.intentpicker.AppLaunchSettings;
 
 public class InstalledAppOpenByDefaultActivity extends SettingsActivity {
 
diff --git a/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceController.java b/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceController.java
index f9c88fc..d8c190f 100644
--- a/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceController.java
@@ -28,7 +28,7 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.applications.AppLaunchSettings;
+import com.android.settings.applications.intentpicker.AppLaunchSettings;
 import com.android.settingslib.applications.AppUtils;
 import com.android.settingslib.applications.ApplicationsState;
 
diff --git a/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceController.java b/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceController.java
index 8ab2c9d..40be629 100644
--- a/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceController.java
@@ -80,7 +80,8 @@
 
     /**
      * Set the package. And also retrieve details from package manager. Some packages may be
-     * exempted from hibernation by default.
+     * exempted from hibernation by default. This method should only be called to initialize the
+     * controller.
      * @param packageName The name of the package whose hibernation state to be managed.
      */
     void setPackage(@NonNull String packageName) {
@@ -93,8 +94,7 @@
                         ? android.os.Build.VERSION_CODES.R
                         : android.os.Build.VERSION_CODES.Q;
         try {
-            mPackageUid = packageManager.getPackageUidAsUser(
-                    packageName, mContext.getUserId());
+            mPackageUid = packageManager.getPackageUid(packageName, /* flags */ 0);
             mIsPackageExemptByDefault = packageManager.getTargetSdkVersion(packageName)
                     <= maxTargetSdkVersionForExemptApps;
             mIsPackageSet = true;
diff --git a/src/com/android/settings/applications/autofill/PasswordsPreferenceController.java b/src/com/android/settings/applications/autofill/PasswordsPreferenceController.java
index f27530e..47882de 100644
--- a/src/com/android/settings/applications/autofill/PasswordsPreferenceController.java
+++ b/src/com/android/settings/applications/autofill/PasswordsPreferenceController.java
@@ -16,37 +16,64 @@
 
 package com.android.settings.applications.autofill;
 
+import static android.service.autofill.AutofillService.EXTRA_RESULT;
+
+import static androidx.lifecycle.Lifecycle.Event.ON_CREATE;
+import static androidx.lifecycle.Lifecycle.Event.ON_DESTROY;
+
 import android.annotation.UserIdInt;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
 import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
 import android.os.UserHandle;
+import android.service.autofill.AutofillService;
 import android.service.autofill.AutofillServiceInfo;
+import android.service.autofill.IAutoFillService;
 import android.text.TextUtils;
 import android.util.IconDrawableFactory;
+import android.util.Log;
 
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.OnLifecycleEvent;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceGroup;
 import androidx.preference.PreferenceScreen;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.IResultReceiver;
+import com.android.settings.R;
 import com.android.settings.Utils;
 import com.android.settings.core.BasePreferenceController;
 
+import java.lang.ref.WeakReference;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * Queries available autofill services and adds preferences for those that declare passwords
  * settings.
+ * <p>
+ * The controller binds to each service to fetch the number of saved passwords in each.
  */
-public class PasswordsPreferenceController extends BasePreferenceController {
+public class PasswordsPreferenceController extends BasePreferenceController
+        implements LifecycleObserver {
+    private static final String TAG = "AutofillSettings";
 
     private final PackageManager mPm;
     private final IconDrawableFactory mIconFactory;
     private final List<AutofillServiceInfo> mServices;
 
+    private LifecycleOwner mLifecycleOwner;
+
     public PasswordsPreferenceController(Context context, String preferenceKey) {
         this(context, preferenceKey,
                 AutofillServiceInfo.getAvailableServices(context, UserHandle.myUserId()));
@@ -67,6 +94,11 @@
         mServices = availableServices;
     }
 
+    @OnLifecycleEvent(ON_CREATE)
+    void onCreate(LifecycleOwner lifecycleOwner) {
+        mLifecycleOwner = lifecycleOwner;
+    }
+
     @Override
     public int getAvailabilityStatus() {
         return mServices.isEmpty() ? CONDITIONALLY_UNAVAILABLE : AVAILABLE;
@@ -96,7 +128,83 @@
             pref.setIntent(
                     new Intent(Intent.ACTION_MAIN)
                             .setClassName(serviceInfo.packageName, service.getPasswordsActivity()));
+
+            final MutableLiveData<Integer> passwordCount = new MutableLiveData<>();
+            passwordCount.observe(
+                    mLifecycleOwner, count -> {
+                        // TODO(b/169455298): Validate the result.
+                        final CharSequence summary =
+                                mContext.getResources().getQuantityString(
+                                        R.plurals.autofill_passwords_count, count, count);
+                        pref.setSummary(summary);
+                    });
+            // TODO(b/169455298): Limit the number of concurrent queries.
+            // TODO(b/169455298): Cache the results for some time.
+            requestSavedPasswordCount(service, user, passwordCount);
+
             group.addPreference(pref);
         }
     }
+
+    private void requestSavedPasswordCount(
+            AutofillServiceInfo service, @UserIdInt int user, MutableLiveData<Integer> data) {
+        final Intent intent =
+                new Intent(AutofillService.SERVICE_INTERFACE)
+                        .setComponent(service.getServiceInfo().getComponentName());
+        final AutofillServiceConnection connection = new AutofillServiceConnection(mContext, data);
+        if (mContext.bindServiceAsUser(
+                intent, connection, Context.BIND_AUTO_CREATE, UserHandle.of(user))) {
+            connection.mBound.set(true);
+            mLifecycleOwner.getLifecycle().addObserver(connection);
+        }
+    }
+
+    private static class AutofillServiceConnection implements ServiceConnection, LifecycleObserver {
+        final WeakReference<Context> mContext;
+        final MutableLiveData<Integer> mData;
+        final AtomicBoolean mBound = new AtomicBoolean();
+
+        AutofillServiceConnection(Context context, MutableLiveData<Integer> data) {
+            mContext = new WeakReference<>(context);
+            mData = data;
+        }
+
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            final IAutoFillService autofillService = IAutoFillService.Stub.asInterface(service);
+            // TODO check if debug is logged on user build.
+            Log.d(TAG, "Fetching password count from " + name);
+            try {
+                autofillService.onSavedPasswordCountRequest(
+                        new IResultReceiver.Stub() {
+                            @Override
+                            public void send(int resultCode, Bundle resultData) {
+                                Log.d(TAG, "Received password count result " + resultCode
+                                        + " from " + name);
+                                if (resultCode == 0 && resultData != null) {
+                                    mData.postValue(resultData.getInt(EXTRA_RESULT));
+                                }
+                                unbind();
+                            }
+                        });
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to fetch password count: " + e);
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+        }
+
+        @OnLifecycleEvent(ON_DESTROY)
+        void unbind() {
+            if (!mBound.getAndSet(false)) {
+                return;
+            }
+            final Context context = mContext.get();
+            if (context != null) {
+                context.unbindService(this);
+            }
+        }
+    }
 }
diff --git a/src/com/android/settings/applications/defaultapps/AutofillPicker.java b/src/com/android/settings/applications/defaultapps/AutofillPicker.java
deleted file mode 100644
index 62a478f..0000000
--- a/src/com/android/settings/applications/defaultapps/AutofillPicker.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.applications.defaultapps;
-
-import android.app.settings.SettingsEnums;
-import android.content.Context;
-import android.provider.SearchIndexableResource;
-
-import com.android.settings.R;
-import com.android.settings.dashboard.DashboardFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.Indexable;
-import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.search.SearchIndexable;
-
-import java.util.Arrays;
-import java.util.List;
-
-@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
-public class AutofillPicker extends DashboardFragment {
-    private static final String TAG = "AutofillPicker";
-
-    @Override
-    public int getMetricsCategory() {
-        return SettingsEnums.DEFAULT_AUTOFILL_PICKER;
-    }
-
-    @Override
-    protected String getLogTag() {
-        return TAG;
-    }
-
-    @Override
-    protected int getPreferenceScreenResId() {
-        return R.xml.default_autofill_picker_settings;
-    }
-
-    @Override
-    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
-        return buildPreferenceControllers(context);
-    }
-
-    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider(R.xml.default_autofill_picker_settings) {
-
-                @Override
-                public List<AbstractPreferenceController> getPreferenceControllers(Context
-                        context) {
-                    return buildPreferenceControllers(context);
-                }
-            };
-
-    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context) {
-        return Arrays.asList(
-                new DefaultAutofillPreferenceController(context),
-                new DefaultWorkAutofillPreferenceController(context));
-    }
-}
diff --git a/src/com/android/settings/applications/intentpicker/AppLaunchSettings.java b/src/com/android/settings/applications/intentpicker/AppLaunchSettings.java
new file mode 100644
index 0000000..a277169
--- /dev/null
+++ b/src/com/android/settings/applications/intentpicker/AppLaunchSettings.java
@@ -0,0 +1,409 @@
+/*
+ * Copyright (C) 2015 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.applications.intentpicker;
+
+import static android.content.pm.verify.domain.DomainVerificationUserState.DOMAIN_STATE_NONE;
+import static android.content.pm.verify.domain.DomainVerificationUserState.DOMAIN_STATE_SELECTED;
+import static android.content.pm.verify.domain.DomainVerificationUserState.DOMAIN_STATE_VERIFIED;
+
+import android.app.Activity;
+import android.app.settings.SettingsEnums;
+import android.appwidget.AppWidgetManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.verify.domain.DomainVerificationManager;
+import android.content.pm.verify.domain.DomainVerificationUserState;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.ArraySet;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Switch;
+import android.widget.TextView;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.appcompat.app.AlertDialog;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.applications.AppInfoBase;
+import com.android.settings.applications.ClearDefaultsPreference;
+import com.android.settings.utils.AnnotationSpan;
+import com.android.settings.widget.EntityHeaderController;
+import com.android.settingslib.applications.AppUtils;
+import com.android.settingslib.widget.FooterPreference;
+import com.android.settingslib.widget.MainSwitchPreference;
+import com.android.settingslib.widget.OnMainSwitchChangeListener;
+
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+
+/** The page of the Open by default */
+public class AppLaunchSettings extends AppInfoBase implements
+        Preference.OnPreferenceChangeListener, OnMainSwitchChangeListener {
+    private static final String TAG = "AppLaunchSettings";
+    // Preference keys
+    private static final String MAIN_SWITCH_PREF_KEY = "open_by_default_supported_links";
+    private static final String VERIFIED_LINKS_PREF_KEY = "open_by_default_verified_links";
+    private static final String ADD_LINK_PREF_KEY = "open_by_default_add_link";
+    private static final String CLEAR_DEFAULTS_PREF_KEY = "app_launch_clear_defaults";
+    private static final String FOOTER_PREF_KEY = "open_by_default_footer";
+
+    private static final String MAIN_PREF_CATEGORY_KEY = "open_by_default_main_category";
+    private static final String SELECTED_LINKS_CATEGORY_KEY =
+            "open_by_default_selected_links_category";
+    private static final String OTHER_DETAILS_PREF_CATEGORY_KEY = "app_launch_other_defaults";
+
+    // Url and Uri
+    private static final String ANNOTATION_URL = "url";
+    private static final String LEARN_MORE_URI =
+            "https://developer.android.com/training/app-links/verify-site-associations";
+
+    // Dialogs id
+    private static final int DLG_VERIFIED_LINKS = DLG_BASE + 1;
+
+    // Arguments key
+    public static final String APP_PACKAGE_KEY = "app_package";
+
+    private ClearDefaultsPreference mClearDefaultsPreference;
+    private MainSwitchPreference mMainSwitchPreference;
+    private Preference mAddLinkPreference;
+    private PreferenceCategory mMainPreferenceCategory;
+    private PreferenceCategory mSelectedLinksPreferenceCategory;
+    private PreferenceCategory mOtherDefaultsPreferenceCategory;
+
+    private boolean mActivityCreated;
+
+    @VisibleForTesting
+    Context mContext;
+    @VisibleForTesting
+    DomainVerificationManager mDomainVerificationManager;
+
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        mContext = context;
+        mActivityCreated = false;
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        addPreferencesFromResource(R.xml.installed_app_launch_settings);
+        mDomainVerificationManager = mContext.getSystemService(DomainVerificationManager.class);
+        initUIComponents();
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+        createHeaderPreference();
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.APPLICATIONS_APP_LAUNCH;
+    }
+
+    @Override
+    protected AlertDialog createDialog(int id, int errorCode) {
+        if (id == DLG_VERIFIED_LINKS) {
+            return createVerifiedLinksDialog();
+        }
+        return null;
+    }
+
+    @Override
+    protected boolean refreshUi() {
+        mClearDefaultsPreference.setPackageName(mPackageName);
+        mClearDefaultsPreference.setAppEntry(mAppEntry);
+        return true;
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        final boolean isChecked = (boolean) newValue;
+        IntentPickerUtils.logd(
+                "onPreferenceChange: " + preference.getTitle() + " isChecked: " + isChecked);
+        if ((preference instanceof LeftSideCheckBoxPreference) && !isChecked) {
+            final Set<String> domainSet = new ArraySet<>();
+            domainSet.add(preference.getTitle().toString());
+            removePreference(preference.getKey());
+            final DomainVerificationUserState userState =
+                    IntentPickerUtils.getDomainVerificationUserState(mDomainVerificationManager,
+                            mPackageName);
+            if (userState == null) {
+                return false;
+            }
+            setDomainVerificationUserSelection(userState.getIdentifier(), domainSet, /* enabled= */
+                    false);
+            mAddLinkPreference.setEnabled(isAddLinksNotEmpty());
+        }
+        return true;
+    }
+
+    @Override
+    public void onSwitchChanged(Switch switchView, boolean isChecked) {
+        IntentPickerUtils.logd("onSwitchChanged: isChecked=" + isChecked);
+        if (mMainSwitchPreference != null) { //mMainSwitchPreference synced with Switch
+            mMainSwitchPreference.setChecked(isChecked);
+        }
+        if (mMainPreferenceCategory != null) {
+            mMainPreferenceCategory.setVisible(isChecked);
+        }
+        if (mDomainVerificationManager != null) {
+            try {
+                mDomainVerificationManager.setDomainVerificationLinkHandlingAllowed(mPackageName,
+                        isChecked);
+            } catch (PackageManager.NameNotFoundException e) {
+                Log.w(TAG, "onSwitchChanged: " + e.getMessage());
+            }
+        }
+    }
+
+    private void createHeaderPreference() {
+        if (mActivityCreated) {
+            Log.w(TAG, "onParentActivityCreated: ignoring duplicate call.");
+            return;
+        }
+        mActivityCreated = true;
+        if (mPackageInfo == null) {
+            Log.w(TAG, "onParentActivityCreated: PakcageInfo is null.");
+            return;
+        }
+        final Activity activity = getActivity();
+        final Preference pref = EntityHeaderController
+                .newInstance(activity, this, null /* header */)
+                .setRecyclerView(getListView(), getSettingsLifecycle())
+                .setIcon(Utils.getBadgedIcon(mContext, mPackageInfo.applicationInfo))
+                .setLabel(mPackageInfo.applicationInfo.loadLabel(mPm))
+                .setSummary("" /* summary */)  // no version number
+                .setIsInstantApp(AppUtils.isInstant(mPackageInfo.applicationInfo))
+                .setPackageName(mPackageName)
+                .setUid(mPackageInfo.applicationInfo.uid)
+                .setHasAppInfoLink(true)
+                .setButtonActions(EntityHeaderController.ActionType.ACTION_NONE,
+                        EntityHeaderController.ActionType.ACTION_NONE)
+                .done(activity, getPrefContext());
+        getPreferenceScreen().addPreference(pref);
+    }
+
+    private void initUIComponents() {
+        initMainSwitchAndCategories();
+        if (canUpdateMainSwitchAndCategories()) {
+            initVerifiedLinksPreference();
+            initAddLinkPreference();
+            addSelectedLinksPreference();
+            initFooter();
+        }
+    }
+
+    private void initMainSwitchAndCategories() {
+        mMainSwitchPreference = (MainSwitchPreference) findPreference(MAIN_SWITCH_PREF_KEY);
+        mMainPreferenceCategory = findPreference(MAIN_PREF_CATEGORY_KEY);
+        mSelectedLinksPreferenceCategory = findPreference(SELECTED_LINKS_CATEGORY_KEY);
+        // Initialize the "Other Default Category" section
+        initOtherDefaultsSection();
+    }
+
+    private boolean canUpdateMainSwitchAndCategories() {
+        final DomainVerificationUserState userState =
+                IntentPickerUtils.getDomainVerificationUserState(mDomainVerificationManager,
+                        mPackageName);
+        if (userState == null) {
+            disabledPreference();
+            return false;
+        }
+
+        IntentPickerUtils.logd("isLinkHandlingAllowed() : " + userState.isLinkHandlingAllowed());
+        mMainSwitchPreference.updateStatus(userState.isLinkHandlingAllowed());
+        mMainSwitchPreference.addOnSwitchChangeListener(this);
+        mMainPreferenceCategory.setVisible(userState.isLinkHandlingAllowed());
+        return true;
+    }
+
+    /** Initialize verified links preference */
+    private void initVerifiedLinksPreference() {
+        final VerifiedLinksPreference verifiedLinksPreference =
+                (VerifiedLinksPreference) mMainPreferenceCategory.findPreference(
+                        VERIFIED_LINKS_PREF_KEY);
+        verifiedLinksPreference.setWidgetFrameClickListener(l -> {
+            showVerifiedLinksDialog();
+        });
+        final int verifiedLinksNo = getLinksNumber(DOMAIN_STATE_VERIFIED);
+        verifiedLinksPreference.setTitle(getVerifiedLinksTitle(verifiedLinksNo));
+        verifiedLinksPreference.setCheckBoxVisible(verifiedLinksNo > 0);
+        verifiedLinksPreference.setEnabled(verifiedLinksNo > 0);
+    }
+
+    private void showVerifiedLinksDialog() {
+        final int linksNo = getLinksNumber(DOMAIN_STATE_VERIFIED);
+        if (linksNo == 0) {
+            return;
+        }
+        showDialogInner(DLG_VERIFIED_LINKS, /* moveErrorCode= */ 0);
+    }
+
+    private AlertDialog createVerifiedLinksDialog() {
+        final int linksNo = getLinksNumber(DOMAIN_STATE_VERIFIED);
+
+        final View titleView = LayoutInflater.from(mContext).inflate(
+                R.layout.app_launch_verified_links_title, /* root= */ null);
+        ((TextView) titleView.findViewById(R.id.dialog_title)).setText(
+                getVerifiedLinksTitle(linksNo));
+        ((TextView) titleView.findViewById(R.id.dialog_message)).setText(
+                getVerifiedLinksMessage(linksNo));
+
+        final List<String> verifiedLinksList = IntentPickerUtils.getLinksList(
+                mDomainVerificationManager, mPackageName, DOMAIN_STATE_VERIFIED);
+        return new AlertDialog.Builder(mContext)
+                .setCustomTitle(titleView)
+                .setCancelable(true)
+                .setItems(verifiedLinksList.toArray(new String[0]), /* listener= */ null)
+                .setPositiveButton(R.string.app_launch_dialog_ok, /* listener= */ null)
+                .create();
+    }
+
+    @VisibleForTesting
+    String getVerifiedLinksTitle(int linksNo) {
+        return getResources().getQuantityString(
+                R.plurals.app_launch_verified_links_title, linksNo, linksNo);
+    }
+
+    private String getVerifiedLinksMessage(int linksNo) {
+        return getResources().getQuantityString(
+                R.plurals.app_launch_verified_links_message, linksNo, linksNo);
+    }
+
+    /** Add selected links items */
+    void addSelectedLinksPreference() {
+        if (getLinksNumber(DOMAIN_STATE_SELECTED) == 0) {
+            return;
+        }
+        mSelectedLinksPreferenceCategory.removeAll();
+        final List<String> selectedLinks = IntentPickerUtils.getLinksList(
+                mDomainVerificationManager, mPackageName, DOMAIN_STATE_SELECTED);
+        for (String host : selectedLinks) {
+            generateCheckBoxPreference(mSelectedLinksPreferenceCategory, host);
+        }
+        mAddLinkPreference.setEnabled(isAddLinksNotEmpty());
+    }
+
+    /** Initialize add link preference */
+    private void initAddLinkPreference() {
+        mAddLinkPreference = findPreference(ADD_LINK_PREF_KEY);
+        mAddLinkPreference.setEnabled(isAddLinksNotEmpty());
+        mAddLinkPreference.setOnPreferenceClickListener(preference -> {
+            final int stateNoneLinksNo = getLinksNumber(DOMAIN_STATE_NONE);
+            IntentPickerUtils.logd("The number of the state none links: " + stateNoneLinksNo);
+            if (stateNoneLinksNo > 0) {
+                showProgressDialogFragment();
+            }
+            return true;
+        });
+    }
+
+    private boolean isAddLinksNotEmpty() {
+        return getLinksNumber(DOMAIN_STATE_NONE) > 0;
+    }
+
+    private void showProgressDialogFragment() {
+        final Bundle args = new Bundle();
+        args.putString(APP_PACKAGE_KEY, mPackageName);
+        final ProgressDialogFragment dialogFragment = new ProgressDialogFragment();
+        dialogFragment.setArguments(args);
+        dialogFragment.showDialog(getActivity().getSupportFragmentManager());
+    }
+
+    private void disabledPreference() {
+        mMainSwitchPreference.updateStatus(false);
+        mMainSwitchPreference.setSelectable(false);
+        mMainSwitchPreference.setEnabled(false);
+        mMainPreferenceCategory.setVisible(false);
+    }
+
+    /** Init OTHER DEFAULTS category */
+    private void initOtherDefaultsSection() {
+        mOtherDefaultsPreferenceCategory = findPreference(OTHER_DETAILS_PREF_CATEGORY_KEY);
+        mOtherDefaultsPreferenceCategory.setVisible(isClearDefaultsEnabled());
+        mClearDefaultsPreference = (ClearDefaultsPreference) findPreference(
+                CLEAR_DEFAULTS_PREF_KEY);
+    }
+
+    private void initFooter() {
+        // learn more
+        final AnnotationSpan.LinkInfo linkInfo =
+                new AnnotationSpan.LinkInfo(ANNOTATION_URL, v -> {
+                    final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(LEARN_MORE_URI));
+                    mContext.startActivity(intent);
+                });
+        final CharSequence footerText = mContext.getText(R.string.app_launch_footer);
+        final FooterPreference footerPreference = (FooterPreference) findPreference(
+                FOOTER_PREF_KEY);
+        footerPreference.setTitle(AnnotationSpan.linkify(footerText, linkInfo));
+    }
+
+    private boolean isClearDefaultsEnabled() {
+        final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(mContext);
+        final boolean hasBindAppWidgetPermission =
+                appWidgetManager.hasBindAppWidgetPermission(mAppEntry.info.packageName);
+
+        final boolean isAutoLaunchEnabled = AppUtils.hasPreferredActivities(mPm, mPackageName)
+                || AppUtils.isDefaultBrowser(mContext, mPackageName)
+                || AppUtils.hasUsbDefaults(mUsbManager, mPackageName);
+
+        IntentPickerUtils.logd("isClearDefaultsEnabled hasBindAppWidgetPermission : "
+                + hasBindAppWidgetPermission);
+        IntentPickerUtils.logd(
+                "isClearDefaultsEnabled isAutoLaunchEnabled : " + isAutoLaunchEnabled);
+        return (isAutoLaunchEnabled || hasBindAppWidgetPermission);
+    }
+
+    private void setDomainVerificationUserSelection(UUID identifier, Set<String> domainSet,
+            boolean isEnabled) {
+        try {
+            mDomainVerificationManager.setDomainVerificationUserSelection(identifier, domainSet,
+                    isEnabled);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.w(TAG, "addSelectedItems : " + e.getMessage());
+        }
+    }
+
+    private void generateCheckBoxPreference(PreferenceCategory parent, String title) {
+        final LeftSideCheckBoxPreference checkBoxPreference = new LeftSideCheckBoxPreference(
+                parent.getContext(), /* isChecked= */ true);
+        checkBoxPreference.setTitle(title);
+        checkBoxPreference.setOnPreferenceChangeListener(this);
+        checkBoxPreference.setKey(UUID.randomUUID().toString());
+        parent.addPreference(checkBoxPreference);
+    }
+
+    /** get the number of the specify links */
+    private int getLinksNumber(@DomainVerificationUserState.DomainState int state) {
+        final List<String> linkList = IntentPickerUtils.getLinksList(
+                mDomainVerificationManager, mPackageName, state);
+        if (linkList == null) {
+            return 0;
+        }
+        return linkList.size();
+    }
+}
diff --git a/src/com/android/settings/applications/intentpicker/IntentPickerUtils.java b/src/com/android/settings/applications/intentpicker/IntentPickerUtils.java
new file mode 100644
index 0000000..5b14bc7
--- /dev/null
+++ b/src/com/android/settings/applications/intentpicker/IntentPickerUtils.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2021 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.applications.intentpicker;
+
+import android.content.pm.PackageManager;
+import android.content.pm.verify.domain.DomainVerificationManager;
+import android.content.pm.verify.domain.DomainVerificationUserState;
+import android.os.Build;
+import android.text.Layout;
+import android.text.SpannableString;
+import android.text.style.AlignmentSpan;
+import android.util.Log;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/** The common APIs for intent picker */
+public class IntentPickerUtils {
+    private static final String TAG = "IntentPickerUtils";
+    private static final boolean DEBUG = Build.IS_DEBUGGABLE;
+
+    private IntentPickerUtils() {
+    }
+
+    /**
+     * Gets the centralized title.
+     *
+     * @param title The title of the dialog box.
+     * @return The spannable string with centralized title.
+     */
+    public static SpannableString getCentralizedDialogTitle(String title) {
+        final SpannableString dialogTitle = new SpannableString(title);
+        dialogTitle.setSpan(new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER), /* start= */
+                0, title.length(), /* flags= */ 0);
+        return dialogTitle;
+    }
+
+    /**
+     * Gets the {@link DomainVerificationUserState} for specific application.
+     *
+     * @param manager The {@link DomainVerificationManager}.
+     * @param pkgName The package name of the target application.
+     */
+    public static DomainVerificationUserState getDomainVerificationUserState(
+            DomainVerificationManager manager, String pkgName) {
+        try {
+            final DomainVerificationUserState domainVerificationUserState =
+                    manager.getDomainVerificationUserState(pkgName);
+            return domainVerificationUserState;
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.w(TAG, e.getMessage());
+            return null;
+        }
+    }
+
+    /**
+     * Gets the links list by {@link DomainVerificationUserState.DomainState}
+     *
+     * @param manager The {@link DomainVerificationManager}.
+     * @param pkgName The package name of the target application.
+     * @param state   The user state you want to query.
+     * @return A links list.
+     */
+    public static List<String> getLinksList(DomainVerificationManager manager, String pkgName,
+            @DomainVerificationUserState.DomainState int state) {
+        final DomainVerificationUserState userStage = getDomainVerificationUserState(manager,
+                pkgName);
+        if (userStage == null) {
+            return null;
+        }
+        return userStage.getHostToStateMap()
+                .entrySet()
+                .stream()
+                .filter(it -> it.getValue() == state)
+                .map(it -> it.getKey())
+                .collect(Collectors.toList());
+    }
+
+    /** Logs the message in debug ROM. */
+    public static void logd(String msg) {
+        if (DEBUG) {
+            Log.d(TAG, msg);
+        }
+    }
+}
diff --git a/src/com/android/settings/applications/intentpicker/LeftSideCheckBoxPreference.java b/src/com/android/settings/applications/intentpicker/LeftSideCheckBoxPreference.java
new file mode 100644
index 0000000..fdb6d25
--- /dev/null
+++ b/src/com/android/settings/applications/intentpicker/LeftSideCheckBoxPreference.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2021 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.applications.intentpicker;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.CheckBox;
+
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.settings.R;
+import com.android.settingslib.widget.TwoTargetPreference;
+
+/** This preference has a check box in the left side. */
+public class LeftSideCheckBoxPreference extends TwoTargetPreference {
+    private boolean mChecked;
+    private CheckBox mCheckBox;
+
+    public LeftSideCheckBoxPreference(Context context, AttributeSet attrs,
+            int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        setLayoutResource(R.layout.preference_checkable_two_target);
+    }
+
+    public LeftSideCheckBoxPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public LeftSideCheckBoxPreference(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public LeftSideCheckBoxPreference(Context context) {
+        this(context, /* attrs= */ null);
+    }
+
+    public LeftSideCheckBoxPreference(Context context, boolean isChecked) {
+        super(context);
+        mChecked = isChecked;
+        setLayoutResource(R.layout.preference_checkable_two_target);
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder view) {
+        super.onBindViewHolder(view);
+        mCheckBox = (CheckBox) view.findViewById(com.android.internal.R.id.checkbox);
+        if (mCheckBox != null) {
+            mCheckBox.setChecked(mChecked);
+        }
+    }
+
+    @Override
+    protected void onClick() {
+        if (mCheckBox != null) {
+            mChecked = !mChecked;
+            mCheckBox.setChecked(mChecked);
+            callChangeListener(mChecked);
+        }
+    }
+}
diff --git a/src/com/android/settings/applications/intentpicker/ProgressDialogFragment.java b/src/com/android/settings/applications/intentpicker/ProgressDialogFragment.java
new file mode 100644
index 0000000..f99775e
--- /dev/null
+++ b/src/com/android/settings/applications/intentpicker/ProgressDialogFragment.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2021 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.applications.intentpicker;
+
+import static android.content.pm.verify.domain.DomainVerificationUserState.DOMAIN_STATE_NONE;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.pm.verify.domain.DomainOwner;
+import android.content.pm.verify.domain.DomainVerificationManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ProgressBar;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.FragmentManager;
+import androidx.lifecycle.ViewModelProviders;
+
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settingslib.utils.ThreadUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/** A customized {@link InstrumentedDialogFragment} with a progress bar. */
+public class ProgressDialogFragment extends InstrumentedDialogFragment {
+    private static final String TAG = "ProgressDialogFragment";
+    private static final String DLG_ID = "ProgressDialog";
+    private static final int PROGRESS_BAR_STEPPING_TIME = 20;
+
+    private ProgressAlertDialog mProgressAlertDialog;
+    private DomainVerificationManager mDomainVerificationManager;
+    private List<SupportedLinkWrapper> mSupportedLinkWrapperList;
+    private SupportedLinkViewModel mViewModel;
+    private Handler mHandle;
+    private String mPackage;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mViewModel = ViewModelProviders.of(this.getActivity()).get(SupportedLinkViewModel.class);
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        mPackage = getArguments().getString(AppLaunchSettings.APP_PACKAGE_KEY);
+        mDomainVerificationManager = getActivity().getSystemService(
+                DomainVerificationManager.class);
+        mHandle = new Handler(Looper.getMainLooper());
+        mProgressAlertDialog = createProgressAlertDialog();
+        return mProgressAlertDialog;
+    }
+
+    private ProgressAlertDialog createProgressAlertDialog() {
+        final Context context = getActivity();
+        final ProgressAlertDialog progressDialog = new ProgressAlertDialog(context);
+        final String title = context.getResources().getString(
+                R.string.app_launch_checking_links_title);
+        progressDialog.setTitle(IntentPickerUtils.getCentralizedDialogTitle(title));
+        progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE,
+                context.getText(R.string.app_launch_dialog_cancel),
+                (dialog, which) -> {
+                    if (which == DialogInterface.BUTTON_NEGATIVE) {
+                        dialog.cancel();
+                    }
+                });
+        progressDialog.setCanceledOnTouchOutside(true);
+        return progressDialog;
+    }
+
+    /** Display the {@link ProgressAlertDialog}. */
+    public void showDialog(FragmentManager manager) {
+        show(manager, DLG_ID);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        generateProgressAlertDialog();
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        if (mProgressAlertDialog != null && mProgressAlertDialog.isShowing()) {
+            mProgressAlertDialog.cancel();
+        }
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return 0;
+    }
+
+    /**
+     * To generate a progress alter dialog and invoke the supported links dialog.
+     */
+    private void generateProgressAlertDialog() {
+        ThreadUtils.postOnBackgroundThread(() -> {
+            final long start = SystemClock.elapsedRealtime();
+            queryLinksInBackground();
+            IntentPickerUtils.logd(
+                    "queryLinksInBackground take time: " + (SystemClock.elapsedRealtime() - start));
+            if (mProgressAlertDialog.isShowing()) {
+                mHandle.post(() -> {
+                    synchronized (mHandle) {
+                        if (mProgressAlertDialog.isShowing()) {
+                            mProgressAlertDialog.dismiss();
+                            IntentPickerUtils.logd("mProgressAlertDialog.dismiss() and isShowing: "
+                                    + mProgressAlertDialog.isShowing());
+                            launchSupportedLinksDialogFragment();
+                        }
+                    }
+                });
+            }
+        });
+    }
+
+    private void queryLinksInBackground() {
+        final List<String> links = IntentPickerUtils.getLinksList(mDomainVerificationManager,
+                mPackage, DOMAIN_STATE_NONE);
+        final int linksNo = links.size();
+        int index = 0;
+        mSupportedLinkWrapperList = new ArrayList<>();
+        for (String host : links) {
+            final List<DomainOwner> ownerList =
+                    mDomainVerificationManager.getOwnersForDomain(host);
+            mSupportedLinkWrapperList.add(new SupportedLinkWrapper(getActivity(), host, ownerList));
+            index++;
+            // The cancel was clicked while progressing to collect data.
+            if (!mProgressAlertDialog.isShowing()) {
+                Log.w(TAG, "Exit the background thread!!!");
+                // clear buffer
+                mSupportedLinkWrapperList.clear();
+                break;
+            }
+            int progress = (int) (index * 100) / linksNo;
+            mHandle.post(() -> {
+                synchronized (mHandle) {
+                    if (!mProgressAlertDialog.isShowing()) {
+                        Log.w(TAG, "Exit the UI thread");
+                        return;
+                    }
+                    mProgressAlertDialog.getProgressBar().setProgress(progress);
+                }
+            });
+            if (ownerList.size() == 0) {
+                SystemClock.sleep(PROGRESS_BAR_STEPPING_TIME);
+            }
+        }
+        IntentPickerUtils.logd("queryLinksInBackground : SupportedLinkWrapperList size="
+                + mSupportedLinkWrapperList.size());
+        Collections.sort(mSupportedLinkWrapperList);
+    }
+
+    private void launchSupportedLinksDialogFragment() {
+        if (mSupportedLinkWrapperList.size() > 0) {
+            mViewModel.setSupportedLinkWrapperList(mSupportedLinkWrapperList);
+            final Bundle args = new Bundle();
+            args.putString(AppLaunchSettings.APP_PACKAGE_KEY, mPackage);
+            final SupportedLinksDialogFragment dialogFragment = new SupportedLinksDialogFragment();
+            dialogFragment.setArguments(args);
+            dialogFragment.showDialog(getActivity().getSupportFragmentManager());
+        }
+    }
+
+    /** Create a custom {@link AlertDialog} with a {@link ProgressBar}. */
+    static class ProgressAlertDialog extends AlertDialog {
+        private ProgressBar mProgressBar;
+
+        protected ProgressAlertDialog(@NonNull Context context) {
+            this(context, 0);
+        }
+
+        protected ProgressAlertDialog(@NonNull Context context, int themeResId) {
+            super(context, themeResId);
+            init(context);
+        }
+
+        private void init(Context context) {
+            final View view = LayoutInflater.from(context).inflate(
+                    R.layout.app_launch_progress, /* root= */ null);
+            mProgressBar = view.findViewById(R.id.scan_links_progressbar);
+            mProgressBar.setProgress(0);
+            mProgressBar.setMax(100);
+            setView(view);
+        }
+
+        ProgressBar getProgressBar() {
+            return mProgressBar;
+        }
+    }
+}
diff --git a/src/com/android/settings/applications/intentpicker/SupportedLinkViewModel.java b/src/com/android/settings/applications/intentpicker/SupportedLinkViewModel.java
new file mode 100644
index 0000000..c374b8c
--- /dev/null
+++ b/src/com/android/settings/applications/intentpicker/SupportedLinkViewModel.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2021 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.applications.intentpicker;
+
+import android.app.Application;
+
+import androidx.lifecycle.AndroidViewModel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This {@link AndroidViewModel} provides supported link wrapper data
+ * between multiple fragments.
+ */
+public class SupportedLinkViewModel extends AndroidViewModel {
+    private List<SupportedLinkWrapper> mSupportedLinkWrapperList;
+
+    public SupportedLinkViewModel(Application application) {
+        super(application);
+    }
+
+    /** Clear the list buffer of the {@link SupportedLinkWrapper}. */
+    public void clearSupportedLinkWrapperList() {
+        mSupportedLinkWrapperList = new ArrayList<>();
+    }
+
+    /** Set the list buffer of the {@link SupportedLinkWrapper}. */
+    public void setSupportedLinkWrapperList(List<SupportedLinkWrapper> wrapperList) {
+        mSupportedLinkWrapperList = wrapperList;
+    }
+
+    /** Get the list buffer of the {@link SupportedLinkWrapper}. */
+    public List<SupportedLinkWrapper> getSupportedLinkWrapperList() {
+        return mSupportedLinkWrapperList;
+    }
+}
diff --git a/src/com/android/settings/applications/intentpicker/SupportedLinkWrapper.java b/src/com/android/settings/applications/intentpicker/SupportedLinkWrapper.java
new file mode 100644
index 0000000..0acc2bc
--- /dev/null
+++ b/src/com/android/settings/applications/intentpicker/SupportedLinkWrapper.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2021 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.applications.intentpicker;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.verify.domain.DomainOwner;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.settings.R;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ *  A buffer of the supported link data. This {@link SupportedLinkWrapper} wraps the host, enabled
+ *  and a list of {@link DomainOwner}.
+ */
+public class SupportedLinkWrapper implements Comparable {
+    private static final String TAG = "SupportedLinkWrapper";
+
+    private String mHost;
+    private List<DomainOwner> mOwnerList;
+    private boolean mIsEnabled;
+    private String mLastOwnerName;
+    private boolean mIsChecked;
+
+    public SupportedLinkWrapper(Context context, String host, List<DomainOwner> ownerList) {
+        mHost = host;
+        mOwnerList = ownerList;
+        mIsEnabled = true;
+        mLastOwnerName = "";
+        mIsChecked = false;
+        init(context);
+    }
+
+    private void init(Context context) {
+        if (mOwnerList.size() > 0) {
+            final long nonOverirideableNo = mOwnerList.stream()
+                    .filter(it -> !it.isOverrideable())
+                    .count();
+            mIsEnabled = (nonOverirideableNo == 0L);
+            if (nonOverirideableNo > 0L) {
+                mLastOwnerName = getLastPackageLabel(context, false);
+            } else {
+                mLastOwnerName = getLastPackageLabel(context, true);
+            }
+        }
+    }
+
+    private String getLastPackageLabel(Context context, boolean isOverrideable) {
+        final List<String> labelList = mOwnerList.stream()
+                .filter(it -> it.isOverrideable() == isOverrideable)
+                .map(it -> getLabel(context, it.getPackageName()))
+                .filter(label -> label != null)
+                .collect(Collectors.toList());
+        return labelList.get(labelList.size() - 1);
+    }
+
+    private String getLabel(Context context, String pkg) {
+        try {
+            final PackageManager pm = context.getPackageManager();
+            return pm.getApplicationInfo(pkg, /* flags= */ 0).loadLabel(pm).toString();
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.w(TAG, "getLabel error : " + e.getMessage());
+            return null;
+        }
+    }
+
+    /** Returns the enabled/disabled value for list item. */
+    public boolean isEnabled() {
+        return mIsEnabled;
+    }
+
+    /** Returns the display format of list item in the Supported Links dialog */
+    public String getDisplayTitle(Context context) {
+        if (TextUtils.isEmpty(mLastOwnerName) || context == null) {
+            return mHost;
+        }
+        return mHost + System.lineSeparator() + context.getString(
+                R.string.app_launch_supported_links_subtext, mLastOwnerName);
+    }
+
+    /** Returns the host name. */
+    public String getHost() {
+        return mHost;
+    }
+
+    /** Returns the checked value for list item. */
+    public boolean isChecked() {
+        return mIsChecked;
+    }
+
+    /** Set the checked value. */
+    public void setChecked(boolean isChecked) {
+        mIsChecked = isChecked;
+    }
+
+    @Override
+    public int compareTo(Object o) {
+        final SupportedLinkWrapper that = (SupportedLinkWrapper) o;
+        if (this.mIsEnabled != that.mIsEnabled) {
+            return this.mIsEnabled ? -1 : 1;
+        }
+        if (TextUtils.isEmpty(this.mLastOwnerName) != TextUtils.isEmpty(that.mLastOwnerName)) {
+            return TextUtils.isEmpty(this.mLastOwnerName) ? -1 : 1;
+        }
+        return 0;
+    }
+}
diff --git a/src/com/android/settings/applications/intentpicker/SupportedLinksAdapter.java b/src/com/android/settings/applications/intentpicker/SupportedLinksAdapter.java
new file mode 100644
index 0000000..9288d52
--- /dev/null
+++ b/src/com/android/settings/applications/intentpicker/SupportedLinksAdapter.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2021 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.applications.intentpicker;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.CheckedTextView;
+
+import com.android.settings.R;
+
+import java.util.List;
+
+/** This adapter is for supported links dialog. */
+public class SupportedLinksAdapter extends BaseAdapter {
+    private final Context mContext;
+    private final List<SupportedLinkWrapper> mWrapperList;
+
+    public SupportedLinksAdapter(Context context, List<SupportedLinkWrapper> list) {
+        mContext = context;
+        mWrapperList = list;
+    }
+
+    @Override
+    public int getCount() {
+        return mWrapperList.size();
+    }
+
+    @Override
+    public Object getItem(int position) {
+        if (position < mWrapperList.size()) {
+            return mWrapperList.get(position);
+        }
+        return null;
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return position;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        if (convertView == null) {
+            convertView = LayoutInflater.from(mContext).inflate(
+                    R.layout.supported_links_dialog_item, /* root= */ null);
+        }
+        final CheckedTextView textView = convertView.findViewById(android.R.id.text1);
+        textView.setText(mWrapperList.get(position).getDisplayTitle(mContext));
+        textView.setEnabled(mWrapperList.get(position).isEnabled());
+        textView.setChecked(mWrapperList.get(position).isChecked());
+        textView.setOnClickListener(l -> {
+            textView.toggle();
+            mWrapperList.get(position).setChecked(textView.isChecked());
+        });
+        return convertView;
+    }
+}
diff --git a/src/com/android/settings/applications/intentpicker/SupportedLinksDialogFragment.java b/src/com/android/settings/applications/intentpicker/SupportedLinksDialogFragment.java
new file mode 100644
index 0000000..db93df2
--- /dev/null
+++ b/src/com/android/settings/applications/intentpicker/SupportedLinksDialogFragment.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2021 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.applications.intentpicker;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.verify.domain.DomainVerificationManager;
+import android.content.pm.verify.domain.DomainVerificationUserState;
+import android.os.Bundle;
+import android.util.ArraySet;
+import android.util.Log;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.lifecycle.ViewModelProviders;
+
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+
+/** A customized {@link InstrumentedDialogFragment} with multiple checkboxes. */
+public class SupportedLinksDialogFragment extends InstrumentedDialogFragment {
+    private static final String TAG = "SupportedLinksDialogFrg";
+    private static final String DLG_ID = "SupportedLinksDialog";
+
+    private SupportedLinkViewModel mViewModel;
+    private List<SupportedLinkWrapper> mSupportedLinkWrapperList;
+    private String mPackage;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mPackage = getArguments().getString(AppLaunchSettings.APP_PACKAGE_KEY);
+        mViewModel = ViewModelProviders.of(this.getActivity()).get(SupportedLinkViewModel.class);
+        mSupportedLinkWrapperList = mViewModel.getSupportedLinkWrapperList();
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        final Context context = getActivity();
+        final SupportedLinksAdapter adapter = new SupportedLinksAdapter(context,
+                mSupportedLinkWrapperList);
+        final AlertDialog.Builder builder = new AlertDialog
+                .Builder(context)
+                .setTitle(IntentPickerUtils.getCentralizedDialogTitle(getSupportedLinksTitle()))
+                .setAdapter(adapter, /* listener= */ null)
+                .setCancelable(true)
+                .setPositiveButton(R.string.app_launch_supported_links_add, (dialog, id) -> {
+                    doSelectedAction();
+                })
+                .setNegativeButton(R.string.app_launch_dialog_cancel, /* listener= */ null);
+        return builder.create();
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return 0;
+    }
+
+    /** Display the dialog. */
+    public void showDialog(FragmentManager manager) {
+        show(manager, DLG_ID);
+    }
+
+    private String getSupportedLinksTitle() {
+        final int supportedLinksNo = mSupportedLinkWrapperList.size();
+        return getResources().getQuantityString(
+                R.plurals.app_launch_supported_links_title, supportedLinksNo, supportedLinksNo);
+    }
+
+    private void doSelectedAction() {
+        final DomainVerificationManager manager = getActivity().getSystemService(
+                DomainVerificationManager.class);
+        final DomainVerificationUserState userState =
+                IntentPickerUtils.getDomainVerificationUserState(manager, mPackage);
+        if (userState == null || mSupportedLinkWrapperList == null) {
+            return;
+        }
+
+        updateUserSelection(manager, userState);
+        displaySelectedItem();
+    }
+
+    private void updateUserSelection(DomainVerificationManager manager,
+            DomainVerificationUserState userState) {
+        final Set<String> domainSet = new ArraySet<>();
+        for (SupportedLinkWrapper wrapper : mSupportedLinkWrapperList) {
+            if (wrapper.isChecked()) {
+                domainSet.add(wrapper.getHost());
+            }
+        }
+        if (domainSet.size() > 0) {
+            setDomainVerificationUserSelection(manager, userState.getIdentifier(),
+                    domainSet, /* enabled= */true);
+        }
+    }
+
+    private void setDomainVerificationUserSelection(DomainVerificationManager manager,
+            UUID identifier, Set<String> domainSet, boolean isEnabled) {
+        try {
+            manager.setDomainVerificationUserSelection(identifier, domainSet, isEnabled);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.w(TAG, "addSelectedItems : " + e.getMessage());
+        }
+    }
+
+    private void displaySelectedItem() {
+        final List<Fragment> fragments = getActivity().getSupportFragmentManager().getFragments();
+        for (Fragment fragment : fragments) {
+            if (fragment instanceof AppLaunchSettings) {
+                ((AppLaunchSettings) fragment).addSelectedLinksPreference();
+            }
+        }
+    }
+}
diff --git a/src/com/android/settings/applications/intentpicker/VerifiedLinksPreference.java b/src/com/android/settings/applications/intentpicker/VerifiedLinksPreference.java
new file mode 100644
index 0000000..5452a2a
--- /dev/null
+++ b/src/com/android/settings/applications/intentpicker/VerifiedLinksPreference.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2021 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.applications.intentpicker;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.CheckBox;
+
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.settings.R;
+import com.android.settingslib.widget.TwoTargetPreference;
+
+/** This customized VerifiedLinksPreference was belonged to Open by default page */
+public class VerifiedLinksPreference extends TwoTargetPreference {
+    private Context mContext;
+    private View.OnClickListener mOnWidgetClickListener;
+    private boolean mShowCheckBox;
+
+    public VerifiedLinksPreference(Context context, AttributeSet attrs,
+            int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        init(context);
+    }
+
+    public VerifiedLinksPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, /* defStyleRes= */0);
+    }
+
+    public VerifiedLinksPreference(Context context, AttributeSet attrs) {
+        this(context, attrs, /* defStyleAttr= */ 0);
+    }
+
+    public VerifiedLinksPreference(Context context) {
+        this(context, /* attrs= */ null);
+    }
+
+    private void init(Context context) {
+        mContext = context;
+        mOnWidgetClickListener = null;
+        mShowCheckBox = true;
+        setLayoutResource(R.layout.preference_checkable_two_target);
+        setWidgetLayoutResource(R.layout.verified_links_widget);
+    }
+
+    /**
+     * Register a callback to be invoked when this widget is clicked.
+     *
+     * @param listener The callback that will run.
+     */
+    public void setWidgetFrameClickListener(View.OnClickListener listener) {
+        mOnWidgetClickListener = listener;
+    }
+
+    /** Determine the visibility of the {@link CheckBox}. */
+    public void setCheckBoxVisible(boolean isVisible) {
+        mShowCheckBox = isVisible;
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder view) {
+        super.onBindViewHolder(view);
+        final View settingsWidget = view.findViewById(android.R.id.widget_frame);
+        final View divider = view.findViewById(R.id.two_target_divider);
+        divider.setVisibility(View.VISIBLE);
+        settingsWidget.setVisibility(View.VISIBLE);
+        if (mOnWidgetClickListener != null) {
+            settingsWidget.setOnClickListener(mOnWidgetClickListener);
+        }
+        final View checkboxContainer = view.findViewById(R.id.checkbox_container);
+        final View parentView = (View) checkboxContainer.getParent();
+        parentView.setEnabled(false);
+        parentView.setClickable(false);
+        CheckBox checkBox = (CheckBox) view.findViewById(com.android.internal.R.id.checkbox);
+        if (checkBox != null) {
+            checkBox.setChecked(true);
+            checkBox.setVisibility(mShowCheckBox ? View.VISIBLE : View.INVISIBLE);
+        }
+    }
+}
diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java
index e98555b..a92f539 100644
--- a/src/com/android/settings/applications/manageapplications/ManageApplications.java
+++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java
@@ -277,7 +277,7 @@
         Intent intent = activity.getIntent();
         Bundle args = getArguments();
         int screenTitle = intent.getIntExtra(
-                SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE_RESID, R.string.application_info_label);
+                SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE_RESID, R.string.all_apps);
         String className = args != null ? args.getString(EXTRA_CLASSNAME) : null;
         if (className == null) {
             className = intent.getComponent().getClassName();
@@ -342,7 +342,7 @@
             screenTitle = R.string.app_notifications_title;
         } else {
             if (screenTitle == -1) {
-                screenTitle = R.string.application_info_label;
+                screenTitle = R.string.all_apps;
             }
             mListType = LIST_TYPE_MAIN;
         }
diff --git a/src/com/android/settings/applications/managedomainurls/DomainAppPreferenceController.java b/src/com/android/settings/applications/managedomainurls/DomainAppPreferenceController.java
index c859db2..07c4858 100644
--- a/src/com/android/settings/applications/managedomainurls/DomainAppPreferenceController.java
+++ b/src/com/android/settings/applications/managedomainurls/DomainAppPreferenceController.java
@@ -28,7 +28,7 @@
 
 import com.android.settings.R;
 import com.android.settings.applications.AppInfoBase;
-import com.android.settings.applications.AppLaunchSettings;
+import com.android.settings.applications.intentpicker.AppLaunchSettings;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.applications.ApplicationsState.AppEntry;
diff --git a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java
index 1fe3f17..0625bbb 100644
--- a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java
+++ b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java
@@ -71,6 +71,7 @@
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 import com.android.settingslib.RestrictedLockUtilsInternal;
+import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity;
 
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -79,7 +80,10 @@
 import java.util.List;
 import java.util.Optional;
 
-public class DeviceAdminAdd extends Activity {
+/**
+ * A confirmation screen for enabling administractor.
+ */
+public class DeviceAdminAdd extends CollapsingToolbarBaseActivity {
     static final String TAG = "DeviceAdminAdd";
 
     static final int DIALOG_WARNING = 1;
diff --git a/src/com/android/settings/biometrics/BiometricUtils.java b/src/com/android/settings/biometrics/BiometricUtils.java
index d93a321..f338eb5 100644
--- a/src/com/android/settings/biometrics/BiometricUtils.java
+++ b/src/com/android/settings/biometrics/BiometricUtils.java
@@ -24,6 +24,7 @@
 import android.content.IntentSender;
 import android.os.storage.StorageManager;
 import android.util.Log;
+import android.view.Surface;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -241,4 +242,14 @@
         }
         return false;
     }
+
+    /**
+     * Returns {@code true} if the screen is going into a landscape mode and the angle is equal to
+     * 270.
+     * @param context Context that we use to get the display this context is associated with
+     * @return True if the angle of the rotation is equal to 270.
+     */
+    public static boolean isReverseLandscape(@NonNull Context context) {
+        return context.getDisplay().getRotation() == Surface.ROTATION_270;
+    }
 }
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
index 10b31e3..8def63d 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
@@ -47,6 +47,7 @@
 import com.android.settings.R;
 import com.android.settings.biometrics.BiometricEnrollSidecar;
 import com.android.settings.biometrics.BiometricErrorDialog;
+import com.android.settings.biometrics.BiometricUtils;
 import com.android.settings.biometrics.BiometricsEnrollEnrolling;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
 
@@ -98,6 +99,7 @@
     private boolean mCanAssumeUdfps;
     @Nullable private ProgressBar mProgressBar;
     private ObjectAnimator mProgressAnim;
+    private TextView mDescriptionText;
     private TextView mErrorText;
     private Interpolator mFastOutSlowInInterpolator;
     private Interpolator mLinearOutSlowInInterpolator;
@@ -145,7 +147,11 @@
         mCanAssumeUdfps = props.size() == 1 && props.get(0).isAnyUdfpsType();
 
         if (mCanAssumeUdfps) {
-            setContentView(R.layout.udfps_enroll_enrolling);
+            if (BiometricUtils.isReverseLandscape(getApplicationContext())) {
+                setContentView(R.layout.udfps_enroll_enrolling_land);
+            } else {
+                setContentView(R.layout.udfps_enroll_enrolling);
+            }
             setDescriptionText(R.string.security_settings_udfps_enroll_start_message);
         } else {
             setContentView(R.layout.fingerprint_enroll_enrolling);
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java
index 94eb278..8bc03ac 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java
@@ -112,7 +112,11 @@
 
     protected int getContentView() {
         if (mCanAssumeUdfps) {
-            return R.layout.udfps_enroll_find_sensor_layout;
+            if (BiometricUtils.isReverseLandscape(getApplicationContext())) {
+                return R.layout.udfps_enroll_find_sensor_land;
+            } else {
+                return R.layout.udfps_enroll_find_sensor_layout;
+            }
         }
         return R.layout.fingerprint_enroll_find_sensor;
     }
diff --git a/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java
index 096c2c5..bc5aa47 100644
--- a/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java
+++ b/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java
@@ -192,6 +192,7 @@
                 updateSubLayout(mLayoutPreference.findViewById(R.id.layout_middle),
                         BluetoothDevice.METADATA_MAIN_ICON,
                         BluetoothDevice.METADATA_MAIN_BATTERY,
+                        BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD,
                         BluetoothDevice.METADATA_MAIN_CHARGING,
                         /* titleResId */ 0,
                         MAIN_DEVICE_ID);
@@ -202,6 +203,7 @@
                 updateSubLayout(mLayoutPreference.findViewById(R.id.layout_left),
                         BluetoothDevice.METADATA_UNTETHERED_LEFT_ICON,
                         BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY,
+                        BluetoothDevice.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD,
                         BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING,
                         R.string.bluetooth_left_name,
                         LEFT_DEVICE_ID);
@@ -209,6 +211,7 @@
                 updateSubLayout(mLayoutPreference.findViewById(R.id.layout_middle),
                         BluetoothDevice.METADATA_UNTETHERED_CASE_ICON,
                         BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY,
+                        BluetoothDevice.METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD,
                         BluetoothDevice.METADATA_UNTETHERED_CASE_CHARGING,
                         R.string.bluetooth_middle_name,
                         CASE_DEVICE_ID);
@@ -216,6 +219,7 @@
                 updateSubLayout(mLayoutPreference.findViewById(R.id.layout_right),
                         BluetoothDevice.METADATA_UNTETHERED_RIGHT_ICON,
                         BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY,
+                        BluetoothDevice.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD,
                         BluetoothDevice.METADATA_UNTETHERED_RIGHT_CHARGING,
                         R.string.bluetooth_right_name,
                         RIGHT_DEVICE_ID);
@@ -243,7 +247,7 @@
     }
 
     private void updateSubLayout(LinearLayout linearLayout, int iconMetaKey, int batteryMetaKey,
-            int chargeMetaKey, int titleResId, int deviceId) {
+            int lowBatteryMetaKey, int chargeMetaKey, int titleResId, int deviceId) {
         if (linearLayout == null) {
             return;
         }
@@ -273,7 +277,15 @@
             linearLayout.setVisibility(View.VISIBLE);
             batterySummaryView.setText(com.android.settings.Utils.formatPercentage(batteryLevel));
             batterySummaryView.setVisibility(View.VISIBLE);
-            showBatteryIcon(linearLayout, batteryLevel, charging, batteryMetaKey);
+            int lowBatteryLevel = BluetoothUtils.getIntMetaData(bluetoothDevice, lowBatteryMetaKey);
+            if (lowBatteryLevel == BluetoothUtils.META_INT_ERROR) {
+                if (batteryMetaKey == BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY) {
+                    lowBatteryLevel = CASE_LOW_BATTERY_LEVEL;
+                } else {
+                    lowBatteryLevel = LOW_BATTERY_LEVEL;
+                }
+            }
+            showBatteryIcon(linearLayout, batteryLevel, lowBatteryLevel, charging);
         } else {
             if (deviceId == MAIN_DEVICE_ID) {
                 linearLayout.setVisibility(View.VISIBLE);
@@ -354,11 +366,8 @@
         });
     }
 
-    private void showBatteryIcon(LinearLayout linearLayout, int level, boolean charging,
-            int batteryMetaKey) {
-        final int lowBatteryLevel =
-                batteryMetaKey == BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY
-                ? CASE_LOW_BATTERY_LEVEL : LOW_BATTERY_LEVEL;
+    private void showBatteryIcon(LinearLayout linearLayout, int level, int lowBatteryLevel,
+            boolean charging) {
         final boolean enableLowBattery = level <= lowBatteryLevel && !charging;
         final ImageView imageView = linearLayout.findViewById(R.id.bt_battery_icon);
         if (enableLowBattery) {
diff --git a/src/com/android/settings/datetime/DateTimeSettings.java b/src/com/android/settings/datetime/DateTimeSettings.java
index 469a4c7..d74847f 100644
--- a/src/com/android/settings/datetime/DateTimeSettings.java
+++ b/src/com/android/settings/datetime/DateTimeSettings.java
@@ -59,6 +59,7 @@
     public void onAttach(Context context) {
         super.onAttach(context);
         getSettingsLifecycle().addObserver(new TimeChangeListenerMixin(context, this));
+        use(LocationTimeZoneDetectionPreferenceController.class).setFragment(this);
     }
 
     @Override
@@ -77,6 +78,7 @@
         final AutoTimeFormatPreferenceController autoTimeFormatPreferenceController =
                 new AutoTimeFormatPreferenceController(
                         activity, this /* UpdateTimeAndDateCallback */);
+
         controllers.add(autoTimeZonePreferenceController);
         controllers.add(autoTimePreferenceController);
         controllers.add(autoTimeFormatPreferenceController);
diff --git a/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceController.java b/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceController.java
index 0b0fa27..cb39635 100644
--- a/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceController.java
+++ b/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceController.java
@@ -31,6 +31,7 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
+import com.android.settings.core.InstrumentedPreferenceFragment;
 import com.android.settings.core.TogglePreferenceController;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnStart;
@@ -46,17 +47,24 @@
         extends TogglePreferenceController
         implements LifecycleObserver, OnStart, OnStop, TimeManager.TimeZoneDetectorListener {
 
+    private static final String TAG = "location_time_zone_detection";
+
     private final TimeManager mTimeManager;
     private final LocationManager mLocationManager;
     private TimeZoneCapabilitiesAndConfig mTimeZoneCapabilitiesAndConfig;
+    private InstrumentedPreferenceFragment mFragment;
     private Preference mPreference;
 
-    public LocationTimeZoneDetectionPreferenceController(Context context, String key) {
-        super(context, key);
+    public LocationTimeZoneDetectionPreferenceController(Context context) {
+        super(context, TAG);
         mTimeManager = context.getSystemService(TimeManager.class);
         mLocationManager = context.getSystemService(LocationManager.class);
     }
 
+    void setFragment(InstrumentedPreferenceFragment fragment) {
+        mFragment = fragment;
+    }
+
     @Override
     public boolean isChecked() {
         TimeZoneCapabilitiesAndConfig capabilitiesAndConfig =
@@ -67,10 +75,17 @@
 
     @Override
     public boolean setChecked(boolean isChecked) {
-        TimeZoneConfiguration configuration = new TimeZoneConfiguration.Builder()
-                .setGeoDetectionEnabled(isChecked)
-                .build();
-        return mTimeManager.updateTimeZoneConfiguration(configuration);
+        if (isChecked && !mLocationManager.isLocationEnabled()) {
+            new LocationToggleDisabledDialogFragment(mContext)
+                    .show(mFragment.getFragmentManager(), TAG);
+            // Toggle status is not updated.
+            return false;
+        } else {
+            TimeZoneConfiguration configuration = new TimeZoneConfiguration.Builder()
+                    .setGeoDetectionEnabled(isChecked)
+                    .build();
+            return mTimeManager.updateTimeZoneConfiguration(configuration);
+        }
     }
 
     @Override
diff --git a/src/com/android/settings/datetime/LocationToggleDisabledDialogFragment.java b/src/com/android/settings/datetime/LocationToggleDisabledDialogFragment.java
new file mode 100644
index 0000000..61d46c6
--- /dev/null
+++ b/src/com/android/settings/datetime/LocationToggleDisabledDialogFragment.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2021 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.datetime;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.provider.Settings;
+
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+
+/**
+ * Dialog shown when user tries to enable GeoTZ with Location toggle disabled.
+ */
+public class LocationToggleDisabledDialogFragment extends InstrumentedDialogFragment {
+
+    private final Context mContext;
+
+    public LocationToggleDisabledDialogFragment(Context context) {
+        mContext = context;
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        return new AlertDialog.Builder(getActivity())
+                .setTitle(R.string.location_time_zone_detection_location_is_off_dialog_title)
+                .setIcon(R.drawable.ic_warning_24dp)
+                .setMessage(R.string.location_time_zone_detection_location_is_off_dialog_message)
+                .setPositiveButton(
+                        R.string.location_time_zone_detection_location_is_off_dialog_ok_button,
+                        (dialog, which) -> {
+                            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
+                            mContext.startActivity(intent);
+                        })
+                .setNegativeButton(
+                        R.string.location_time_zone_detection_location_is_off_dialog_cancel_button,
+                        (dialog, which) -> {})
+                .create();
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.DIALOG_DATE_TIME_ENABLE_GEOTZ_WITH_DISABLED_LOCATION;
+    }
+}
diff --git a/src/com/android/settings/datetime/timezone/RegionSearchPicker.java b/src/com/android/settings/datetime/timezone/RegionSearchPicker.java
index 07986e2..85d5d70 100644
--- a/src/com/android/settings/datetime/timezone/RegionSearchPicker.java
+++ b/src/com/android/settings/datetime/timezone/RegionSearchPicker.java
@@ -71,14 +71,14 @@
         final FilteredCountryTimeZones countryTimeZones = mTimeZoneData.lookupCountryTimeZones(
                 regionId);
         final Activity activity = getActivity();
-        if (countryTimeZones == null || countryTimeZones.getTimeZoneIds().isEmpty()) {
+        if (countryTimeZones == null || countryTimeZones.getPreferredTimeZoneIds().isEmpty()) {
             Log.e(TAG, "Region has no time zones: " + regionId);
             activity.setResult(Activity.RESULT_CANCELED);
             activity.finish();
             return;
         }
 
-        List<String> timeZoneIds = countryTimeZones.getTimeZoneIds();
+        List<String> timeZoneIds = countryTimeZones.getPreferredTimeZoneIds();
         // Choose the time zone associated the region if there is only one time zone in that region
         if (timeZoneIds.size() == 1) {
             final Intent resultData = new Intent()
diff --git a/src/com/android/settings/datetime/timezone/RegionZonePicker.java b/src/com/android/settings/datetime/timezone/RegionZonePicker.java
index 8e4aa05..7f988cd 100644
--- a/src/com/android/settings/datetime/timezone/RegionZonePicker.java
+++ b/src/com/android/settings/datetime/timezone/RegionZonePicker.java
@@ -103,7 +103,7 @@
         // It could be a timely operations if there are many time zones. A region in time zone data
         // contains a maximum of 29 time zones currently. It may change in the future, but it's
         // unlikely to be changed drastically.
-        return getRegionTimeZoneInfo(filteredCountryTimeZones.getTimeZoneIds());
+        return getRegionTimeZoneInfo(filteredCountryTimeZones.getPreferredTimeZoneIds());
     }
 
     /**
diff --git a/src/com/android/settings/datetime/timezone/TimeZoneSettings.java b/src/com/android/settings/datetime/timezone/TimeZoneSettings.java
index 60cd636..6c779b5 100644
--- a/src/com/android/settings/datetime/timezone/TimeZoneSettings.java
+++ b/src/com/android/settings/datetime/timezone/TimeZoneSettings.java
@@ -214,10 +214,11 @@
                 mTimeZoneData.lookupCountryTimeZones(regionId);
 
         use(RegionZonePreferenceController.class).setTimeZoneInfo(tzInfo);
-        // Only clickable when the region has more than 1 time zones or no time zone is selected.
 
+        // Only clickable when the region has more than 1 time zones or no time zone is selected.
         use(RegionZonePreferenceController.class).setClickable(tzInfo == null ||
-                (countryTimeZones != null && countryTimeZones.getTimeZoneIds().size() > 1));
+                (countryTimeZones != null
+                        && countryTimeZones.getPreferredTimeZoneIds().size() > 1));
         use(TimeZoneInfoPreferenceController.class).setTimeZoneInfo(tzInfo);
 
         updatePreferenceStates();
@@ -244,7 +245,8 @@
 
         FilteredCountryTimeZones countryTimeZones =
                 timeZoneData.lookupCountryTimeZones(regionId);
-        if (countryTimeZones == null || !countryTimeZones.getTimeZoneIds().contains(tzId)) {
+        if (countryTimeZones == null
+                || !countryTimeZones.getPreferredTimeZoneIds().contains(tzId)) {
             Log.e(TAG, "Unknown time zone id is selected: " + tzId);
             return;
         }
diff --git a/src/com/android/settings/datetime/timezone/model/FilteredCountryTimeZones.java b/src/com/android/settings/datetime/timezone/model/FilteredCountryTimeZones.java
index 7a38853..05a542d 100644
--- a/src/com/android/settings/datetime/timezone/model/FilteredCountryTimeZones.java
+++ b/src/com/android/settings/datetime/timezone/model/FilteredCountryTimeZones.java
@@ -16,11 +16,15 @@
 
 package com.android.settings.datetime.timezone.model;
 
+import android.util.ArraySet;
+
 import com.android.i18n.timezone.CountryTimeZones;
 
+import java.time.Instant;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.stream.Collectors;
+import java.util.Set;
 
 /**
  * Wrap {@class CountryTimeZones} to filter time zone that are shown in the picker.
@@ -39,31 +43,46 @@
      * a timestamp known to be in the recent past is used. This should be updated occasionally but
      * it doesn't have to be very often.
      */
-    private static final long MIN_USE_DATE_OF_TIMEZONE = 1546300800000L; // 1/1/2019 00:00 UTC
+    private static final Instant MIN_USE_DATE_OF_TIMEZONE =
+            Instant.ofEpochMilli(1546300800000L); // 1/1/2019 00:00 UTC
 
     private final CountryTimeZones mCountryTimeZones;
-    private final List<String> mTimeZoneIds;
+    private final List<String> mPreferredTimeZoneIds;
+    private final Set<String> mAlternativeTimeZoneIds;
 
     public FilteredCountryTimeZones(CountryTimeZones countryTimeZones) {
         mCountryTimeZones = countryTimeZones;
-        List<String> timeZoneIds = countryTimeZones.getTimeZoneMappings().stream()
-                .filter(timeZoneMapping ->
-                        timeZoneMapping.isShownInPicker()
-                                && (timeZoneMapping.getNotUsedAfter() == null
-                                || timeZoneMapping.getNotUsedAfter() >= MIN_USE_DATE_OF_TIMEZONE))
-                .map(timeZoneMapping -> timeZoneMapping.getTimeZoneId())
-                .collect(Collectors.toList());
-        mTimeZoneIds = Collections.unmodifiableList(timeZoneIds);
+        List<String> timeZoneIds = new ArrayList<>();
+        Set<String> alternativeTimeZoneIds = new ArraySet<>();
+        for (CountryTimeZones.TimeZoneMapping timeZoneMapping :
+                countryTimeZones.getTimeZoneMappings()) {
+            if (timeZoneMapping.isShownInPickerAt(MIN_USE_DATE_OF_TIMEZONE)) {
+                String timeZoneId = timeZoneMapping.getTimeZoneId();
+                timeZoneIds.add(timeZoneId);
+                alternativeTimeZoneIds.addAll(timeZoneMapping.getAlternativeIds());
+            }
+        }
+        mPreferredTimeZoneIds = Collections.unmodifiableList(timeZoneIds);
+        mAlternativeTimeZoneIds = Collections.unmodifiableSet(alternativeTimeZoneIds);
     }
 
-    public List<String> getTimeZoneIds() {
-        return mTimeZoneIds;
+    public List<String> getPreferredTimeZoneIds() {
+        return mPreferredTimeZoneIds;
     }
 
     public CountryTimeZones getCountryTimeZones() {
         return mCountryTimeZones;
     }
 
+    /**
+     * Returns whether {@code timeZoneId} is currently used in the country or is an alternative
+     * name of a currently used time zone.
+     */
+    public boolean matches(String timeZoneId) {
+        return mPreferredTimeZoneIds.contains(timeZoneId)
+                || mAlternativeTimeZoneIds.contains(timeZoneId);
+    }
+
     public String getRegionId() {
         return TimeZoneData.normalizeRegionId(mCountryTimeZones.getCountryIso());
     }
diff --git a/src/com/android/settings/datetime/timezone/model/TimeZoneData.java b/src/com/android/settings/datetime/timezone/model/TimeZoneData.java
index 335e6e2..06f2de0 100644
--- a/src/com/android/settings/datetime/timezone/model/TimeZoneData.java
+++ b/src/com/android/settings/datetime/timezone/model/TimeZoneData.java
@@ -71,7 +71,7 @@
         Set<String> regionIds = new ArraySet<>();
         for (CountryTimeZones countryTimeZone : countryTimeZones) {
             FilteredCountryTimeZones filteredZones = new FilteredCountryTimeZones(countryTimeZone);
-            if (filteredZones.getTimeZoneIds().contains(tzId)) {
+            if (filteredZones.matches(tzId)) {
                 regionIds.add(filteredZones.getRegionId());
             }
         }
diff --git a/src/com/android/settings/development/DefaultUsbConfigurationPreferenceController.java b/src/com/android/settings/development/DefaultUsbConfigurationPreferenceController.java
index 905c552..be7704f 100644
--- a/src/com/android/settings/development/DefaultUsbConfigurationPreferenceController.java
+++ b/src/com/android/settings/development/DefaultUsbConfigurationPreferenceController.java
@@ -54,4 +54,11 @@
         mPreference.setDisabledByAdmin(
                 checkIfUsbDataSignalingIsDisabled(mContext, UserHandle.myUserId()));
     }
+
+    @Override
+    protected void onDeveloperOptionsSwitchEnabled() {
+        super.onDeveloperOptionsSwitchEnabled();
+        mPreference.setDisabledByAdmin(
+                checkIfUsbDataSignalingIsDisabled(mContext, UserHandle.myUserId()));
+    }
 }
diff --git a/src/com/android/settings/development/UsbAudioRoutingPreferenceController.java b/src/com/android/settings/development/UsbAudioRoutingPreferenceController.java
index 8aa4f3c..e130b2b 100644
--- a/src/com/android/settings/development/UsbAudioRoutingPreferenceController.java
+++ b/src/com/android/settings/development/UsbAudioRoutingPreferenceController.java
@@ -83,4 +83,11 @@
                 Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED, SETTING_VALUE_OFF);
         ((SwitchPreference) mPreference).setChecked(false);
     }
+
+    @Override
+    protected void onDeveloperOptionsSwitchEnabled() {
+        super.onDeveloperOptionsSwitchEnabled();
+        mPreference.setDisabledByAdmin(
+                checkIfUsbDataSignalingIsDisabled(mContext, UserHandle.myUserId()));
+    }
 }
diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
index b8c4e28..03a7b97 100644
--- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
+++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
@@ -248,15 +248,19 @@
 
         mPreferenceController.setVolume(mSelectedStorageEntry.getVolumeInfo());
 
-        if (mSelectedStorageEntry.isPrivate() && mSelectedStorageEntry.isMounted()) {
+        if (!mSelectedStorageEntry.isMounted()) {
+            // Set null volume to hide category stats.
+            mPreferenceController.setVolume(null);
+            return;
+        }
+        if (mSelectedStorageEntry.isPrivate()) {
             // Stats data is only available on private volumes.
             getLoaderManager().restartLoader(STORAGE_JOB_ID, Bundle.EMPTY, this);
             getLoaderManager()
                  .restartLoader(VOLUME_SIZE_JOB_ID, Bundle.EMPTY, new VolumeSizeCallbacks());
             getLoaderManager().restartLoader(ICON_JOB_ID, Bundle.EMPTY, new IconLoaderCallbacks());
         } else {
-            // Set null volume to hide category stats.
-            mPreferenceController.setVolume(null);
+            mPreferenceController.setVolume(mSelectedStorageEntry.getVolumeInfo());
         }
     }
 
diff --git a/src/com/android/settings/deviceinfo/StorageItemPreference.java b/src/com/android/settings/deviceinfo/StorageItemPreference.java
index 0766a74..65ef6f4 100644
--- a/src/com/android/settings/deviceinfo/StorageItemPreference.java
+++ b/src/com/android/settings/deviceinfo/StorageItemPreference.java
@@ -35,6 +35,7 @@
     private ProgressBar mProgressBar;
     private static final int PROGRESS_MAX = 100;
     private int mProgressPercent = UNINITIALIZED;
+    private long mStorageSize;
 
     public StorageItemPreference(Context context) {
         this(context, null);
@@ -47,6 +48,7 @@
     }
 
     public void setStorageSize(long size, long total) {
+        mStorageSize = size;
         setSummary(
                 FileSizeFormatter.formatFileSize(
                         getContext(),
@@ -61,6 +63,10 @@
         updateProgressBar();
     }
 
+    public long getStorageSize() {
+        return mStorageSize;
+    }
+
     protected void updateProgressBar() {
         if (mProgressBar == null || mProgressPercent == UNINITIALIZED)
             return;
diff --git a/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceController.java b/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceController.java
index f733c72..f753868 100644
--- a/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceController.java
@@ -26,6 +26,7 @@
 import androidx.fragment.app.FragmentManager;
 import androidx.preference.PreferenceScreen;
 
+import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.deletionhelper.ActivationWarningFragment;
 import com.android.settings.overlay.FeatureFactory;
@@ -66,6 +67,9 @@
 
     @Override
     public int getAvailabilityStatus() {
+        if (!mContext.getResources().getBoolean(R.bool.config_show_smart_storage_toggle)) {
+            return UNSUPPORTED_ON_DEVICE;
+        }
         return !ActivityManager.isLowRamDeviceStatic() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
     }
 
@@ -108,4 +112,4 @@
 
         return true;
     }
-}
\ No newline at end of file
+}
diff --git a/src/com/android/settings/deviceinfo/storage/EmptyTrashFragment.java b/src/com/android/settings/deviceinfo/storage/EmptyTrashFragment.java
new file mode 100644
index 0000000..da7b9ba
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/storage/EmptyTrashFragment.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2021 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.deviceinfo.storage;
+
+import android.app.Dialog;
+import android.app.settings.SettingsEnums;
+import android.os.Bundle;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.Fragment;
+
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+
+/**
+ * Dialog asks if users want to empty trash files.
+ */
+public class EmptyTrashFragment extends InstrumentedDialogFragment {
+    private static final String TAG_EMPTY_TRASH = "empty_trash";
+
+    /** Shows the empty trash dialog. */
+    public static void show(Fragment parent) {
+        final EmptyTrashFragment dialog = new EmptyTrashFragment();
+        dialog.setTargetFragment(parent, 0 /* requestCode */);
+        dialog.show(parent.getFragmentManager(), TAG_EMPTY_TRASH);
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.DIALOG_EMPTY_TRASH;
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+        return builder.setTitle(R.string.storage_trash_dialog_title)
+                .setMessage(R.string.storage_trash_dialog_ask_message)
+                .setPositiveButton(R.string.storage_trash_dialog_confirm, (dialog, which) -> {
+                    // TODO(170918505): Implement the logic in worker thread.
+                }).setNegativeButton(android.R.string.cancel, null)
+                .create();
+    }
+}
diff --git a/src/com/android/settings/deviceinfo/storage/StorageEntry.java b/src/com/android/settings/deviceinfo/storage/StorageEntry.java
index f718116..9ea0292 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageEntry.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageEntry.java
@@ -236,6 +236,14 @@
         return mVolumeInfo == null ? false : mVolumeInfo.getType() == VolumeInfo.TYPE_PUBLIC;
     }
 
+    /**
+     * Stub volume is a volume that is maintained by external party such as the ChromeOS processes
+     * in ARC++.
+     */
+    public boolean isStub() {
+        return mVolumeInfo == null ? false : mVolumeInfo.getType() == VolumeInfo.TYPE_STUB;
+    }
+
     /** Returns description. */
     public String getDescription() {
         if (isVolumeInfo()) {
diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
index e007090..e5259f9 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
@@ -19,12 +19,13 @@
 import static com.android.settings.dashboard.profileselector.ProfileSelectFragment.PERSONAL_TAB;
 import static com.android.settings.dashboard.profileselector.ProfileSelectFragment.WORK_TAB;
 
-import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
 import android.net.TrafficStats;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -53,6 +54,8 @@
 import com.android.settingslib.deviceinfo.StorageVolumeProvider;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 
@@ -67,20 +70,33 @@
     private static final String SYSTEM_FRAGMENT_TAG = "SystemInfo";
 
     @VisibleForTesting
-    static final String PHOTO_KEY = "pref_photos_videos";
+    static final String PUBLIC_STORAGE_KEY = "pref_public_storage";
     @VisibleForTesting
-    static final String AUDIO_KEY = "pref_music_audio";
+    static final String IMAGES_KEY = "pref_images";
     @VisibleForTesting
-    static final String GAME_KEY = "pref_games";
+    static final String VIDEOS_KEY = "pref_videos";
     @VisibleForTesting
-    static final String MOVIES_KEY = "pref_movies";
+    static final String AUDIOS_KEY = "pref_audios";
     @VisibleForTesting
-    static final String OTHER_APPS_KEY = "pref_other_apps";
+    static final String APPS_KEY = "pref_apps";
+    @VisibleForTesting
+    static final String GAMES_KEY = "pref_games";
+    @VisibleForTesting
+    static final String DOCUMENTS_AND_OTHER_KEY = "pref_documents_and_other";
     @VisibleForTesting
     static final String SYSTEM_KEY = "pref_system";
     @VisibleForTesting
-    static final String FILES_KEY = "pref_files";
+    static final String TRASH_KEY = "pref_trash";
 
+    private final Uri mImagesUri;
+    private final Uri mVideosUri;
+    private final Uri mAudiosUri;
+    private final Uri mDocumentsAndOtherUri;
+
+    // This value should align with the design of storage_dashboard_fragment.xml
+    private static final int LAST_STORAGE_CATEGORY_PREFERENCE_ORDER = 200;
+
+    private PackageManager mPackageManager;
     private final Fragment mFragment;
     private final MetricsFeatureProvider mMetricsFeatureProvider;
     private final StorageVolumeProvider mSvp;
@@ -89,14 +105,27 @@
     private long mUsedBytes;
     private long mTotalSize;
 
+    private List<StorageItemPreference> mPrivateStorageItemPreferences;
     private PreferenceScreen mScreen;
-    private StorageItemPreference mPhotoPreference;
-    private StorageItemPreference mAudioPreference;
-    private StorageItemPreference mGamePreference;
-    private StorageItemPreference mMoviesPreference;
-    private StorageItemPreference mAppPreference;
-    private StorageItemPreference mFilePreference;
-    private StorageItemPreference mSystemPreference;
+    @VisibleForTesting
+    Preference mPublicStoragePreference;
+    @VisibleForTesting
+    StorageItemPreference mImagesPreference;
+    @VisibleForTesting
+    StorageItemPreference mVideosPreference;
+    @VisibleForTesting
+    StorageItemPreference mAudiosPreference;
+    @VisibleForTesting
+    StorageItemPreference mAppsPreference;
+    @VisibleForTesting
+    StorageItemPreference mGamesPreference;
+    @VisibleForTesting
+    StorageItemPreference mDocumentsAndOtherPreference;
+    @VisibleForTesting
+    StorageItemPreference mSystemPreference;
+    @VisibleForTesting
+    StorageItemPreference mTrashPreference;
+
     private boolean mIsWorkProfile;
 
     private static final String AUTHORITY_MEDIA = "com.android.providers.media.documents";
@@ -104,11 +133,21 @@
     public StorageItemPreferenceController(
             Context context, Fragment hostFragment, VolumeInfo volume, StorageVolumeProvider svp) {
         super(context);
+        mPackageManager = context.getPackageManager();
         mFragment = hostFragment;
         mVolume = volume;
         mSvp = svp;
         mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
         mUserId = UserHandle.myUserId();
+
+        mImagesUri = Uri.parse(context.getResources()
+                .getString(R.string.config_images_storage_category_uri));
+        mVideosUri = Uri.parse(context.getResources()
+                .getString(R.string.config_videos_storage_category_uri));
+        mAudiosUri = Uri.parse(context.getResources()
+                .getString(R.string.config_audios_storage_category_uri));
+        mDocumentsAndOtherUri = Uri.parse(context.getResources()
+                .getString(R.string.config_documents_and_other_storage_category_uri));
     }
 
     public StorageItemPreferenceController(
@@ -128,57 +167,42 @@
 
     @Override
     public boolean handlePreferenceTreeClick(Preference preference) {
-        if (preference == null) {
-            return false;
-        }
-
-        Intent intent = null;
         if (preference.getKey() == null) {
             return false;
         }
         switch (preference.getKey()) {
-            case PHOTO_KEY:
-                intent = getPhotosIntent();
-                break;
-            case AUDIO_KEY:
-                intent = getAudioIntent();
-                break;
-            case GAME_KEY:
-                intent = getGamesIntent();
-                break;
-            case MOVIES_KEY:
-                intent = getMoviesIntent();
-                break;
-            case OTHER_APPS_KEY:
-                // Because we are likely constructed with a null volume, this is theoretically
-                // possible.
-                if (mVolume == null) {
-                    break;
-                }
-                intent = getAppsIntent();
-                break;
-            case FILES_KEY:
-                if (mVolume == null) {
-                    break;
-                }
-                intent = getFilesIntent();
-                FeatureFactory.getFactory(mContext).getMetricsFeatureProvider().action(
-                        mContext, SettingsEnums.STORAGE_FILES);
-                break;
+            case PUBLIC_STORAGE_KEY:
+                launchPublicStorageIntent();
+                return true;
+            case IMAGES_KEY:
+                launchImagesIntent();
+                return true;
+            case VIDEOS_KEY:
+                launchVideosIntent();
+                return true;
+            case AUDIOS_KEY:
+                launchAudiosIntent();
+                return true;
+            case APPS_KEY:
+                launchAppsIntent();
+                return true;
+            case GAMES_KEY:
+                launchGamesIntent();
+                return true;
+            case DOCUMENTS_AND_OTHER_KEY:
+                launchDocumentsAndOtherIntent();
+                return true;
             case SYSTEM_KEY:
                 final SystemInfoFragment dialog = new SystemInfoFragment();
                 dialog.setTargetFragment(mFragment, 0);
                 dialog.show(mFragment.getFragmentManager(), SYSTEM_FRAGMENT_TAG);
                 return true;
+            case TRASH_KEY:
+                launchTrashIntent();
+                return true;
+            default:
+                // Do nothing.
         }
-
-        if (intent != null) {
-            intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
-
-            Utils.launchIntent(mFragment, intent);
-            return true;
-        }
-
         return super.handlePreferenceTreeClick(preference);
     }
 
@@ -192,57 +216,106 @@
      */
     public void setVolume(VolumeInfo volume) {
         mVolume = volume;
+
         updateCategoryPreferencesVisibility();
+        updatePrivateStorageCategoryPreferencesOrder();
     }
 
-    private void updateCategoryPreferencesVisibility() {
-        // Stats data is only available on private volumes.
-        final boolean isValidVolume = mVolume != null
+    // Stats data is only available on private volumes.
+    private boolean isValidPrivateVolume() {
+        return mVolume != null
                 && mVolume.getType() == VolumeInfo.TYPE_PRIVATE
                 && (mVolume.getState() == VolumeInfo.STATE_MOUNTED
                 || mVolume.getState() == VolumeInfo.STATE_MOUNTED_READ_ONLY);
-
-        mPhotoPreference.setVisible(isValidVolume);
-        mAudioPreference.setVisible(isValidVolume);
-        mGamePreference.setVisible(isValidVolume);
-        mMoviesPreference.setVisible(isValidVolume);
-        mAppPreference.setVisible(isValidVolume);
-        mFilePreference.setVisible(isValidVolume);
-        mSystemPreference.setVisible(isValidVolume);
-
-        if (isValidVolume) {
-            setFilesPreferenceVisibility();
-        }
     }
 
-    private void setFilesPreferenceVisibility() {
-        if (mScreen != null) {
+    private boolean isValidPublicVolume() {
+        return mVolume != null
+                && (mVolume.getType() == VolumeInfo.TYPE_PUBLIC
+                || mVolume.getType() == VolumeInfo.TYPE_STUB)
+                && (mVolume.getState() == VolumeInfo.STATE_MOUNTED
+                || mVolume.getState() == VolumeInfo.STATE_MOUNTED_READ_ONLY);
+    }
+
+    private void updateCategoryPreferencesVisibility() {
+        if (mScreen == null) {
+            return;
+        }
+
+        mPublicStoragePreference.setVisible(isValidPublicVolume());
+
+        final boolean privateStoragePreferencesVisible = isValidPrivateVolume();
+        mImagesPreference.setVisible(privateStoragePreferencesVisible);
+        mVideosPreference.setVisible(privateStoragePreferencesVisible);
+        mAudiosPreference.setVisible(privateStoragePreferencesVisible);
+        mAppsPreference.setVisible(privateStoragePreferencesVisible);
+        mGamesPreference.setVisible(privateStoragePreferencesVisible);
+        mDocumentsAndOtherPreference.setVisible(privateStoragePreferencesVisible);
+        mSystemPreference.setVisible(privateStoragePreferencesVisible);
+        // TODO(b/170918505): Shows trash category after trash category feature complete.
+        mTrashPreference.setVisible(false);
+
+        if (privateStoragePreferencesVisible) {
             final VolumeInfo sharedVolume = mSvp.findEmulatedForPrivate(mVolume);
             // If we don't have a shared volume for our internal storage (or the shared volume isn't
             // mounted as readable for whatever reason), we should hide the File preference.
-            final boolean hideFilePreference =
-                    (sharedVolume == null) || !sharedVolume.isMountedReadable();
-            if (hideFilePreference) {
-                mScreen.removePreference(mFilePreference);
-            } else {
-                mScreen.addPreference(mFilePreference);
+            if (sharedVolume == null || !sharedVolume.isMountedReadable()) {
+                mDocumentsAndOtherPreference.setVisible(false);
             }
         }
     }
 
+    private void updatePrivateStorageCategoryPreferencesOrder() {
+        if (mScreen == null || !isValidPrivateVolume()) {
+            return;
+        }
+
+        if (mPrivateStorageItemPreferences == null) {
+            mPrivateStorageItemPreferences = new ArrayList<>();
+
+            mPrivateStorageItemPreferences.add(mImagesPreference);
+            mPrivateStorageItemPreferences.add(mVideosPreference);
+            mPrivateStorageItemPreferences.add(mAudiosPreference);
+            mPrivateStorageItemPreferences.add(mAppsPreference);
+            mPrivateStorageItemPreferences.add(mGamesPreference);
+            mPrivateStorageItemPreferences.add(mDocumentsAndOtherPreference);
+            mPrivateStorageItemPreferences.add(mSystemPreference);
+            mPrivateStorageItemPreferences.add(mTrashPreference);
+        }
+        mScreen.removePreference(mImagesPreference);
+        mScreen.removePreference(mVideosPreference);
+        mScreen.removePreference(mAudiosPreference);
+        mScreen.removePreference(mAppsPreference);
+        mScreen.removePreference(mGamesPreference);
+        mScreen.removePreference(mDocumentsAndOtherPreference);
+        mScreen.removePreference(mSystemPreference);
+        mScreen.removePreference(mTrashPreference);
+
+        // Sort display order by size.
+        Collections.sort(mPrivateStorageItemPreferences,
+                Comparator.comparingLong(StorageItemPreference::getStorageSize));
+        int orderIndex = LAST_STORAGE_CATEGORY_PREFERENCE_ORDER;
+        for (StorageItemPreference preference : mPrivateStorageItemPreferences) {
+            preference.setOrder(orderIndex--);
+            mScreen.addPreference(preference);
+        }
+    }
+
     /**
      * Sets the user id for which this preference controller is handling.
      */
     public void setUserId(UserHandle userHandle) {
         mUserId = userHandle.getIdentifier();
 
-        tintPreference(mPhotoPreference);
-        tintPreference(mMoviesPreference);
-        tintPreference(mAudioPreference);
-        tintPreference(mGamePreference);
-        tintPreference(mAppPreference);
+        tintPreference(mPublicStoragePreference);
+        tintPreference(mImagesPreference);
+        tintPreference(mVideosPreference);
+        tintPreference(mAudiosPreference);
+        tintPreference(mAppsPreference);
+        tintPreference(mGamesPreference);
+        tintPreference(mDocumentsAndOtherPreference);
         tintPreference(mSystemPreference);
-        tintPreference(mFilePreference);
+        tintPreference(mTrashPreference);
     }
 
     private void tintPreference(Preference preference) {
@@ -263,15 +336,18 @@
     @Override
     public void displayPreference(PreferenceScreen screen) {
         mScreen = screen;
-        mPhotoPreference = screen.findPreference(PHOTO_KEY);
-        mAudioPreference = screen.findPreference(AUDIO_KEY);
-        mGamePreference = screen.findPreference(GAME_KEY);
-        mMoviesPreference = screen.findPreference(MOVIES_KEY);
-        mAppPreference = screen.findPreference(OTHER_APPS_KEY);
+        mPublicStoragePreference = screen.findPreference(PUBLIC_STORAGE_KEY);
+        mImagesPreference = screen.findPreference(IMAGES_KEY);
+        mVideosPreference = screen.findPreference(VIDEOS_KEY);
+        mAudiosPreference = screen.findPreference(AUDIOS_KEY);
+        mAppsPreference = screen.findPreference(APPS_KEY);
+        mGamesPreference = screen.findPreference(GAMES_KEY);
+        mDocumentsAndOtherPreference = screen.findPreference(DOCUMENTS_AND_OTHER_KEY);
         mSystemPreference = screen.findPreference(SYSTEM_KEY);
-        mFilePreference = screen.findPreference(FILES_KEY);
+        mTrashPreference = screen.findPreference(TRASH_KEY);
 
         updateCategoryPreferencesVisibility();
+        updatePrivateStorageCategoryPreferencesOrder();
     }
 
     public void onLoadFinished(SparseArray<StorageAsyncLoader.AppsStorageResult> result,
@@ -280,12 +356,14 @@
         final StorageAsyncLoader.AppsStorageResult profileData = result.get(
                 Utils.getManagedProfileId(mContext.getSystemService(UserManager.class), userId));
 
-        mPhotoPreference.setStorageSize(getPhotosSize(data, profileData), mTotalSize);
-        mAudioPreference.setStorageSize(getAudioSize(data, profileData), mTotalSize);
-        mGamePreference.setStorageSize(getGamesSize(data, profileData), mTotalSize);
-        mMoviesPreference.setStorageSize(getMoviesSize(data, profileData), mTotalSize);
-        mAppPreference.setStorageSize(getAppsSize(data, profileData), mTotalSize);
-        mFilePreference.setStorageSize(getFilesSize(data, profileData), mTotalSize);
+        mImagesPreference.setStorageSize(getImagesSize(data, profileData), mTotalSize);
+        mVideosPreference.setStorageSize(getVideosSize(data, profileData), mTotalSize);
+        mAudiosPreference.setStorageSize(getAudiosSize(data, profileData), mTotalSize);
+        mAppsPreference.setStorageSize(getAppsSize(data, profileData), mTotalSize);
+        mGamesPreference.setStorageSize(getGamesSize(data, profileData), mTotalSize);
+        mDocumentsAndOtherPreference.setStorageSize(getDocumentsAndOtherSize(data, profileData),
+                mTotalSize);
+        mTrashPreference.setStorageSize(getTrashSize(data, profileData), mTotalSize);
 
         if (mSystemPreference != null) {
             // Everything else that hasn't already been attributed is tracked as
@@ -306,6 +384,8 @@
             final long systemSize = Math.max(TrafficStats.GB_IN_BYTES, mUsedBytes - attributedSize);
             mSystemPreference.setStorageSize(systemSize, mTotalSize);
         }
+
+        updatePrivateStorageCategoryPreferencesOrder();
     }
 
     public void setUsedSize(long usedSizeBytes) {
@@ -316,37 +396,39 @@
         mTotalSize = totalSizeBytes;
     }
 
-    /**
-     * Returns a list of keys used by this preference controller.
-     */
-    public static List<String> getUsedKeys() {
-        List<String> list = new ArrayList<>();
-        list.add(PHOTO_KEY);
-        list.add(AUDIO_KEY);
-        list.add(GAME_KEY);
-        list.add(MOVIES_KEY);
-        list.add(OTHER_APPS_KEY);
-        list.add(SYSTEM_KEY);
-        list.add(FILES_KEY);
-        return list;
+    private void launchPublicStorageIntent() {
+        final Intent intent = mVolume.buildBrowseIntent();
+        if (intent != null) {
+            mContext.startActivity(intent);
+        }
     }
 
-    private Intent getPhotosIntent() {
-        Bundle args = getWorkAnnotatedBundle(2);
-        args.putString(
-                ManageApplications.EXTRA_CLASSNAME, Settings.PhotosStorageActivity.class.getName());
-        args.putInt(
-                ManageApplications.EXTRA_STORAGE_TYPE,
-                ManageApplications.STORAGE_TYPE_PHOTOS_VIDEOS);
-        return new SubSettingLauncher(mContext)
-                .setDestination(ManageApplications.class.getName())
-                .setTitleRes(R.string.storage_photos_videos)
-                .setArguments(args)
-                .setSourceMetricsCategory(mMetricsFeatureProvider.getMetricsCategory(mFragment))
-                .toIntent();
+    // TODO(b/183078080): To simplify StorageItemPreferenceController, move launchxxxIntent to a
+    //                    utility object.
+    private void launchImagesIntent() {
+        Intent intent = new Intent(Intent.ACTION_VIEW);
+        intent.setData(mImagesUri);
+
+        if (intent.resolveActivity(mPackageManager) == null) {
+            final Bundle args = getWorkAnnotatedBundle(2);
+            args.putString(ManageApplications.EXTRA_CLASSNAME,
+                    Settings.PhotosStorageActivity.class.getName());
+            args.putInt(ManageApplications.EXTRA_STORAGE_TYPE,
+                    ManageApplications.STORAGE_TYPE_PHOTOS_VIDEOS);
+            intent = new SubSettingLauncher(mContext)
+                    .setDestination(ManageApplications.class.getName())
+                    .setTitleRes(R.string.storage_photos_videos)
+                    .setArguments(args)
+                    .setSourceMetricsCategory(mMetricsFeatureProvider.getMetricsCategory(mFragment))
+                    .toIntent();
+            intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
+            Utils.launchIntent(mFragment, intent);
+        } else {
+            mContext.startActivity(intent);
+        }
     }
 
-    private long getPhotosSize(StorageAsyncLoader.AppsStorageResult data,
+    private long getImagesSize(StorageAsyncLoader.AppsStorageResult data,
             StorageAsyncLoader.AppsStorageResult profileData) {
         if (profileData != null) {
             return data.photosAppsSize + data.externalStats.imageBytes
@@ -359,26 +441,62 @@
         }
     }
 
-    private Intent getAudioIntent() {
-        if (mVolume == null) {
-            return null;
-        }
+    private void launchVideosIntent() {
+        Intent intent = new Intent(Intent.ACTION_VIEW);
+        intent.setData(mVideosUri);
 
-        Bundle args = getWorkAnnotatedBundle(4);
-        args.putString(ManageApplications.EXTRA_CLASSNAME,
-                Settings.StorageUseActivity.class.getName());
-        args.putString(ManageApplications.EXTRA_VOLUME_UUID, mVolume.getFsUuid());
-        args.putString(ManageApplications.EXTRA_VOLUME_NAME, mVolume.getDescription());
-        args.putInt(ManageApplications.EXTRA_STORAGE_TYPE, ManageApplications.STORAGE_TYPE_MUSIC);
-        return new SubSettingLauncher(mContext)
-                .setDestination(ManageApplications.class.getName())
-                .setTitleRes(R.string.storage_music_audio)
-                .setArguments(args)
-                .setSourceMetricsCategory(mMetricsFeatureProvider.getMetricsCategory(mFragment))
-                .toIntent();
+        if (intent.resolveActivity(mPackageManager) == null) {
+            final Bundle args = getWorkAnnotatedBundle(1);
+            args.putString(ManageApplications.EXTRA_CLASSNAME,
+                    Settings.MoviesStorageActivity.class.getName());
+            intent = new SubSettingLauncher(mContext)
+                    .setDestination(ManageApplications.class.getName())
+                    .setTitleRes(R.string.storage_movies_tv)
+                    .setArguments(args)
+                    .setSourceMetricsCategory(mMetricsFeatureProvider.getMetricsCategory(mFragment))
+                    .toIntent();
+            intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
+            Utils.launchIntent(mFragment, intent);
+        } else {
+            mContext.startActivity(intent);
+        }
     }
 
-    private long getAudioSize(StorageAsyncLoader.AppsStorageResult data,
+    private long getVideosSize(StorageAsyncLoader.AppsStorageResult data,
+            StorageAsyncLoader.AppsStorageResult profileData) {
+        if (profileData != null) {
+            return data.videoAppsSize + profileData.videoAppsSize;
+        } else {
+            return data.videoAppsSize;
+        }
+    }
+
+    private void launchAudiosIntent() {
+        Intent intent = new Intent(Intent.ACTION_VIEW);
+        intent.setData(mAudiosUri);
+
+        if (intent.resolveActivity(mPackageManager) == null) {
+            final Bundle args = getWorkAnnotatedBundle(4);
+            args.putString(ManageApplications.EXTRA_CLASSNAME,
+                    Settings.StorageUseActivity.class.getName());
+            args.putString(ManageApplications.EXTRA_VOLUME_UUID, mVolume.getFsUuid());
+            args.putString(ManageApplications.EXTRA_VOLUME_NAME, mVolume.getDescription());
+            args.putInt(ManageApplications.EXTRA_STORAGE_TYPE,
+                    ManageApplications.STORAGE_TYPE_MUSIC);
+            intent = new SubSettingLauncher(mContext)
+                    .setDestination(ManageApplications.class.getName())
+                    .setTitleRes(R.string.storage_music_audio)
+                    .setArguments(args)
+                    .setSourceMetricsCategory(mMetricsFeatureProvider.getMetricsCategory(mFragment))
+                    .toIntent();
+            intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
+            Utils.launchIntent(mFragment, intent);
+        } else {
+            mContext.startActivity(intent);
+        }
+    }
+
+    private long getAudiosSize(StorageAsyncLoader.AppsStorageResult data,
             StorageAsyncLoader.AppsStorageResult profileData) {
         if (profileData != null) {
             return data.musicAppsSize + data.externalStats.audioBytes
@@ -388,21 +506,20 @@
         }
     }
 
-    private Intent getAppsIntent() {
-        if (mVolume == null) {
-            return null;
-        }
+    private void launchAppsIntent() {
         final Bundle args = getWorkAnnotatedBundle(3);
         args.putString(ManageApplications.EXTRA_CLASSNAME,
                 Settings.StorageUseActivity.class.getName());
         args.putString(ManageApplications.EXTRA_VOLUME_UUID, mVolume.getFsUuid());
         args.putString(ManageApplications.EXTRA_VOLUME_NAME, mVolume.getDescription());
-        return new SubSettingLauncher(mContext)
+        final Intent intent = new SubSettingLauncher(mContext)
                 .setDestination(ManageApplications.class.getName())
                 .setTitleRes(R.string.apps_storage)
                 .setArguments(args)
                 .setSourceMetricsCategory(mMetricsFeatureProvider.getMetricsCategory(mFragment))
                 .toIntent();
+        intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
+        Utils.launchIntent(mFragment, intent);
     }
 
     private long getAppsSize(StorageAsyncLoader.AppsStorageResult data,
@@ -414,16 +531,18 @@
         }
     }
 
-    private Intent getGamesIntent() {
+    private void launchGamesIntent() {
         final Bundle args = getWorkAnnotatedBundle(1);
         args.putString(ManageApplications.EXTRA_CLASSNAME,
                 Settings.GamesStorageActivity.class.getName());
-        return new SubSettingLauncher(mContext)
+        final Intent intent = new SubSettingLauncher(mContext)
                 .setDestination(ManageApplications.class.getName())
                 .setTitleRes(R.string.game_storage_settings)
                 .setArguments(args)
                 .setSourceMetricsCategory(mMetricsFeatureProvider.getMetricsCategory(mFragment))
                 .toIntent();
+        intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
+        Utils.launchIntent(mFragment, intent);
     }
 
     private long getGamesSize(StorageAsyncLoader.AppsStorageResult data,
@@ -435,27 +554,6 @@
         }
     }
 
-    private Intent getMoviesIntent() {
-        final Bundle args = getWorkAnnotatedBundle(1);
-        args.putString(ManageApplications.EXTRA_CLASSNAME,
-                Settings.MoviesStorageActivity.class.getName());
-        return new SubSettingLauncher(mContext)
-                .setDestination(ManageApplications.class.getName())
-                .setTitleRes(R.string.storage_movies_tv)
-                .setArguments(args)
-                .setSourceMetricsCategory(mMetricsFeatureProvider.getMetricsCategory(mFragment))
-                .toIntent();
-    }
-
-    private long getMoviesSize(StorageAsyncLoader.AppsStorageResult data,
-            StorageAsyncLoader.AppsStorageResult profileData) {
-        if (profileData != null) {
-            return data.videoAppsSize + profileData.videoAppsSize;
-        } else {
-            return data.videoAppsSize;
-        }
-    }
-
     private Bundle getWorkAnnotatedBundle(int additionalCapacity) {
         final Bundle args = new Bundle(1 + additionalCapacity);
         args.putInt(SettingsActivity.EXTRA_SHOW_FRAGMENT_TAB,
@@ -463,11 +561,20 @@
         return args;
     }
 
-    private Intent getFilesIntent() {
-        return mSvp.findEmulatedForPrivate(mVolume).buildBrowseIntent();
+    private void launchDocumentsAndOtherIntent() {
+        Intent intent = new Intent(Intent.ACTION_VIEW);
+        intent.setData(mDocumentsAndOtherUri);
+
+        if (intent.resolveActivity(mPackageManager) == null) {
+            intent = mSvp.findEmulatedForPrivate(mVolume).buildBrowseIntent();
+            intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
+            Utils.launchIntent(mFragment, intent);
+        } else {
+            mContext.startActivity(intent);
+        }
     }
 
-    private long getFilesSize(StorageAsyncLoader.AppsStorageResult data,
+    private long getDocumentsAndOtherSize(StorageAsyncLoader.AppsStorageResult data,
             StorageAsyncLoader.AppsStorageResult profileData) {
         if (profileData != null) {
             return data.externalStats.totalBytes
@@ -489,6 +596,22 @@
         }
     }
 
+    private void launchTrashIntent() {
+        final Intent intent = new Intent("android.settings.VIEW_TRASH");
+
+        if (intent.resolveActivity(mPackageManager) == null) {
+            EmptyTrashFragment.show(mFragment);
+        } else {
+            mContext.startActivity(intent);
+        }
+    }
+
+    private long getTrashSize(StorageAsyncLoader.AppsStorageResult data,
+            StorageAsyncLoader.AppsStorageResult profileData) {
+        // TODO(170918505): Implement it.
+        return 0L;
+    }
+
     private static long totalValues(StorageMeasurement.MeasurementDetails details, int userId,
             String... keys) {
         long total = 0;
diff --git a/src/com/android/settings/display/AdaptiveSleepPreferenceController.java b/src/com/android/settings/display/AdaptiveSleepPreferenceController.java
index e0527f9..c16b95c 100644
--- a/src/com/android/settings/display/AdaptiveSleepPreferenceController.java
+++ b/src/com/android/settings/display/AdaptiveSleepPreferenceController.java
@@ -60,7 +60,6 @@
         mPreference = new RestrictedSwitchPreference(context);
         mPreference.setTitle(R.string.adaptive_sleep_title);
         mPreference.setSummary(R.string.adaptive_sleep_description);
-        mPreference.setIcon(R.drawable.empty_icon);
         mPreference.setChecked(isChecked());
         mPreference.setKey(PREFERENCE_KEY);
         mPreference.setOnPreferenceClickListener(preference -> {
diff --git a/src/com/android/settings/display/ScreenTimeoutSettings.java b/src/com/android/settings/display/ScreenTimeoutSettings.java
index 3b0d333..a15a7a0 100644
--- a/src/com/android/settings/display/ScreenTimeoutSettings.java
+++ b/src/com/android/settings/display/ScreenTimeoutSettings.java
@@ -164,7 +164,8 @@
         final String textMoreDetails = getResources().getString(R.string.admin_more_details);
 
         final SpannableString spannableString = new SpannableString(
-                textDisabledByAdmin + System.lineSeparator() + textMoreDetails);
+                textDisabledByAdmin + System.lineSeparator()
+                + System.lineSeparator() + textMoreDetails);
         final ClickableSpan clickableSpan = new ClickableSpan() {
             @Override
             public void onClick(@NonNull View widget) {
@@ -174,7 +175,7 @@
 
         if (textDisabledByAdmin != null && textMoreDetails != null) {
             spannableString.setSpan(clickableSpan, textDisabledByAdmin.length() + 1,
-                    textDisabledByAdmin.length() + textMoreDetails.length() + 1,
+                    textDisabledByAdmin.length() + textMoreDetails.length() + 2,
                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
         }
 
diff --git a/src/com/android/settings/emergency/MoreSettingsPreferenceController.java b/src/com/android/settings/emergency/MoreSettingsPreferenceController.java
new file mode 100644
index 0000000..34c11c7
--- /dev/null
+++ b/src/com/android/settings/emergency/MoreSettingsPreferenceController.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2021 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.emergency;
+
+import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
+import static android.content.pm.PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
+import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.widget.LayoutPreference;
+
+import java.util.List;
+
+/**
+ * Preference controller for More settings button
+ */
+public class MoreSettingsPreferenceController extends BasePreferenceController implements
+        View.OnClickListener {
+
+    private static final String EXTRA_KEY_ATTRIBUTION = "attribution";
+    private static final String TAG = "MoreSettingsPrefCtrl";
+    @VisibleForTesting
+    Intent mIntent;
+
+    public MoreSettingsPreferenceController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+        final String packageName = mContext.getResources().getString(
+                R.string.config_emergency_package_name);
+
+        if (TextUtils.isEmpty(packageName)) {
+            return;
+        }
+        mIntent = new Intent(Intent.ACTION_MAIN)
+                .setPackage(packageName);
+
+        final List<ResolveInfo> info = mContext.getPackageManager()
+                .queryIntentActivities(mIntent, MATCH_SYSTEM_ONLY);
+
+        if (info != null && !info.isEmpty()) {
+            mIntent.setClassName(packageName, info.get(0).activityInfo.name);
+        } else {
+            mIntent = null;
+        }
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        final LayoutPreference pref = screen.findPreference(getPreferenceKey());
+        final Button button = pref.findViewById(R.id.button);
+        button.setText(getButtonText());
+        button.setOnClickListener(this);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        if (mIntent == null) {
+            return UNSUPPORTED_ON_DEVICE;
+        } else {
+            return AVAILABLE;
+        }
+    }
+
+    @Override
+    public void onClick(View v) {
+        final Intent intent = new Intent(mIntent)
+                .addCategory(Intent.CATEGORY_LAUNCHER)
+                .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        Bundle bundle = new Bundle();
+        bundle.putString(EXTRA_KEY_ATTRIBUTION, mContext.getPackageName());
+        mContext.startActivity(intent, bundle);
+    }
+
+    private CharSequence getButtonText() {
+        final String packageName = mContext.getResources().getString(
+                R.string.config_emergency_package_name);
+        try {
+            final PackageManager pm = mContext.getPackageManager();
+            final ApplicationInfo appInfo = pm.getApplicationInfo(
+                    packageName, MATCH_DISABLED_COMPONENTS
+                            | MATCH_DISABLED_UNTIL_USED_COMPONENTS);
+            return mContext.getString(R.string.open_app_button, appInfo.loadLabel(pm));
+        } catch (Exception e) {
+            Log.d(TAG, "Failed to get open app button text, falling back.");
+            return "";
+        }
+    }
+}
diff --git a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
index 47b2a0a..a55d0d3 100644
--- a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
@@ -257,6 +257,27 @@
         BatteryEntry.startRequestQueue();
     }
 
+    /**
+     * Gets the BatteryEntry list by using the supplied BatteryUsageStats.
+     */
+    public List<BatteryEntry> getBatteryEntryList(
+            BatteryUsageStats batteryUsageStats, boolean showAllApps) {
+        mBatteryUsageStats = USE_FAKE_DATA ? getFakeStats() : batteryUsageStats;
+        if (!sConfig.shouldShowBatteryAttributionList(mContext)) {
+            return null;
+        }
+        final int dischargePercentage = getDischargePercentage(batteryUsageStats);
+        final List<BatteryEntry> usageList = getCoalescedUsageList(showAllApps);
+        final double totalPower = batteryUsageStats.getConsumedPower();
+        for (int i = 0; i < usageList.size(); i++) {
+            final BatteryEntry entry = usageList.get(i);
+            final double percentOfTotal = mBatteryUtils.calculateBatteryPercent(
+                    entry.getConsumedPower(), totalPower, dischargePercentage);
+            entry.percent = percentOfTotal;
+        }
+        return usageList;
+    }
+
     private int getDischargePercentage(BatteryUsageStats batteryUsageStats) {
         int dischargePercentage = batteryUsageStats.getDischargePercentage();
         if (dischargePercentage < 0) {
@@ -311,7 +332,7 @@
             final int index = batteryEntryList.indexOfKey(realUid);
             if (index < 0) {
                 // New entry.
-                batteryEntryList.put(realUid, new BatteryEntry(mActivity, mHandler, mUserManager,
+                batteryEntryList.put(realUid, new BatteryEntry(mContext, mHandler, mUserManager,
                         consumer, isHidden, packages, null));
             } else {
                 // Combine BatterySippers if we already have one with this UID.
@@ -328,7 +349,7 @@
                 continue;
             }
 
-            results.add(new BatteryEntry(mActivity, mHandler, mUserManager,
+            results.add(new BatteryEntry(mContext, mHandler, mUserManager,
                     consumer, /* isHidden */ true, null, null));
         }
 
@@ -337,7 +358,7 @@
                     mBatteryUsageStats.getUserBatteryConsumers();
             for (int i = 0, size = userBatteryConsumers.size(); i < size; i++) {
                 final UserBatteryConsumer consumer = userBatteryConsumers.get(i);
-                results.add(new BatteryEntry(mActivity, mHandler, mUserManager,
+                results.add(new BatteryEntry(mContext, mHandler, mUserManager,
                         consumer, /* isHidden */ true, null, null));
             }
         }
diff --git a/src/com/android/settings/fuelgauge/BatteryEntry.java b/src/com/android/settings/fuelgauge/BatteryEntry.java
index 9fafefd..ed52f48 100644
--- a/src/com/android/settings/fuelgauge/BatteryEntry.java
+++ b/src/com/android/settings/fuelgauge/BatteryEntry.java
@@ -35,6 +35,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.Log;
+import android.util.Pair;
 
 import androidx.annotation.NonNull;
 
@@ -51,6 +52,19 @@
  * and icon image.
  */
 public class BatteryEntry {
+
+    public static final class NameAndIcon {
+        public final String name;
+        public final Drawable icon;
+        public final int iconId;
+
+        public NameAndIcon(String name, Drawable icon, int iconId) {
+            this.name = name;
+            this.icon = icon;
+            this.iconId = iconId;
+        }
+    }
+
     public static final int MSG_UPDATE_NAME_ICON = 1;
     public static final int MSG_REPORT_FULLY_DRAWN = 2;
 
@@ -154,9 +168,10 @@
         mBatteryConsumer = batteryConsumer;
         mIsHidden = isHidden;
         mDefaultPackageName = packageName;
-        mConsumedPower = batteryConsumer.getConsumedPower();
 
         if (batteryConsumer instanceof UidBatteryConsumer) {
+            mConsumedPower = batteryConsumer.getConsumedPower();
+
             UidBatteryConsumer uidBatteryConsumer = (UidBatteryConsumer) batteryConsumer;
             int uid = uidBatteryConsumer.getUid();
             if (mDefaultPackageName == null) {
@@ -182,59 +197,18 @@
             getQuickNameIconForUid(uid, packages);
             return;
         } else if (batteryConsumer instanceof SystemBatteryConsumer) {
-            switch(((SystemBatteryConsumer) batteryConsumer).getDrainType()) {
-                case SystemBatteryConsumer.DRAIN_TYPE_AMBIENT_DISPLAY:
-                    name = context.getResources().getString(R.string.ambient_display_screen_title);
-                    iconId = R.drawable.ic_settings_aod;
-                    break;
-                case SystemBatteryConsumer.DRAIN_TYPE_BLUETOOTH:
-                    name = context.getResources().getString(R.string.power_bluetooth);
-                    iconId = com.android.internal.R.drawable.ic_settings_bluetooth;
-                    break;
-                case SystemBatteryConsumer.DRAIN_TYPE_CAMERA:
-                    name = context.getResources().getString(R.string.power_camera);
-                    iconId = R.drawable.ic_settings_camera;
-                    break;
-                case SystemBatteryConsumer.DRAIN_TYPE_MOBILE_RADIO:
-                    name = context.getResources().getString(R.string.power_cell);
-                    iconId = R.drawable.ic_cellular_1_bar;
-                    break;
-                case SystemBatteryConsumer.DRAIN_TYPE_FLASHLIGHT:
-                    name = context.getResources().getString(R.string.power_flashlight);
-                    iconId = R.drawable.ic_settings_display;
-                    break;
-                case SystemBatteryConsumer.DRAIN_TYPE_PHONE:
-                    name = context.getResources().getString(R.string.power_phone);
-                    iconId = R.drawable.ic_settings_voice_calls;
-                    break;
-                case SystemBatteryConsumer.DRAIN_TYPE_SCREEN:
-                    name = context.getResources().getString(R.string.power_screen);
-                    iconId = R.drawable.ic_settings_display;
-                    break;
-                case SystemBatteryConsumer.DRAIN_TYPE_WIFI:
-                    name = context.getResources().getString(R.string.power_wifi);
-                    iconId = R.drawable.ic_settings_wireless;
-                    break;
-                case SystemBatteryConsumer.DRAIN_TYPE_IDLE:
-                case SystemBatteryConsumer.DRAIN_TYPE_MEMORY:
-                    name = context.getResources().getString(R.string.power_idle);
-                    iconId = R.drawable.ic_settings_phone_idle;
-                    break;
-                case SystemBatteryConsumer.DRAIN_TYPE_CUSTOM:
-                    name = null;
-                    iconId = R.drawable.ic_power_system;
-                    break;
-            }
+            mConsumedPower = batteryConsumer.getConsumedPower()
+                    - ((SystemBatteryConsumer) batteryConsumer).getPowerConsumedByApps();
+            final NameAndIcon nameAndIcon = getNameAndIconFromDrainType(
+                    context, ((SystemBatteryConsumer) batteryConsumer).getDrainType());
+            iconId = nameAndIcon.iconId;
+            name = nameAndIcon.name;
         } else if (batteryConsumer instanceof UserBatteryConsumer) {
-            UserInfo info = um.getUserInfo(((UserBatteryConsumer) batteryConsumer).getUserId());
-            if (info != null) {
-                icon = Utils.getUserIcon(context, um, info);
-                name = Utils.getUserLabel(context, info);
-            } else {
-                icon = null;
-                name = context.getResources().getString(
-                        R.string.running_process_item_removed_user_label);
-            }
+            mConsumedPower = batteryConsumer.getConsumedPower();
+            final NameAndIcon nameAndIcon = getNameAndIconFromUserId(
+                    context, ((UserBatteryConsumer) batteryConsumer).getUserId());
+            icon = nameAndIcon.icon;
+            name = nameAndIcon.name;
         }
 
         if (iconId != 0) {
@@ -271,15 +245,9 @@
         }
 
         if (packages == null || packages.length == 0) {
-            if (uid == 0) {
-                name = mContext.getResources().getString(R.string.process_kernel_label);
-            } else if ("mediaserver".equals(name)) {
-                name = mContext.getResources().getString(R.string.process_mediaserver_label);
-            } else if ("dex2oat".equals(name)) {
-                name = mContext.getResources().getString(R.string.process_dex2oat_label);
-            }
-            iconId = R.drawable.ic_power_system;
-            icon = mContext.getDrawable(iconId);
+            final NameAndIcon nameAndIcon = getNameAndIconFromUid(mContext, name, uid);
+            icon = nameAndIcon.icon;
+            name = nameAndIcon.name;
         } else {
             icon = mContext.getPackageManager().getDefaultActivityIcon();
         }
@@ -452,6 +420,13 @@
     }
 
     /**
+     * Returns the BatteryConsumer of the app described by this entry.
+     */
+    public BatteryConsumer getBatteryConsumer() {
+        return mBatteryConsumer;
+    }
+
+    /**
      * Returns foreground foreground time (in milliseconds) that is attributed to this entry.
      */
     public long getTimeInForegroundMs() {
@@ -493,4 +468,93 @@
                     ((UidBatteryConsumer) batteryConsumer).getPackageWithHighestDrain();
         }
     }
+
+    /**
+     * Gets name and icon resource from UserBatteryConsumer userId.
+     */
+    public static NameAndIcon getNameAndIconFromUserId(
+            Context context, final int userId) {
+        UserManager um = context.getSystemService(UserManager.class);
+        UserInfo info = um.getUserInfo(userId);
+
+        Drawable icon = null;
+        String name = null;
+        if (info != null) {
+            icon = Utils.getUserIcon(context, um, info);
+            name = Utils.getUserLabel(context, info);
+        } else {
+            name = context.getResources().getString(
+                    R.string.running_process_item_removed_user_label);
+        }
+        return new NameAndIcon(name, icon, 0 /* iconId */);
+    }
+
+    /**
+     * Gets name and icon resource from UidBatteryConsumer uid.
+     */
+    public static NameAndIcon getNameAndIconFromUid(
+            Context context, String name, final int uid) {
+        Drawable icon = context.getDrawable(R.drawable.ic_power_system);
+        if (uid == 0) {
+            name = context.getResources().getString(R.string.process_kernel_label);
+        } else if ("mediaserver".equals(name)) {
+            name = context.getResources().getString(R.string.process_mediaserver_label);
+        } else if ("dex2oat".equals(name)) {
+            name = context.getResources().getString(R.string.process_dex2oat_label);
+        }
+        return new NameAndIcon(name, icon, 0 /* iconId */);
+    }
+
+    /**
+     * Gets name annd icon resource from SystemBatteryConsumer drain type.
+     */
+    public static NameAndIcon getNameAndIconFromDrainType(
+            Context context, final int drainType) {
+        String name = null;
+        int iconId = 0;
+        switch (drainType) {
+            case SystemBatteryConsumer.DRAIN_TYPE_AMBIENT_DISPLAY:
+                name = context.getResources().getString(R.string.ambient_display_screen_title);
+                iconId = R.drawable.ic_settings_aod;
+                break;
+            case SystemBatteryConsumer.DRAIN_TYPE_BLUETOOTH:
+                name = context.getResources().getString(R.string.power_bluetooth);
+                iconId = com.android.internal.R.drawable.ic_settings_bluetooth;
+                break;
+            case SystemBatteryConsumer.DRAIN_TYPE_CAMERA:
+                name = context.getResources().getString(R.string.power_camera);
+                iconId = R.drawable.ic_settings_camera;
+                break;
+            case SystemBatteryConsumer.DRAIN_TYPE_MOBILE_RADIO:
+                name = context.getResources().getString(R.string.power_cell);
+                iconId = R.drawable.ic_cellular_1_bar;
+                break;
+            case SystemBatteryConsumer.DRAIN_TYPE_FLASHLIGHT:
+                name = context.getResources().getString(R.string.power_flashlight);
+                iconId = R.drawable.ic_settings_display;
+                break;
+            case SystemBatteryConsumer.DRAIN_TYPE_PHONE:
+                name = context.getResources().getString(R.string.power_phone);
+                iconId = R.drawable.ic_settings_voice_calls;
+                break;
+            case SystemBatteryConsumer.DRAIN_TYPE_SCREEN:
+                name = context.getResources().getString(R.string.power_screen);
+                iconId = R.drawable.ic_settings_display;
+                break;
+            case SystemBatteryConsumer.DRAIN_TYPE_WIFI:
+                name = context.getResources().getString(R.string.power_wifi);
+                iconId = R.drawable.ic_settings_wireless;
+                break;
+            case SystemBatteryConsumer.DRAIN_TYPE_IDLE:
+            case SystemBatteryConsumer.DRAIN_TYPE_MEMORY:
+                name = context.getResources().getString(R.string.power_idle);
+                iconId = R.drawable.ic_settings_phone_idle;
+                break;
+            case SystemBatteryConsumer.DRAIN_TYPE_CUSTOM:
+                name = null;
+                iconId = R.drawable.ic_power_system;
+                break;
+        }
+        return new NameAndIcon(name, null /* icon */, iconId);
+    }
 }
diff --git a/src/com/android/settings/fuelgauge/BatterySaverController.java b/src/com/android/settings/fuelgauge/BatterySaverController.java
index fba163d..15070c3 100644
--- a/src/com/android/settings/fuelgauge/BatterySaverController.java
+++ b/src/com/android/settings/fuelgauge/BatterySaverController.java
@@ -111,7 +111,7 @@
                             Utils.formatPercentage(percent)) :
                     mContext.getString(R.string.battery_saver_off_summary);
         } else {
-            return mContext.getString(R.string.battery_saver_auto_routine);
+            return mContext.getString(R.string.battery_saver_pref_auto_routine_summary);
         }
     }
 
diff --git a/src/com/android/settings/fuelgauge/BatterySettingsFeatureProvider.java b/src/com/android/settings/fuelgauge/BatterySettingsFeatureProvider.java
index 73b875b..11f28b7 100644
--- a/src/com/android/settings/fuelgauge/BatterySettingsFeatureProvider.java
+++ b/src/com/android/settings/fuelgauge/BatterySettingsFeatureProvider.java
@@ -24,6 +24,6 @@
     /**
      * Get replacement activity for a given activity or fragment path.
      */
-    String getReplacingActivityName(String activity);
+    String getReplacingActivityName(String originalActivity);
 
 }
diff --git a/src/com/android/settings/fuelgauge/BatterySettingsFeatureProviderImpl.java b/src/com/android/settings/fuelgauge/BatterySettingsFeatureProviderImpl.java
index e410695..218d096 100644
--- a/src/com/android/settings/fuelgauge/BatterySettingsFeatureProviderImpl.java
+++ b/src/com/android/settings/fuelgauge/BatterySettingsFeatureProviderImpl.java
@@ -16,13 +16,21 @@
 
 package com.android.settings.fuelgauge;
 
+import android.content.Context;
+
 /**
  * Feature provider implementation for battery settings usage.
  */
 public class BatterySettingsFeatureProviderImpl implements BatterySettingsFeatureProvider {
 
+    protected Context mContext;
+
+    public BatterySettingsFeatureProviderImpl(Context context) {
+        mContext = context.getApplicationContext();
+    }
+
     @Override
-    public String getReplacingActivityName(String activity) {
+    public String getReplacingActivityName(String originalActivity) {
         return null;
     }
 }
diff --git a/src/com/android/settings/fuelgauge/FakeUid.java b/src/com/android/settings/fuelgauge/FakeUid.java
index b49fb10..ee0d91f 100644
--- a/src/com/android/settings/fuelgauge/FakeUid.java
+++ b/src/com/android/settings/fuelgauge/FakeUid.java
@@ -366,6 +366,16 @@
     }
 
     @Override
+    public long getGnssMeasuredBatteryConsumptionUC() {
+        return 0;
+    }
+
+    @Override
+    public long getMobileRadioMeasuredBatteryConsumptionUC() {
+        return 0;
+    }
+
+    @Override
     public long getScreenOnMeasuredBatteryConsumptionUC() {
         return 0;
     }
diff --git a/src/com/android/settings/fuelgauge/SmartBatteryPreferenceController.java b/src/com/android/settings/fuelgauge/SmartBatteryPreferenceController.java
index ea277a1..27b70cb 100644
--- a/src/com/android/settings/fuelgauge/SmartBatteryPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/SmartBatteryPreferenceController.java
@@ -20,27 +20,23 @@
 import android.content.Context;
 import android.provider.Settings;
 import android.text.TextUtils;
-import android.widget.Switch;
 
 import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
 
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.widget.MainSwitchPreference;
-import com.android.settingslib.widget.OnMainSwitchChangeListener;
 
 /**
  * Controller to change and update the smart battery toggle
  */
 public class SmartBatteryPreferenceController extends BasePreferenceController implements
-        OnMainSwitchChangeListener {
+        Preference.OnPreferenceChangeListener {
 
     private static final String KEY_SMART_BATTERY = "smart_battery";
     private static final int ON = 1;
     private static final int OFF = 0;
     private PowerUsageFeatureProvider mPowerUsageFeatureProvider;
-    private MainSwitchPreference mPreference;
 
     public SmartBatteryPreferenceController(Context context) {
         super(context, KEY_SMART_BATTERY);
@@ -70,19 +66,14 @@
         super.updateState(preference);
         final boolean smartBatteryOn = Settings.Global.getInt(mContext.getContentResolver(),
                 Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED, ON) == ON;
-        ((MainSwitchPreference) preference).updateStatus(smartBatteryOn);
+        ((SwitchPreference) preference).setChecked(smartBatteryOn);
     }
 
     @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        mPreference = (MainSwitchPreference) screen.findPreference(getPreferenceKey());
-        mPreference.addOnSwitchChangeListener(this);
-    }
-
-    @Override
-    public void onSwitchChanged(Switch switchView, boolean isChecked) {
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        final boolean smartBatteryOn = (Boolean) newValue;
         Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED, isChecked ? ON : OFF);
+                Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED, smartBatteryOn ? ON : OFF);
+        return true;
     }
 }
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryManagerPreferenceController.java b/src/com/android/settings/fuelgauge/batterytip/BatteryManagerPreferenceController.java
index 9565036..790264c 100644
--- a/src/com/android/settings/fuelgauge/batterytip/BatteryManagerPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryManagerPreferenceController.java
@@ -19,7 +19,6 @@
 import android.app.AppOpsManager;
 import android.content.Context;
 import android.os.UserManager;
-import android.provider.Settings;
 
 import androidx.annotation.VisibleForTesting;
 import androidx.preference.Preference;
@@ -34,7 +33,6 @@
  */
 public class BatteryManagerPreferenceController extends BasePreferenceController {
     private static final String KEY_BATTERY_MANAGER = "smart_battery_manager";
-    private static final int ON = 1;
     private PowerUsageFeatureProvider mPowerUsageFeatureProvider;
     private AppOpsManager mAppOpsManager;
     private UserManager mUserManager;
@@ -56,24 +54,17 @@
     public void updateState(Preference preference) {
         super.updateState(preference);
         final int num = BatteryTipUtils.getRestrictedAppsList(mAppOpsManager, mUserManager).size();
-        final String setting = mPowerUsageFeatureProvider.isSmartBatterySupported()
-                ? Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED
-                : Settings.Global.APP_AUTO_RESTRICTION_ENABLED;
-        final boolean featureOn =
-                Settings.Global.getInt(mContext.getContentResolver(), setting, ON) == ON;
 
-        updateSummary(preference, featureOn, num);
+        updateSummary(preference, num);
     }
 
     @VisibleForTesting
-    void updateSummary(Preference preference, boolean featureOn, int num) {
+    void updateSummary(Preference preference, int num) {
         if (num > 0) {
             preference.setSummary(mContext.getResources().getQuantityString(
                     R.plurals.battery_manager_app_restricted, num, num));
-        } else if (featureOn) {
-            preference.setSummary(R.string.battery_manager_on);
         } else {
-            preference.setSummary(R.string.battery_manager_off);
+            preference.setSummary(R.string.battery_manager_summary);
         }
     }
 }
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java
index 1052afe..623bd4f 100644
--- a/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java
@@ -69,7 +69,8 @@
 
         tips.add(new LowBatteryDetector(context, policy, batteryInfo).detect());
         tips.add(new HighUsageDetector(context, policy, mBatteryUsageStats, batteryInfo).detect());
-        tips.add(new SmartBatteryDetector(policy, context.getContentResolver()).detect());
+        tips.add(new SmartBatteryDetector(
+                context, policy, batteryInfo, context.getContentResolver()).detect());
         tips.add(new EarlyWarningDetector(policy, context).detect());
         tips.add(new BatteryDefenderDetector(batteryInfo).detect());
         // Disable this feature now since it introduces false positive cases. We will try to improve
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipUtils.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipUtils.java
index e88a494..d12784f 100644
--- a/src/com/android/settings/fuelgauge/batterytip/BatteryTipUtils.java
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipUtils.java
@@ -30,7 +30,6 @@
 import com.android.settings.SettingsActivity;
 import com.android.settings.core.InstrumentedPreferenceFragment;
 import com.android.settings.fuelgauge.batterytip.actions.BatteryDefenderAction;
-import com.android.settings.fuelgauge.batterytip.actions.BatterySaverAction;
 import com.android.settings.fuelgauge.batterytip.actions.BatteryTipAction;
 import com.android.settings.fuelgauge.batterytip.actions.OpenBatterySaverAction;
 import com.android.settings.fuelgauge.batterytip.actions.OpenRestrictAppFragmentAction;
@@ -99,11 +98,7 @@
                 return new SmartBatteryAction(settingsActivity, fragment);
             case BatteryTip.TipType.BATTERY_SAVER:
             case BatteryTip.TipType.LOW_BATTERY:
-                if (batteryTip.getState() == BatteryTip.StateType.HANDLED) {
-                    return new OpenBatterySaverAction(settingsActivity);
-                } else {
-                    return new BatterySaverAction(settingsActivity);
-                }
+                return new OpenBatterySaverAction(settingsActivity);
             case BatteryTip.TipType.APP_RESTRICTION:
                 if (batteryTip.getState() == BatteryTip.StateType.HANDLED) {
                     return new OpenRestrictAppFragmentAction(fragment, (RestrictAppTip) batteryTip);
diff --git a/src/com/android/settings/fuelgauge/batterytip/detectors/EarlyWarningDetector.java b/src/com/android/settings/fuelgauge/batterytip/detectors/EarlyWarningDetector.java
index 9b6b9b5..f7a4f8c 100644
--- a/src/com/android/settings/fuelgauge/batterytip/detectors/EarlyWarningDetector.java
+++ b/src/com/android/settings/fuelgauge/batterytip/detectors/EarlyWarningDetector.java
@@ -56,7 +56,7 @@
                 EarlyWarningDetector.class.getName()) || mPolicy.testBatterySaverTip;
 
         final int state = powerSaveModeOn
-                ? BatteryTip.StateType.HANDLED
+                ? BatteryTip.StateType.INVISIBLE
                 : mPolicy.batterySaverTipEnabled && discharging && earlyWarning
                         ? BatteryTip.StateType.NEW
                         : BatteryTip.StateType.INVISIBLE;
diff --git a/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java b/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java
index ca9141d..75f47a7 100644
--- a/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java
+++ b/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java
@@ -49,16 +49,16 @@
         final boolean lowBattery = mBatteryInfo.batteryLevel <= mWarningLevel
                 || (mBatteryInfo.discharging && mBatteryInfo.remainingTimeUs != 0
                 && mBatteryInfo.remainingTimeUs < TimeUnit.HOURS.toMicros(mPolicy.lowBatteryHour));
+        final boolean lowBatteryEnabled = mPolicy.lowBatteryEnabled && !powerSaveModeOn;
+        final boolean dischargingLowBatteryState =
+                mPolicy.testLowBatteryTip || (mBatteryInfo.discharging && lowBattery);
 
         int state = BatteryTip.StateType.INVISIBLE;
-        if (mPolicy.lowBatteryEnabled) {
-            if (powerSaveModeOn) {
-                // Show it is handled if battery saver is on
-                state = BatteryTip.StateType.HANDLED;
-            } else if (mPolicy.testLowBatteryTip || (mBatteryInfo.discharging && lowBattery)) {
-                // Show it is new if in test or in discharging low battery state
-                state = BatteryTip.StateType.NEW;
-            }
+
+        // Show it as new if in test or in discharging low battery state,
+        // dismiss it if battery saver is on or disabled by config.
+        if (lowBatteryEnabled && dischargingLowBatteryState) {
+            state = BatteryTip.StateType.NEW;
         }
 
         return new LowBatteryTip(
diff --git a/src/com/android/settings/fuelgauge/batterytip/detectors/SmartBatteryDetector.java b/src/com/android/settings/fuelgauge/batterytip/detectors/SmartBatteryDetector.java
index a8d4981..23409a1 100644
--- a/src/com/android/settings/fuelgauge/batterytip/detectors/SmartBatteryDetector.java
+++ b/src/com/android/settings/fuelgauge/batterytip/detectors/SmartBatteryDetector.java
@@ -17,8 +17,11 @@
 package com.android.settings.fuelgauge.batterytip.detectors;
 
 import android.content.ContentResolver;
+import android.content.Context;
+import android.os.PowerManager;
 import android.provider.Settings;
 
+import com.android.settings.fuelgauge.BatteryInfo;
 import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy;
 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
 import com.android.settings.fuelgauge.batterytip.tips.SmartBatteryTip;
@@ -27,22 +30,33 @@
  * Detect whether to show smart battery tip.
  */
 public class SmartBatteryDetector implements BatteryTipDetector {
+    private static final int EXPECTED_BATTERY_LEVEL = 30;
+
+    private BatteryInfo mBatteryInfo;
     private BatteryTipPolicy mPolicy;
     private ContentResolver mContentResolver;
+    private PowerManager mPowerManager;
 
-    public SmartBatteryDetector(BatteryTipPolicy policy, ContentResolver contentResolver) {
+    public SmartBatteryDetector(Context context, BatteryTipPolicy policy, BatteryInfo batteryInfo,
+            ContentResolver contentResolver) {
         mPolicy = policy;
+        mBatteryInfo = batteryInfo;
         mContentResolver = contentResolver;
+        mPowerManager = context.getSystemService(PowerManager.class);
     }
 
     @Override
     public BatteryTip detect() {
-        // Show it if there is no other tips shown
         final boolean smartBatteryOff = Settings.Global.getInt(mContentResolver,
-                Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED, 1) == 0
+                Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED, 1) == 0;
+        final boolean isUnderExpectedBatteryLevel =
+                mBatteryInfo.batteryLevel <= EXPECTED_BATTERY_LEVEL;
+        // Show it if in test or smart battery is off.
+        final boolean enableSmartBatteryTip =
+                smartBatteryOff && !mPowerManager.isPowerSaveMode() && isUnderExpectedBatteryLevel
                 || mPolicy.testSmartBatteryTip;
         final int state =
-                smartBatteryOff ? BatteryTip.StateType.NEW : BatteryTip.StateType.INVISIBLE;
+                enableSmartBatteryTip ? BatteryTip.StateType.NEW : BatteryTip.StateType.INVISIBLE;
         return new SmartBatteryTip(state);
     }
 }
diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/EarlyWarningTip.java b/src/com/android/settings/fuelgauge/batterytip/tips/EarlyWarningTip.java
index 0c2bb03..6701314 100644
--- a/src/com/android/settings/fuelgauge/batterytip/tips/EarlyWarningTip.java
+++ b/src/com/android/settings/fuelgauge/batterytip/tips/EarlyWarningTip.java
@@ -18,7 +18,6 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.content.res.ColorStateList;
 import android.os.Parcel;
 
 import com.android.settings.R;
@@ -43,31 +42,23 @@
     @Override
     public CharSequence getTitle(Context context) {
         return context.getString(
-                mState == StateType.HANDLED
-                        ? R.string.battery_tip_early_heads_up_done_title
-                        : R.string.battery_tip_early_heads_up_title);
+                mState = R.string.battery_tip_early_heads_up_title);
     }
 
     @Override
     public CharSequence getSummary(Context context) {
         return context.getString(
-                mState == StateType.HANDLED
-                        ? R.string.battery_tip_early_heads_up_done_summary
-                        : R.string.battery_tip_early_heads_up_summary);
+                mState = R.string.battery_tip_early_heads_up_summary);
     }
 
     @Override
     public int getIconId() {
-        return mState == StateType.HANDLED
-                ? R.drawable.ic_battery_status_maybe_24dp
-                : R.drawable.ic_battery_status_bad_24dp;
+        return mState = R.drawable.ic_battery_status_bad_24dp;
     }
 
     @Override
     public int getIconTintColorId() {
-        return mState == StateType.HANDLED
-                ? R.color.battery_maybe_color_light
-                : R.color.battery_bad_color_light;
+        return mState = R.color.battery_bad_color_light;
     }
 
     @Override
@@ -76,9 +67,9 @@
         if (earlyWarningTip.mState == StateType.NEW) {
             // Display it if there is early warning
             mState = StateType.NEW;
-        } else if (mState == StateType.NEW && earlyWarningTip.mState == StateType.INVISIBLE) {
-            // If powerSaveMode is really on, show it as handled, otherwise just dismiss it.
-            mState = earlyWarningTip.mPowerSaveModeOn ? StateType.HANDLED : StateType.INVISIBLE;
+        } else if (earlyWarningTip.mPowerSaveModeOn) {
+            // If powerSaveMode is really on, dismiss it.
+            mState = StateType.INVISIBLE;
         } else {
             mState = earlyWarningTip.getState();
         }
diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTip.java b/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTip.java
index d7acdd2..7790b10 100644
--- a/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTip.java
+++ b/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTip.java
@@ -21,7 +21,6 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import com.android.settings.R;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 /**
@@ -43,8 +42,7 @@
 
     @Override
     public CharSequence getSummary(Context context) {
-        return mState == StateType.HANDLED ? context.getString(
-                R.string.battery_tip_early_heads_up_done_summary) : mSummary;
+        return mSummary;
     }
 
     @Override
diff --git a/src/com/android/settings/gestures/LongPressPowerButtonPreferenceController.java b/src/com/android/settings/gestures/LongPressPowerButtonPreferenceController.java
new file mode 100644
index 0000000..7a45602
--- /dev/null
+++ b/src/com/android/settings/gestures/LongPressPowerButtonPreferenceController.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2021 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.gestures;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.provider.Settings;
+
+import androidx.annotation.Nullable;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.core.TogglePreferenceController;
+
+/**
+ * Configures the behaviour of long press power button action.
+ */
+public class LongPressPowerButtonPreferenceController extends TogglePreferenceController implements
+        LifecycleObserver {
+
+    private static final String POWER_BUTTON_LONG_PRESS_SETTING =
+            Settings.Global.POWER_BUTTON_LONG_PRESS;
+    private static final Uri POWER_BUTTON_LONG_PRESS_SETTING_URI =
+            Settings.Global.getUriFor(POWER_BUTTON_LONG_PRESS_SETTING);
+
+    // Used for fallback to global actions if necessary.
+    @VisibleForTesting
+    static final String CARDS_AVAILABLE_KEY =
+            Settings.Secure.GLOBAL_ACTIONS_PANEL_AVAILABLE;
+    @VisibleForTesting
+    static final String CARDS_ENABLED_KEY = Settings.Secure.GLOBAL_ACTIONS_PANEL_ENABLED;
+
+    /**
+     * Value used for long press power button behaviour when Assist setting is enabled.
+     *
+     * {@link com.android.server.policy.PhoneWindowManager#LONG_PRESS_POWER_GLOBAL_ACTIONS} for
+     * source of the value.
+     */
+    @VisibleForTesting
+    static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
+    @VisibleForTesting
+    static final int LONG_PRESS_POWER_SHUT_OFF = 2;
+    @VisibleForTesting
+    static final int LONG_PRESS_POWER_ASSISTANT_VALUE = 5; // Settings.Secure.ASSISTANT
+
+    /**
+     * Value used for long press power button behaviour when the Assist setting is disabled.
+     *
+     * If this value matches Assist setting, then it falls back to Global Actions panel or
+     * power menu, depending on their respective settings.
+     */
+    private static final int POWER_BUTTON_LONG_PRESS_DEFAULT_VALUE_RESOURCE =
+            R.integer.config_longPressOnPowerBehavior;
+
+    @Nullable
+    private SettingObserver mSettingsObserver;
+
+    public LongPressPowerButtonPreferenceController(Context context, String key) {
+        super(context, key);
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mSettingsObserver = new SettingObserver(screen.findPreference(getPreferenceKey()));
+    }
+
+    /**
+     * Called when the settings pages resumes.
+     */
+    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
+    public void onResume() {
+        if (mSettingsObserver != null) {
+            mSettingsObserver.register();
+        }
+    }
+
+    /**
+     * Called when the settings page pauses.
+     */
+    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
+    public void onPause() {
+        if (mSettingsObserver != null) {
+            mSettingsObserver.unregister();
+        }
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        final boolean enabled = mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable);
+        return enabled ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+    }
+
+    @Override
+    public boolean isChecked() {
+        final int powerButtonValue = Settings.Global.getInt(mContext.getContentResolver(),
+                POWER_BUTTON_LONG_PRESS_SETTING,
+                mContext.getResources().getInteger(POWER_BUTTON_LONG_PRESS_DEFAULT_VALUE_RESOURCE));
+        return powerButtonValue == LONG_PRESS_POWER_ASSISTANT_VALUE;
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        if (isChecked) {
+            return Settings.Global.putInt(mContext.getContentResolver(),
+                    POWER_BUTTON_LONG_PRESS_SETTING, LONG_PRESS_POWER_ASSISTANT_VALUE);
+        }
+
+        // We need to determine the right disabled value - we set it to device default
+        // if it's different than Assist, otherwise we fallback to either global actions or power
+        //menu.
+        final int defaultPowerButtonValue = mContext.getResources().getInteger(
+                POWER_BUTTON_LONG_PRESS_DEFAULT_VALUE_RESOURCE);
+        if (defaultPowerButtonValue == LONG_PRESS_POWER_ASSISTANT_VALUE) {
+            final int fallbackValue = isCardsOrControlsAvailable() ? LONG_PRESS_POWER_GLOBAL_ACTIONS
+                    : LONG_PRESS_POWER_SHUT_OFF;
+            return Settings.Global.putInt(mContext.getContentResolver(),
+                    POWER_BUTTON_LONG_PRESS_SETTING, fallbackValue);
+        }
+
+        return Settings.Global.putInt(mContext.getContentResolver(),
+                POWER_BUTTON_LONG_PRESS_SETTING, defaultPowerButtonValue);
+    }
+
+    /**
+     * Returns true if the global actions menu on power button click is enabled via any of the
+     * content options.
+     */
+    private boolean isCardsOrControlsAvailable() {
+        final ContentResolver resolver = mContext.getContentResolver();
+        final boolean cardsAvailable = Settings.Secure.getInt(resolver, CARDS_AVAILABLE_KEY, 0)
+                != 0;
+        final boolean controlsAvailable = mContext.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_CONTROLS);
+        return cardsAvailable || controlsAvailable;
+    }
+
+    private final class SettingObserver extends ContentObserver {
+
+        private final Preference mPreference;
+
+        SettingObserver(Preference preference) {
+            super(new Handler(Looper.getMainLooper()));
+            mPreference = preference;
+        }
+
+        public void register() {
+            final ContentResolver cr = mContext.getContentResolver();
+            cr.registerContentObserver(POWER_BUTTON_LONG_PRESS_SETTING_URI, false, this);
+        }
+
+        public void unregister() {
+            final ContentResolver cr = mContext.getContentResolver();
+            cr.unregisterContentObserver(this);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            updateState(mPreference);
+        }
+    }
+
+}
diff --git a/src/com/android/settings/gestures/OneHandedEnablePreferenceController.java b/src/com/android/settings/gestures/OneHandedEnablePreferenceController.java
index c6db4ea..03bd195 100644
--- a/src/com/android/settings/gestures/OneHandedEnablePreferenceController.java
+++ b/src/com/android/settings/gestures/OneHandedEnablePreferenceController.java
@@ -17,7 +17,6 @@
 package com.android.settings.gestures;
 
 import android.content.Context;
-import android.os.SystemProperties;
 
 import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
@@ -28,15 +27,13 @@
  **/
 public class OneHandedEnablePreferenceController extends TogglePreferenceController {
 
-    static final String SUPPORT_ONE_HANDED_MODE = "ro.support_one_handed_mode";
-
     public OneHandedEnablePreferenceController(Context context, String key) {
         super(context, key);
     }
 
     @Override
     public int getAvailabilityStatus() {
-        return SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false)
+        return OneHandedSettingsUtils.isSupportOneHandedMode()
                 ? BasePreferenceController.AVAILABLE
                 : BasePreferenceController.UNSUPPORTED_ON_DEVICE;
     }
@@ -45,6 +42,7 @@
     public boolean setChecked(boolean isChecked) {
         OneHandedSettingsUtils.setSettingsOneHandedModeEnabled(mContext,
                 isChecked);
+        OneHandedSettingsUtils.setSwipeDownNotificationEnabled(mContext, !isChecked);
         return true;
     }
 
diff --git a/src/com/android/settings/gestures/OneHandedSettings.java b/src/com/android/settings/gestures/OneHandedSettings.java
index 2449cf2..6a07c85 100644
--- a/src/com/android/settings/gestures/OneHandedSettings.java
+++ b/src/com/android/settings/gestures/OneHandedSettings.java
@@ -18,7 +18,6 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.os.SystemProperties;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
@@ -52,8 +51,7 @@
             new BaseSearchIndexProvider(R.xml.one_handed_settings) {
                 @Override
                 protected boolean isPageSearchEnabled(Context context) {
-                    return SystemProperties.getBoolean(
-                            OneHandedEnablePreferenceController.SUPPORT_ONE_HANDED_MODE, false);
+                    return OneHandedSettingsUtils.isSupportOneHandedMode();
                 }
             };
 }
diff --git a/src/com/android/settings/gestures/OneHandedSettingsUtils.java b/src/com/android/settings/gestures/OneHandedSettingsUtils.java
index f3d7e33..ed0f62f 100644
--- a/src/com/android/settings/gestures/OneHandedSettingsUtils.java
+++ b/src/com/android/settings/gestures/OneHandedSettingsUtils.java
@@ -22,6 +22,7 @@
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.SystemProperties;
 import android.provider.Settings;
 
 /**
@@ -29,6 +30,8 @@
  */
 public class OneHandedSettingsUtils {
 
+    static final String SUPPORT_ONE_HANDED_MODE = "ro.support_one_handed_mode";
+
     public enum OneHandedTimeout {
         NEVER(0), SHORT(4), MEDIUM(8), LONG(12);
 
@@ -52,6 +55,13 @@
     }
 
     /**
+     * Get One-Handed mode support flag.
+     */
+    public static boolean isSupportOneHandedMode() {
+        return SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false);
+    }
+
+    /**
      * Get one-handed mode enable or disable flag from Settings provider.
      *
      * @param context App context
@@ -119,6 +129,28 @@
     }
 
     /**
+     * Get Swipe-down-notification enable or disable flag from Settings provider.
+     *
+     * @param context App context
+     * @return enable or disable Swipe-down-notification flag.
+     */
+    public static boolean isSwipeDownNotificationEnabled(Context context) {
+        return Settings.Secure.getInt(context.getContentResolver(),
+                Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED, 0) == 1;
+    }
+
+    /**
+     * Set Swipe-down-notification enable or disable flag to Settings provider.
+     *
+     * @param context App context
+     * @param enable enable or disable Swipe-down-notification.
+     */
+    public static void setSwipeDownNotificationEnabled(Context context, boolean enable) {
+        Settings.Secure.putInt(context.getContentResolver(),
+                Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED, enable ? 1 : 0);
+    }
+
+    /**
      * Register callback for observing Settings.Secure.ONE_HANDED_MODE_ENABLED state.
      * @param callback for state changes
      */
diff --git a/src/com/android/settings/gestures/PowerMenuPreferenceController.java b/src/com/android/settings/gestures/PowerMenuPreferenceController.java
index 6ef583b..b11ba65 100644
--- a/src/com/android/settings/gestures/PowerMenuPreferenceController.java
+++ b/src/com/android/settings/gestures/PowerMenuPreferenceController.java
@@ -57,7 +57,8 @@
 
     @Override
     public int getAvailabilityStatus() {
-        return isCardsAvailable() || isControlsAvailable() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
+        return isCardsAvailable() || isControlsAvailable() || isAssistInvocationAvailable()
+                ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
     }
 
     private boolean isControlsAvailable() {
@@ -68,4 +69,9 @@
         return Settings.Secure.getInt(mContext.getContentResolver(),
                 CARDS_AVAILABLE_SETTING, 0) == 1;
     }
+
+    private boolean isAssistInvocationAvailable() {
+        return mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable);
+    }
 }
diff --git a/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceController.java b/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceController.java
index 5eba539..28441cd 100644
--- a/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceController.java
+++ b/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceController.java
@@ -16,14 +16,8 @@
 
 package com.android.settings.gestures;
 
-import static android.provider.Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED;
-
-import static com.android.settings.gestures.OneHandedEnablePreferenceController.SUPPORT_ONE_HANDED_MODE;
 
 import android.content.Context;
-import android.os.SystemProperties;
-import android.provider.Settings;
-import android.text.TextUtils;
 
 import com.android.settings.R;
 import com.android.settings.core.TogglePreferenceController;
@@ -33,32 +27,20 @@
  **/
 public class SwipeBottomToNotificationPreferenceController extends TogglePreferenceController {
 
-    private static final int ON = 1;
-    private static final int OFF = 0;
-
     private static final String PREF_KEY = "gesture_swipe_bottom_to_notification";
 
     public SwipeBottomToNotificationPreferenceController(Context context, String key) {
         super(context, key);
     }
 
-    /** Indicates whether the gesture is available or not. */
-    public static boolean isGestureAvailable(Context context) {
-        // Disable the gesture once One-Handed mode gesture enabled.
-        if (SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false)) {
-            return !OneHandedSettingsUtils.isOneHandedModeEnabled(context);
-        }
-        return true;
-    }
-
     @Override
     public int getAvailabilityStatus() {
-        return isGestureAvailable(mContext) ? AVAILABLE : DISABLED_DEPENDENT_SETTING;
+        return OneHandedSettingsUtils.isSupportOneHandedMode() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
     }
 
     @Override
     public boolean isSliceable() {
-        return TextUtils.equals(getPreferenceKey(), PREF_KEY);
+        return true;
     }
 
     @Override
@@ -68,15 +50,16 @@
 
     @Override
     public boolean setChecked(boolean isChecked) {
-        Settings.Secure.putInt(mContext.getContentResolver(),
-                SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED, isChecked ? ON : OFF);
+        if (isChecked) {
+            OneHandedSettingsUtils.setSettingsOneHandedModeEnabled(mContext, false);
+        }
+        OneHandedSettingsUtils.setSwipeDownNotificationEnabled(mContext, isChecked);
         return true;
     }
 
     @Override
     public boolean isChecked() {
-        return Settings.Secure.getInt(mContext.getContentResolver(),
-                SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED, OFF) == ON;
+        return OneHandedSettingsUtils.isSwipeDownNotificationEnabled(mContext);
     }
 
     @Override
diff --git a/src/com/android/settings/gestures/SwipeBottomToNotificationSettings.java b/src/com/android/settings/gestures/SwipeBottomToNotificationSettings.java
index d0441f3..9d85f11 100644
--- a/src/com/android/settings/gestures/SwipeBottomToNotificationSettings.java
+++ b/src/com/android/settings/gestures/SwipeBottomToNotificationSettings.java
@@ -50,8 +50,10 @@
 
                 @Override
                 protected boolean isPageSearchEnabled(Context context) {
-                    return SwipeBottomToNotificationPreferenceController
-                            .isGestureAvailable(context);
+                    if (!OneHandedSettingsUtils.isSupportOneHandedMode()) {
+                        return false;
+                    }
+                    return !OneHandedSettingsUtils.isOneHandedModeEnabled(context);
                 }
             };
 }
diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java
index aa7b2d1..881e39c 100644
--- a/src/com/android/settings/homepage/SettingsHomepageActivity.java
+++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java
@@ -43,6 +43,25 @@
 
     private static final String TAG = "SettingsHomepageActivity";
 
+    private static final long HOMEPAGE_LOADING_TIMEOUT_MS = 300;
+
+    private View mHomepageView;
+    private View mSuggestionView;
+
+    /**
+     * Shows the homepage and shows/hides the suggestion together. Only allows to be executed once
+     * to avoid the flicker caused by the suggestion suddenly appearing/disappearing.
+     */
+    public void showHomepageWithSuggestion(boolean showSuggestion) {
+        if (mHomepageView == null) {
+            return;
+        }
+        Log.i(TAG, "showHomepageWithSuggestion: " + showSuggestion);
+        mSuggestionView.setVisibility(showSuggestion ? View.VISIBLE : View.GONE);
+        mHomepageView.setVisibility(View.VISIBLE);
+        mHomepageView = null;
+    }
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -56,15 +75,23 @@
         FeatureFactory.getFactory(this).getSearchFeatureProvider()
                 .initSearchToolbar(this /* activity */, toolbar, SettingsEnums.SETTINGS_HOMEPAGE);
 
-        final ImageView avatarView = findViewById(R.id.account_avatar);
-        getLifecycle().addObserver(new AvatarViewMixin(this, avatarView));
         getLifecycle().addObserver(new HideNonSystemOverlayMixin(this));
 
         if (!getSystemService(ActivityManager.class).isLowRamDevice()) {
-            // Only allow contextual features on high ram devices.
+            // Only allow features on high ram devices.
+            final ImageView avatarView = findViewById(R.id.account_avatar);
+            if (AvatarViewMixin.isAvatarSupported(this)) {
+                avatarView.setVisibility(View.VISIBLE);
+                getLifecycle().addObserver(new AvatarViewMixin(this, avatarView));
+            }
+
             if (FeatureFlagUtils.isEnabled(this, FeatureFlags.SILKY_HOME)) {
                 showSuggestionFragment();
+            } else {
+                findViewById(R.id.homepage_title).setVisibility(View.GONE);
+                avatarView.setVisibility(View.GONE);
             }
+
             if (FeatureFlagUtils.isEnabled(this, FeatureFlags.CONTEXTUAL_HOME)) {
                 showFragment(new ContextualCardsFragment(), R.id.contextual_cards_content);
             }
@@ -81,9 +108,16 @@
             return;
         }
 
+        mSuggestionView = findViewById(R.id.suggestion_content);
+        mHomepageView = findViewById(R.id.settings_homepage_container);
+        // Hide the homepage for preparing the suggestion.
+        mHomepageView.setVisibility(View.GONE);
+        // Schedule a timer to show the homepage and hide the suggestion on timeout.
+        mHomepageView.postDelayed(() -> showHomepageWithSuggestion(false),
+                HOMEPAGE_LOADING_TIMEOUT_MS);
         try {
-            showFragment(fragment.newInstance(), R.id.contextual_suggestion_content);
-        } catch (IllegalAccessException | InstantiationException e) {
+            showFragment(fragment.getConstructor().newInstance(), R.id.suggestion_content);
+        } catch (Exception e) {
             Log.w(TAG, "Cannot show fragment", e);
         }
     }
@@ -110,10 +144,7 @@
 
     private int getSearchBoxHeight() {
         final int searchBarHeight = getResources().getDimensionPixelSize(R.dimen.search_bar_height);
-        final int searchBarMarginTop = getResources().getDimensionPixelSize(
-                R.dimen.search_bar_margin);
-        final int searchBarMarginBottom = getResources().getDimensionPixelSize(
-                R.dimen.search_bar_margin_bottom);
-        return searchBarHeight + searchBarMarginTop + searchBarMarginBottom;
+        final int searchBarMargin = getResources().getDimensionPixelSize(R.dimen.search_bar_margin);
+        return searchBarHeight + searchBarMargin * 2;
     }
 }
diff --git a/src/com/android/settings/homepage/contextualcards/slices/LowStorageSlice.java b/src/com/android/settings/homepage/contextualcards/slices/LowStorageSlice.java
index 576b435..3812534 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/LowStorageSlice.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/LowStorageSlice.java
@@ -33,7 +33,7 @@
 import com.android.settings.R;
 import com.android.settings.SubSettings;
 import com.android.settings.Utils;
-import com.android.settings.deviceinfo.StorageSettings;
+import com.android.settings.deviceinfo.StorageDashboardFragment;
 import com.android.settings.slices.CustomSliceRegistry;
 import com.android.settings.slices.CustomSliceable;
 import com.android.settings.slices.SliceBuilderUtils;
@@ -107,7 +107,7 @@
                 .toString();
 
         return SliceBuilderUtils.buildSearchResultPageIntent(mContext,
-                StorageSettings.class.getName(), "" /* key */,
+                StorageDashboardFragment.class.getName(), "" /* key */,
                 screenTitle,
                 SettingsEnums.SLICE)
                 .setClassName(mContext.getPackageName(), SubSettings.class.getName())
diff --git a/src/com/android/settings/location/LocationFooterPreferenceController.java b/src/com/android/settings/location/LocationFooterPreferenceController.java
deleted file mode 100644
index 3b9324d..0000000
--- a/src/com/android/settings/location/LocationFooterPreferenceController.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.android.settings.location;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ResolveInfo;
-import android.location.LocationManager;
-import android.util.Log;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
-
-import com.android.settingslib.widget.FooterPreference;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Preference controller for location footer preference category
- */
-public class LocationFooterPreferenceController extends LocationBasePreferenceController {
-
-    private static final String TAG = "LocationFooter";
-    private static final Intent INJECT_INTENT =
-            new Intent(LocationManager.SETTINGS_FOOTER_DISPLAYED_ACTION);
-
-    private final PackageManager mPackageManager;
-
-    public LocationFooterPreferenceController(Context context, String key) {
-        super(context, key);
-        mPackageManager = context.getPackageManager();
-    }
-
-    /**
-     * Insert footer preferences.
-     */
-    @Override
-    public void updateState(Preference preference) {
-        PreferenceCategory category = (PreferenceCategory) preference;
-        category.removeAll();
-        Collection<FooterData> footerData = getFooterData();
-        for (FooterData data : footerData) {
-            try {
-                String footerString =
-                        mPackageManager
-                                .getResourcesForApplication(data.applicationInfo)
-                                .getString(data.footerStringRes);
-
-                // Generate a footer preference with the given text
-                FooterPreference footerPreference = new FooterPreference(preference.getContext());
-                footerPreference.setTitle(footerString);
-                category.addPreference(footerPreference);
-            } catch (NameNotFoundException exception) {
-                Log.w(
-                        TAG,
-                        "Resources not found for application "
-                                + data.applicationInfo.packageName);
-            }
-        }
-    }
-
-    /**
-     * Do nothing on location mode changes.
-     */
-    @Override
-    public void onLocationModeChanged(int mode, boolean restricted) {}
-
-    /**
-     * Location footer preference group should be displayed if there is at least one footer to
-     * inject.
-     */
-    @Override
-    public int getAvailabilityStatus() {
-        return !getFooterData().isEmpty() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
-    }
-
-    /**
-     * Return a list of strings with text provided by ACTION_INJECT_FOOTER broadcast receivers.
-     */
-    private List<FooterData> getFooterData() {
-        // Fetch footer text from system apps
-        List<ResolveInfo> resolveInfos =
-                mPackageManager.queryBroadcastReceivers(
-                        INJECT_INTENT, PackageManager.GET_META_DATA);
-        if (resolveInfos == null) {
-            Log.e(TAG, "Unable to resolve intent " + INJECT_INTENT);
-            return Collections.emptyList();
-        }
-
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "Found broadcast receivers: " + resolveInfos);
-        }
-
-        List<FooterData> footerDataList = new ArrayList<>(resolveInfos.size());
-        for (ResolveInfo resolveInfo : resolveInfos) {
-            ActivityInfo activityInfo = resolveInfo.activityInfo;
-            ApplicationInfo appInfo = activityInfo.applicationInfo;
-
-            // If a non-system app tries to inject footer, ignore it
-            if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
-                Log.w(TAG, "Ignoring attempt to inject footer from app not in system image: "
-                        + resolveInfo);
-                continue;
-            }
-
-            // Get the footer text resource id from broadcast receiver's metadata
-            if (activityInfo.metaData == null) {
-                if (Log.isLoggable(TAG, Log.DEBUG)) {
-                    Log.d(TAG, "No METADATA in broadcast receiver " + activityInfo.name);
-                }
-                continue;
-            }
-
-            final int footerTextRes =
-                    activityInfo.metaData.getInt(LocationManager.METADATA_SETTINGS_FOOTER_STRING);
-            if (footerTextRes == 0) {
-                Log.w(
-                        TAG,
-                        "No mapping of integer exists for "
-                                + LocationManager.METADATA_SETTINGS_FOOTER_STRING);
-                continue;
-            }
-            footerDataList.add(new FooterData(footerTextRes, appInfo));
-        }
-        return footerDataList;
-    }
-
-    /**
-     * Contains information related to a footer.
-     */
-    private static class FooterData {
-
-        // The string resource of the footer
-        final int footerStringRes;
-
-        // Application info of receiver injecting this footer
-        final ApplicationInfo applicationInfo;
-
-        FooterData(int footerRes, ApplicationInfo appInfo) {
-            this.footerStringRes = footerRes;
-            this.applicationInfo = appInfo;
-        }
-    }
-}
diff --git a/src/com/android/settings/location/LocationPersonalSettings.java b/src/com/android/settings/location/LocationPersonalSettings.java
index bdf2d2b..ef5465c 100644
--- a/src/com/android/settings/location/LocationPersonalSettings.java
+++ b/src/com/android/settings/location/LocationPersonalSettings.java
@@ -52,7 +52,6 @@
         use(AppLocationPermissionPreferenceController.class).init(this);
         // STOPSHIP(b/180533061): resolve the personal/work location services issue before we can
         // ship.
-        use(LocationFooterPreferenceController.class).init(this);
         use(RecentLocationAccessSeeAllButtonPreferenceController.class).init(this);
 
         final int profileType = getArguments().getInt(ProfileSelectFragment.EXTRA_PROFILE);
diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java
index bb971bf..7b7ca16 100644
--- a/src/com/android/settings/location/LocationSettings.java
+++ b/src/com/android/settings/location/LocationSettings.java
@@ -84,7 +84,6 @@
         use(AppLocationPermissionPreferenceController.class).init(this);
         use(RecentLocationAccessPreferenceController.class).init(this);
         use(RecentLocationAccessSeeAllButtonPreferenceController.class).init(this);
-        use(LocationFooterPreferenceController.class).init(this);
         use(LocationForWorkPreferenceController.class).init(this);
         use(LocationInjectedServicesForWorkPreferenceController.class).init(this);
     }
diff --git a/src/com/android/settings/location/LocationWorkProfileSettings.java b/src/com/android/settings/location/LocationWorkProfileSettings.java
index 6783075..4cafcbf 100644
--- a/src/com/android/settings/location/LocationWorkProfileSettings.java
+++ b/src/com/android/settings/location/LocationWorkProfileSettings.java
@@ -50,7 +50,6 @@
         super.onAttach(context);
 
         use(AppLocationPermissionPreferenceController.class).init(this);
-        use(LocationFooterPreferenceController.class).init(this);
         use(LocationForWorkPreferenceController.class).init(this);
         use(RecentLocationAccessSeeAllButtonPreferenceController.class).init(this);
 
diff --git a/src/com/android/settings/network/InternetUpdater.java b/src/com/android/settings/network/InternetUpdater.java
index 3967276..dd70cef 100644
--- a/src/com/android/settings/network/InternetUpdater.java
+++ b/src/com/android/settings/network/InternetUpdater.java
@@ -142,13 +142,13 @@
     private NetworkCallback mNetworkCallback = new NetworkCallback() {
         public void onCapabilitiesChanged(@NonNull Network network,
                 @NonNull NetworkCapabilities networkCapabilities) {
-            checkNetworkCapabilities(networkCapabilities);
+            updateInternetAvailable(networkCapabilities);
         }
 
         @Override
         public void onLost(@NonNull Network network) {
             mInternetAvailable = false;
-            update();
+            updateInternetType();
         }
     };
 
@@ -203,7 +203,7 @@
         Network activeNetwork = mConnectivityManager.getActiveNetwork();
         if (activeNetwork == null) {
             mInternetAvailable = false;
-            update();
+            updateInternetType();
             return;
         }
 
@@ -211,36 +211,34 @@
                 mConnectivityManager.getNetworkCapabilities(activeNetwork);
         if (activeNetworkCapabilities == null) {
             mInternetAvailable = false;
-            update();
+            updateInternetType();
             return;
         }
 
-        checkNetworkCapabilities(activeNetworkCapabilities);
-    }
-
-    private void checkNetworkCapabilities(@NonNull NetworkCapabilities networkCapabilities) {
-        if (!networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
-            mInternetAvailable = false;
-            update();
-            return;
-        }
-
-        boolean internetAvailable = false;
-        for (int transport : networkCapabilities.getTransportTypes()) {
-            if (sTransportMap.containsKey(transport)) {
-                mTransport = transport;
-                internetAvailable = true;
-                Log.i(TAG, "Detect an internet capability network with transport type: "
-                        + mTransport);
-                break;
-            }
-        }
-        mInternetAvailable = internetAvailable;
-        update();
+        updateInternetAvailable(activeNetworkCapabilities);
     }
 
     @VisibleForTesting
-    void update() {
+    void updateInternetAvailable(@NonNull NetworkCapabilities capabilities) {
+        boolean internetAvailable = false;
+        if (capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+                && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
+            for (int transport : capabilities.getTransportTypes()) {
+                if (sTransportMap.containsKey(transport)) {
+                    mTransport = transport;
+                    internetAvailable = true;
+                    Log.i(TAG, "Detect an internet available network with transport type: "
+                            + mTransport);
+                    break;
+                }
+            }
+        }
+        mInternetAvailable = internetAvailable;
+        updateInternetType();
+    }
+
+    @VisibleForTesting
+    void updateInternetType() {
         @InternetType int internetType = INTERNET_NETWORKS_AVAILABLE;
         if (mInternetAvailable) {
             internetType = sTransportMap.get(mTransport);
diff --git a/src/com/android/settings/network/NetworkProviderSettings.java b/src/com/android/settings/network/NetworkProviderSettings.java
index 803b981..1d8ee7a 100644
--- a/src/com/android/settings/network/NetworkProviderSettings.java
+++ b/src/com/android/settings/network/NetworkProviderSettings.java
@@ -1129,7 +1129,7 @@
     @Override
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         MenuItem item = menu.add(0, MENU_FIX_CONNECTIVITY, 0, R.string.fix_connectivity);
-        item.setIcon(R.drawable.ic_refresh_24dp);
+        item.setIcon(R.drawable.ic_repair_24dp);
         item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
         super.onCreateOptionsMenu(menu, inflater);
     }
diff --git a/src/com/android/settings/network/ProviderModelSlice.java b/src/com/android/settings/network/ProviderModelSlice.java
index 18765a8..beb7489 100644
--- a/src/com/android/settings/network/ProviderModelSlice.java
+++ b/src/com/android/settings/network/ProviderModelSlice.java
@@ -21,6 +21,7 @@
 
 import static com.android.settings.slices.CustomSliceRegistry.PROVIDER_MODEL_SLICE_URI;
 
+import android.annotation.ColorInt;
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.Intent;
@@ -30,6 +31,7 @@
 import android.util.Log;
 
 import androidx.annotation.VisibleForTesting;
+import androidx.core.graphics.drawable.IconCompat;
 import androidx.slice.Slice;
 import androidx.slice.builders.ListBuilder;
 
@@ -83,9 +85,10 @@
         // Second section:  Add a carrier item.
         // Third section:  Add the Wi-Fi items which are not connected.
         // Fourth section:  If device has connection problem, this row show the message for user.
-        boolean hasEthernet = isEthernetConnected();
+        @InternetUpdater.InternetType int internetType = getInternetType();
         final ListBuilder listBuilder = mHelper.createListBuilder(getUri());
-        if (mHelper.isAirplaneModeEnabled() && !mWifiManager.isWifiEnabled() && !hasEthernet) {
+        if (mHelper.isAirplaneModeEnabled() && !mWifiManager.isWifiEnabled()
+                && internetType != InternetUpdater.INTERNET_ETHERNET) {
             log("Airplane mode is enabled.");
             return listBuilder.build();
         }
@@ -105,15 +108,17 @@
         log("hasCarrier: " + hasCarrier);
 
         // First section:  Add a Ethernet or Wi-Fi item which state is connected.
+        boolean isConnectedWifiAddedTop = false;
         final WifiSliceItem connectedWifiItem = mHelper.getConnectedWifiItem(wifiList);
-        if (hasEthernet) {
+        if (internetType == InternetUpdater.INTERNET_ETHERNET) {
             log("get Ethernet item which is connected");
             listBuilder.addRow(createEthernetRow());
             maxListSize--;
         } else {
-            if (connectedWifiItem != null) {
-                log("get Wi-Fi item which is connected");
+            if (connectedWifiItem != null && internetType == InternetUpdater.INTERNET_WIFI) {
+                log("get Wi-Fi item which is connected to internet");
                 listBuilder.addRow(getWifiSliceItemRow(connectedWifiItem));
+                isConnectedWifiAddedTop = true;
                 maxListSize--;
             }
         }
@@ -128,7 +133,7 @@
         }
 
         // Third section:  Add the connected Wi-Fi item to Wi-Fi list if the Ethernet is connected.
-        if (connectedWifiItem != null && hasEthernet) {
+        if (connectedWifiItem != null && !isConnectedWifiAddedTop) {
             log("get Wi-Fi item which is connected");
             listBuilder.addRow(getWifiSliceItemRow(connectedWifiItem));
             maxListSize--;
@@ -222,12 +227,12 @@
         return SliceBackgroundWorker.getInstance(getUri());
     }
 
-    private boolean isEthernetConnected() {
+    private @InternetUpdater.InternetType int getInternetType() {
         final NetworkProviderWorker worker = getWorker();
         if (worker == null) {
-            return false;
+            return InternetUpdater.INTERNET_NETWORKS_AVAILABLE;
         }
-        return worker.isEthernetConnected();
+        return worker.getInternetType();
     }
 
     @VisibleForTesting
@@ -243,6 +248,20 @@
                 .setSubtitle(mContext.getText(R.string.to_switch_networks_disconnect_ethernet));
     }
 
+    @Override
+    protected IconCompat getWifiSliceItemLevelIcon(WifiSliceItem wifiSliceItem) {
+        if (wifiSliceItem.getConnectedState() == WifiEntry.CONNECTED_STATE_CONNECTED
+                && getInternetType() != InternetUpdater.INTERNET_WIFI) {
+            final @ColorInt int tint = Utils.getColorAttrDefaultColor(mContext,
+                    android.R.attr.colorControlNormal);
+            final Drawable drawable = mContext.getDrawable(
+                    Utils.getWifiIconResource(wifiSliceItem.getLevel()));
+            drawable.setTint(tint);
+            return Utils.createIconWithDrawable(drawable);
+        }
+        return super.getWifiSliceItemLevelIcon(wifiSliceItem);
+    }
+
     /**
      * Wrap the subscriptionManager call for test mocking.
      */
diff --git a/src/com/android/settings/network/VpnPreferenceController.java b/src/com/android/settings/network/VpnPreferenceController.java
index e815d49..0bec7ac 100644
--- a/src/com/android/settings/network/VpnPreferenceController.java
+++ b/src/com/android/settings/network/VpnPreferenceController.java
@@ -27,6 +27,8 @@
 import android.os.UserManager;
 import android.provider.Settings;
 import android.provider.SettingsSlicesContract;
+import android.security.Credentials;
+import android.security.LegacyVpnProfileStore;
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -36,8 +38,11 @@
 
 import com.android.internal.net.LegacyVpnInfo;
 import com.android.internal.net.VpnConfig;
+import com.android.internal.net.VpnProfile;
 import com.android.settings.R;
+import com.android.settings.Utils;
 import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.vpn2.VpnInfoPreference;
 import com.android.settingslib.RestrictedLockUtilsInternal;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
@@ -119,6 +124,7 @@
         // Copied from SystemUI::SecurityControllerImpl
         SparseArray<VpnConfig> vpns = new SparseArray<>();
         final List<UserInfo> users = mUserManager.getUsers();
+        int connectedLegacyVpnCount = 0;
         for (UserInfo user : users) {
             VpnConfig cfg = mVpnManager.getVpnConfig(user.id);
             if (cfg == null) {
@@ -129,6 +135,8 @@
                 final LegacyVpnInfo legacyVpn = mVpnManager.getLegacyVpnInfo(user.id);
                 if (legacyVpn == null || legacyVpn.state != LegacyVpnInfo.STATE_CONNECTED) {
                     continue;
+                } else {
+                    connectedLegacyVpnCount++;
                 }
             }
             vpns.put(user.id, cfg);
@@ -141,13 +149,34 @@
             uid = userInfo.id;
         }
         VpnConfig vpn = vpns.get(uid);
-        final String summary;
+        String summary;
         if (vpn == null) {
             summary = mContext.getString(R.string.vpn_disconnected_summary);
         } else {
             summary = getNameForVpnConfig(vpn, UserHandle.of(uid));
         }
-        ThreadUtils.postOnMainThread(() -> mPreference.setSummary(summary));
+        // Optionally add warning icon if an insecure VPN is present.
+        if (Utils.isProviderModelEnabled(mContext) && mPreference instanceof VpnInfoPreference) {
+            final int insecureVpnCount = getInsecureVpnCount();
+            boolean isInsecureVPN = insecureVpnCount > 0;
+            ((VpnInfoPreference) mPreference).setInsecureVpn(isInsecureVPN);
+            // Set the summary based on the total number of VPNs and insecure VPNs.
+            if (isInsecureVPN) {
+                // Add the users and the number of legacy vpns to determine if there is more than
+                // one vpn, since there can be more than one VPN per user.
+                final int vpnCount = vpns.size()
+                        + LegacyVpnProfileStore.list(Credentials.VPN).length
+                        - connectedLegacyVpnCount;
+                if (vpnCount == 1) {
+                    summary = mContext.getString(R.string.vpn_settings_insecure_single);
+                } else {
+                    summary = mContext.getString(
+                            R.string.vpn_settings_insecure_multiple, insecureVpnCount);
+                }
+            }
+        }
+        final String finalSummary = summary;
+        ThreadUtils.postOnMainThread(() -> mPreference.setSummary(finalSummary));
     }
 
     @VisibleForTesting
@@ -167,6 +196,21 @@
         }
     }
 
+    @VisibleForTesting
+    protected int getInsecureVpnCount() {
+        int count = 0;
+        for (String key : LegacyVpnProfileStore.list(Credentials.VPN)) {
+            final VpnProfile profile = VpnProfile.decode(key,
+                    LegacyVpnProfileStore.get(Credentials.VPN + key));
+            // Return whether any profile is an insecure type.
+            if (VpnProfile.isLegacyType(profile.type)) {
+                count++;
+            }
+        }
+        // We did not find any insecure VPNs.
+        return count;
+    }
+
     // Copied from SystemUI::SecurityControllerImpl
     private final ConnectivityManager.NetworkCallback
             mNetworkCallback = new ConnectivityManager.NetworkCallback() {
diff --git a/src/com/android/settings/network/telephony/NetworkOperatorPreference.java b/src/com/android/settings/network/telephony/NetworkOperatorPreference.java
index cfd587a..a4cff33 100644
--- a/src/com/android/settings/network/telephony/NetworkOperatorPreference.java
+++ b/src/com/android/settings/network/telephony/NetworkOperatorPreference.java
@@ -19,6 +19,7 @@
 import static android.telephony.SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
 
 import android.content.Context;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
 import android.telephony.CellIdentity;
 import android.telephony.CellIdentityGsm;
 import android.telephony.CellIdentityLte;
@@ -180,7 +181,7 @@
     public OperatorInfo getOperatorInfo() {
         return new OperatorInfo(Objects.toString(mCellId.getOperatorAlphaLong(), ""),
                 Objects.toString(mCellId.getOperatorAlphaShort(), ""),
-                getOperatorNumeric());
+                getOperatorNumeric(), getAccessNetworkTypeFromCellInfo(mCellInfo));
     }
 
     private int getIconIdForCell(CellInfo ci) {
@@ -225,6 +226,25 @@
         return null;
     }
 
+    private int getAccessNetworkTypeFromCellInfo(CellInfo ci) {
+        if (ci instanceof CellInfoGsm) {
+            return AccessNetworkType.GERAN;
+        }
+        if (ci instanceof CellInfoCdma) {
+            return AccessNetworkType.CDMA2000;
+        }
+        if ((ci instanceof CellInfoWcdma) || (ci instanceof CellInfoTdscdma)) {
+            return AccessNetworkType.UTRAN;
+        }
+        if (ci instanceof CellInfoLte) {
+            return AccessNetworkType.EUTRAN;
+        }
+        if (ci instanceof CellInfoNr) {
+            return AccessNetworkType.NGRAN;
+        }
+        return AccessNetworkType.UNKNOWN;
+    }
+
     private void updateIcon(int level) {
         if (!mUseNewApi || level < 0 || level >= NUM_SIGNAL_STRENGTH_BINS) {
             return;
diff --git a/src/com/android/settings/network/telephony/NetworkProviderWorker.java b/src/com/android/settings/network/telephony/NetworkProviderWorker.java
index 57f17b5..698e779 100644
--- a/src/com/android/settings/network/telephony/NetworkProviderWorker.java
+++ b/src/com/android/settings/network/telephony/NetworkProviderWorker.java
@@ -288,9 +288,9 @@
     }
 
     /**
-     * Returns true, if the ethernet network is connected.
+     * Returns the internet type.
      */
-    public boolean isEthernetConnected() {
-        return mInternetType == INTERNET_ETHERNET;
+    public @InternetUpdater.InternetType int getInternetType() {
+        return mInternetType;
     }
 }
diff --git a/src/com/android/settings/notification/app/RecentConversationsPreferenceController.java b/src/com/android/settings/notification/app/RecentConversationsPreferenceController.java
index 8be6016..d4ad994 100644
--- a/src/com/android/settings/notification/app/RecentConversationsPreferenceController.java
+++ b/src/com/android/settings/notification/app/RecentConversationsPreferenceController.java
@@ -72,7 +72,7 @@
         return true;
     }
 
-    Preference getClearAll(PreferenceGroup parent) {
+    LayoutPreference getClearAll(PreferenceGroup parent) {
         LayoutPreference pref = new LayoutPreference(
                 mContext, R.layout.conversations_clear_recents);
         pref.setOrder(1);
@@ -80,10 +80,21 @@
         button.setOnClickListener(v -> {
             try {
                 mPs.removeAllRecentConversations();
+                // Removing recents is asynchronous, so we can't immediately reload the list from
+                // the backend. Instead, proactively remove all of items that were marked as
+                // clearable, so long as we didn't get an error
+
+                for (int i = parent.getPreferenceCount() - 1; i >= 0; i--) {
+                    Preference p = parent.getPreference(i);
+                    if (p instanceof RecentConversationPreference) {
+                        if (((RecentConversationPreference) p).hasClearListener()) {
+                            parent.removePreference(p);
+                        }
+                    }
+                }
             } catch (RemoteException e) {
                 Slog.w(TAG, "Could not clear recents", e);
             }
-            updateState(parent);
         });
         return pref;
     }
@@ -118,36 +129,45 @@
     protected void populateList(List<ConversationChannel> conversations,
             PreferenceGroup containerGroup) {
         containerGroup.removeAll();
+        boolean hasClearable = false;
         if (conversations != null) {
-            populateConversations(conversations, containerGroup);
+            hasClearable = populateConversations(conversations, containerGroup);
         }
 
         if (containerGroup.getPreferenceCount() == 0) {
             containerGroup.setVisible(false);
         } else {
             containerGroup.setVisible(true);
-            Preference clearAll = getClearAll(containerGroup);
-            if (clearAll != null) {
-                containerGroup.addPreference(clearAll);
+            if (hasClearable) {
+                Preference clearAll = getClearAll(containerGroup);
+                if (clearAll != null) {
+                    containerGroup.addPreference(clearAll);
+                }
             }
         }
     }
 
-    protected void populateConversations(List<ConversationChannel> conversations,
+    protected boolean populateConversations(List<ConversationChannel> conversations,
             PreferenceGroup containerGroup) {
         int order = 100;
+        boolean hasClearable = false;
         for (ConversationChannel conversation : conversations) {
             if (conversation.getParentNotificationChannel().getImportance() == IMPORTANCE_NONE
                     || (conversation.getParentNotificationChannelGroup() != null
                     && conversation.getParentNotificationChannelGroup().isBlocked())) {
                 continue;
             }
-            containerGroup.addPreference(
-                    createConversationPref(containerGroup, conversation, order++));
+            RecentConversationPreference pref =
+                    createConversationPref(containerGroup, conversation, order++);
+            containerGroup.addPreference(pref);
+            if (pref.hasClearListener()) {
+                hasClearable = true;
+            }
         }
+        return hasClearable;
     }
 
-    protected Preference createConversationPref(PreferenceGroup parent,
+    protected RecentConversationPreference createConversationPref(PreferenceGroup parent,
             final ConversationChannel conversation, int order) {
         final String pkg = conversation.getShortcutInfo().getPackage();
         final int uid = conversation.getUid();
diff --git a/src/com/android/settings/overlay/FeatureFactory.java b/src/com/android/settings/overlay/FeatureFactory.java
index 0e47556..e7b23b9 100644
--- a/src/com/android/settings/overlay/FeatureFactory.java
+++ b/src/com/android/settings/overlay/FeatureFactory.java
@@ -41,6 +41,7 @@
 import com.android.settings.panel.PanelFeatureProvider;
 import com.android.settings.search.SearchFeatureProvider;
 import com.android.settings.security.SecurityFeatureProvider;
+import com.android.settings.security.SecuritySettingsFeatureProvider;
 import com.android.settings.slices.SlicesFeatureProvider;
 import com.android.settings.users.UserFeatureProvider;
 import com.android.settings.wifi.WifiTrackerLibProvider;
@@ -162,6 +163,11 @@
      */
     public abstract ExtraAppInfoFeatureProvider getExtraAppInfoFeatureProvider();
 
+    /**
+     * Retrieve implementation for SecuritySettings feature.
+     */
+    public abstract SecuritySettingsFeatureProvider getSecuritySettingsFeatureProvider();
+
     public static final class FactoryNotFoundException extends RuntimeException {
         public FactoryNotFoundException(Throwable throwable) {
             super("Unable to create factory. Did you misconfigure Proguard?", throwable);
diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java
index dc08547..00f9a0e 100644
--- a/src/com/android/settings/overlay/FeatureFactoryImpl.java
+++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java
@@ -63,6 +63,8 @@
 import com.android.settings.search.SearchFeatureProviderImpl;
 import com.android.settings.security.SecurityFeatureProvider;
 import com.android.settings.security.SecurityFeatureProviderImpl;
+import com.android.settings.security.SecuritySettingsFeatureProvider;
+import com.android.settings.security.SecuritySettingsFeatureProviderImpl;
 import com.android.settings.slices.SlicesFeatureProvider;
 import com.android.settings.slices.SlicesFeatureProviderImpl;
 import com.android.settings.users.UserFeatureProvider;
@@ -100,6 +102,7 @@
     private FaceFeatureProvider mFaceFeatureProvider;
     private WifiTrackerLibProvider mWifiTrackerLibProvider;
     private ExtraAppInfoFeatureProvider mExtraAppInfoFeatureProvider;
+    private SecuritySettingsFeatureProvider mSecuritySettingsFeatureProvider;
 
     @Override
     public SupportFeatureProvider getSupportFeatureProvider(Context context) {
@@ -135,7 +138,7 @@
     @Override
     public BatterySettingsFeatureProvider getBatterySettingsFeatureProvider(Context context) {
         if (mBatterySettingsFeatureProvider == null) {
-            mBatterySettingsFeatureProvider = new BatterySettingsFeatureProviderImpl();
+            mBatterySettingsFeatureProvider = new BatterySettingsFeatureProviderImpl(context);
         }
         return mBatterySettingsFeatureProvider;
     }
@@ -313,4 +316,12 @@
         }
         return mExtraAppInfoFeatureProvider;
     }
+
+    @Override
+    public SecuritySettingsFeatureProvider getSecuritySettingsFeatureProvider() {
+        if (mSecuritySettingsFeatureProvider == null) {
+            mSecuritySettingsFeatureProvider = new SecuritySettingsFeatureProviderImpl();
+        }
+        return mSecuritySettingsFeatureProvider;
+    }
 }
diff --git a/src/com/android/settings/password/ChooseLockPattern.java b/src/com/android/settings/password/ChooseLockPattern.java
index c52b410..4b9883a 100644
--- a/src/com/android/settings/password/ChooseLockPattern.java
+++ b/src/com/android/settings/password/ChooseLockPattern.java
@@ -32,6 +32,7 @@
 import android.util.TypedValue;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
+import android.view.Surface;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ScrollView;
@@ -508,6 +509,12 @@
                 Bundle savedInstanceState) {
             final GlifLayout layout = (GlifLayout) inflater.inflate(
                     R.layout.choose_lock_pattern, container, false);
+            switch(getContext().getDisplay().getRotation()) {
+                case Surface.ROTATION_90:
+                case Surface.ROTATION_270:
+                    layout.setLandscapeHeaderAreaVisible(false /* visible */);
+                    break;
+            }
             layout.setHeaderText(getActivity().getTitle());
             if (getResources().getBoolean(R.bool.config_lock_pattern_minimal_ui)) {
                 View iconView = layout.findViewById(R.id.sud_layout_icon);
diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
index 6a97dcd..14b364c 100644
--- a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
+++ b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
@@ -228,7 +228,7 @@
             launchedCDC = builder.setHeader(mTitle) // Show the title in the header location
                     .setDescription(mDetails)
                     .setAlternateButton(alternateButton)
-                    .setExternal(true)
+                    .setExternal(false)
                     .setUserId(LockPatternUtils.USER_FRP)
                     .show();
         } else if (isManagedProfile && isInternalActivity()
diff --git a/src/com/android/settings/password/ConfirmLockPattern.java b/src/com/android/settings/password/ConfirmLockPattern.java
index 598e09a..0e18436 100644
--- a/src/com/android/settings/password/ConfirmLockPattern.java
+++ b/src/com/android/settings/password/ConfirmLockPattern.java
@@ -28,6 +28,7 @@
 import android.os.storage.StorageManager;
 import android.text.TextUtils;
 import android.view.LayoutInflater;
+import android.view.Surface;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.animation.AnimationUtils;
@@ -45,6 +46,8 @@
 import com.android.settingslib.animation.AppearAnimationUtils;
 import com.android.settingslib.animation.DisappearAnimationUtils;
 
+import com.google.android.setupdesign.GlifLayout;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -90,8 +93,7 @@
         private boolean mDisappearing = false;
         private CountDownTimer mCountdownTimer;
 
-        private TextView mHeaderTextView;
-        private TextView mDetailsTextView;
+        private GlifLayout mGlifLayout;
 
         // caller-supplied text for various prompts
         private CharSequence mHeaderText;
@@ -117,9 +119,14 @@
                             : R.layout.confirm_lock_pattern,
                     container,
                     false);
-            mHeaderTextView = (TextView) view.findViewById(R.id.headerText);
+            mGlifLayout = view.findViewById(R.id.setup_wizard_layout);
+            switch(getContext().getDisplay().getRotation()) {
+                case Surface.ROTATION_90:
+                case Surface.ROTATION_270:
+                    mGlifLayout.setLandscapeHeaderAreaVisible(false /* visible */);
+                    break;
+            }
             mLockPatternView = (LockPatternView) view.findViewById(R.id.lockPattern);
-            mDetailsTextView = (TextView) view.findViewById(R.id.sud_layout_description);
             mErrorTextView = (TextView) view.findViewById(R.id.errorText);
 
             mIsManagedProfile = UserManager.get(getActivity()).isManagedProfile(mEffectiveUserId);
@@ -177,7 +184,7 @@
                             return (float)(numRows - row) / numRows;
                         }
                     });
-            setAccessibilityTitle(mHeaderTextView.getText());
+            setAccessibilityTitle(mGlifLayout.getHeaderText());
 
             mCredentialCheckResultTracker = (CredentialCheckResultTracker) getFragmentManager()
                     .findFragmentByTag(FRAGMENT_TAG_CHECK_LOCK_RESULT);
@@ -242,13 +249,13 @@
         @Override
         public void prepareEnterAnimation() {
             super.prepareEnterAnimation();
-            mHeaderTextView.setAlpha(0f);
+            mGlifLayout.getHeaderTextView().setAlpha(0f);
             mCancelButton.setAlpha(0f);
             if (mForgotButton != null) {
                 mForgotButton.setAlpha(0f);
             }
             mLockPatternView.setAlpha(0f);
-            mDetailsTextView.setAlpha(0f);
+            mGlifLayout.getDescriptionTextView().setAlpha(0f);
         }
 
         private int getDefaultDetails() {
@@ -269,8 +276,9 @@
 
         private Object[][] getActiveViews() {
             ArrayList<ArrayList<Object>> result = new ArrayList<>();
-            result.add(new ArrayList<>(Collections.singletonList(mHeaderTextView)));
-            result.add(new ArrayList<>(Collections.singletonList(mDetailsTextView)));
+            result.add(new ArrayList<>(Collections.singletonList(mGlifLayout.getHeaderTextView())));
+            result.add(new ArrayList<>(
+                    Collections.singletonList(mGlifLayout.getDescriptionTextView())));
             if (mCancelButton.getVisibility() == View.VISIBLE) {
                 result.add(new ArrayList<>(Collections.singletonList(mCancelButton)));
             }
@@ -306,14 +314,14 @@
             switch (stage) {
                 case NeedToUnlock:
                     if (mHeaderText != null) {
-                        mHeaderTextView.setText(mHeaderText);
+                        mGlifLayout.setHeaderText(mHeaderText);
                     } else {
-                        mHeaderTextView.setText(getDefaultHeader());
+                        mGlifLayout.setHeaderText(getDefaultHeader());
                     }
                     if (mDetailsText != null) {
-                        mDetailsTextView.setText(mDetailsText);
+                        mGlifLayout.setDescriptionText(mDetailsText);
                     } else {
-                        mDetailsTextView.setText(getDefaultDetails());
+                        mGlifLayout.setDescriptionText(getDefaultDetails());
                     }
                     mErrorTextView.setText("");
                     updateErrorMessage(
@@ -341,7 +349,7 @@
 
             // Always announce the header for accessibility. This is a no-op
             // when accessibility is disabled.
-            mHeaderTextView.announceForAccessibility(mHeaderTextView.getText());
+            mGlifLayout.getHeaderTextView().announceForAccessibility(mGlifLayout.getHeaderText());
         }
 
         private int getDefaultHeader() {
diff --git a/src/com/android/settings/security/CredentialManagementAppAdapter.java b/src/com/android/settings/security/CredentialManagementAppAdapter.java
index e56fc63..6b37f7f 100644
--- a/src/com/android/settings/security/CredentialManagementAppAdapter.java
+++ b/src/com/android/settings/security/CredentialManagementAppAdapter.java
@@ -25,6 +25,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ImageView;
+import android.widget.RelativeLayout;
 import android.widget.TextView;
 
 import androidx.annotation.NonNull;
@@ -61,6 +62,7 @@
 
     private final boolean mIncludeHeader;
     private final boolean mIncludeExpander;
+    private final boolean mIsLayoutRtl;
 
     /**
      * View holder for the header in the request manage credentials screen.
@@ -113,6 +115,15 @@
             mChildRecyclerView = view.findViewById(R.id.uris);
             mExpandedApps = new ArrayList<>();
 
+            if (mIsLayoutRtl) {
+                RelativeLayout appDetails = view.findViewById(R.id.app_details);
+                RelativeLayout.LayoutParams params =
+                        (RelativeLayout.LayoutParams) appDetails.getLayoutParams();
+                params.addRule(RelativeLayout.LEFT_OF, R.id.app_icon);
+                params.addRule(RelativeLayout.RIGHT_OF, R.id.expand);
+                view.setLayoutParams(params);
+            }
+
             mExpanderIconView.setOnClickListener(view1 -> {
                 final String appName = mSortedAppNames.get(getBindingAdapterPosition());
                 if (mExpandedApps.contains(appName)) {
@@ -195,6 +206,8 @@
         mViewPool = new RecyclerView.RecycledViewPool();
         mIncludeHeader = includeHeader;
         mIncludeExpander = includeExpander;
+        mIsLayoutRtl = context.getResources().getConfiguration().getLayoutDirection()
+                == View.LAYOUT_DIRECTION_RTL;
     }
 
     /**
diff --git a/src/com/android/settings/security/SecuritySettingsFeatureProvider.java b/src/com/android/settings/security/SecuritySettingsFeatureProvider.java
new file mode 100644
index 0000000..78e4bc7
--- /dev/null
+++ b/src/com/android/settings/security/SecuritySettingsFeatureProvider.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2021 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.security;
+
+/** FeatureProvider for security settings. */
+public interface SecuritySettingsFeatureProvider {
+
+    /** Returns whether an alternative SecuritySettings fragment is available. */
+    boolean hasAlternativeSecuritySettingsFragment();
+
+    /** Returns the alternative SecuritySettings fragment name if available. */
+    String getAlternativeSecuritySettingsFragmentClassname();
+}
diff --git a/src/com/android/settings/security/SecuritySettingsFeatureProviderImpl.java b/src/com/android/settings/security/SecuritySettingsFeatureProviderImpl.java
new file mode 100644
index 0000000..8aba523
--- /dev/null
+++ b/src/com/android/settings/security/SecuritySettingsFeatureProviderImpl.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 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.security;
+
+/** Implementation for {@code SecuritySettingsFeatureProvider}. */
+public class SecuritySettingsFeatureProviderImpl implements SecuritySettingsFeatureProvider {
+
+    @Override
+    public boolean hasAlternativeSecuritySettingsFragment() {
+        return false;
+    }
+
+    @Override
+    public String getAlternativeSecuritySettingsFragmentClassname() {
+        return null;
+    }
+}
diff --git a/src/com/android/settings/security/TopLevelSecurityEntryPreferenceController.java b/src/com/android/settings/security/TopLevelSecurityEntryPreferenceController.java
index 4efc620..349a91d 100644
--- a/src/com/android/settings/security/TopLevelSecurityEntryPreferenceController.java
+++ b/src/com/android/settings/security/TopLevelSecurityEntryPreferenceController.java
@@ -19,12 +19,17 @@
 import android.content.Context;
 import android.hardware.face.FaceManager;
 import android.hardware.fingerprint.FingerprintManager;
+import android.text.TextUtils;
 import android.util.FeatureFlagUtils;
 
+import androidx.preference.Preference;
+
 import com.android.settings.R;
 import com.android.settings.Utils;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.core.FeatureFlags;
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.overlay.FeatureFactory;
 
 public class TopLevelSecurityEntryPreferenceController extends BasePreferenceController {
 
@@ -56,4 +61,28 @@
             return mContext.getText(R.string.security_dashboard_summary_no_fingerprint);
         }
     }
+
+    @Override
+    public boolean handlePreferenceTreeClick(Preference preference) {
+        if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
+            return super.handlePreferenceTreeClick(preference);
+        }
+
+        SecuritySettingsFeatureProvider securitySettingsFeatureProvider =
+                FeatureFactory.getFactory(mContext).getSecuritySettingsFeatureProvider();
+        if (securitySettingsFeatureProvider.hasAlternativeSecuritySettingsFragment()) {
+            String alternativeFragmentClassname =
+                    securitySettingsFeatureProvider
+                            .getAlternativeSecuritySettingsFragmentClassname();
+            if (alternativeFragmentClassname != null) {
+                new SubSettingLauncher(mContext)
+                        .setDestination(alternativeFragmentClassname)
+                        .setSourceMetricsCategory(getMetricsCategory())
+                        .launch();
+                return true;
+            }
+        }
+
+        return super.handlePreferenceTreeClick(preference);
+    }
 }
diff --git a/src/com/android/settings/vpn2/VpnInfoPreference.java b/src/com/android/settings/vpn2/VpnInfoPreference.java
new file mode 100644
index 0000000..cca45b5
--- /dev/null
+++ b/src/com/android/settings/vpn2/VpnInfoPreference.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2021 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.vpn2;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.View;
+
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.settings.R;
+import com.android.settingslib.HelpUtils;
+import com.android.settingslib.RestrictedPreference;
+
+
+/**
+ * A preference with an Info icon on the side
+ */
+public class VpnInfoPreference extends RestrictedPreference implements View.OnClickListener {
+
+    private boolean mIsInsecureVpn = false;
+    private String mHelpUrl;
+
+    public VpnInfoPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mHelpUrl = context.getString(R.string.help_url_insecure_vpn);
+    }
+
+    @Override
+    protected int getSecondTargetResId() {
+        // Note: in the future, we will probably want to provide a configuration option
+        // for this info to not be the warning color.
+        return R.layout.preference_widget_warning;
+    }
+
+    @Override
+    protected boolean shouldHideSecondTarget() {
+        return false;
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+        final View icon = holder.findViewById(R.id.warning_button);
+        if (mIsInsecureVpn && !TextUtils.isEmpty(mHelpUrl)) {
+            icon.setVisibility(View.VISIBLE);
+            icon.setOnClickListener(this);
+            icon.setEnabled(true);
+        } else {
+            icon.setVisibility(View.GONE);
+            icon.setOnClickListener(this);
+            icon.setEnabled(false);
+        }
+
+        // Hide the divider from view
+        final View divider = holder.findViewById(R.id.two_target_divider);
+        divider.setVisibility(View.GONE);
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (v.getId() == R.id.warning_button) {
+            final Intent intent = HelpUtils.getHelpIntent(
+                    getContext(), mHelpUrl, this.getClass().getName());
+
+            if (intent != null) {
+                ((Activity) getContext()).startActivityForResult(intent, 0);
+            }
+        }
+    }
+
+    /**
+     * Sets whether this preference corresponds to an insecure VPN. This will also affect whether
+     * the warning icon appears to the user.
+     */
+    public void setInsecureVpn(boolean isInsecureVpn) {
+        if (mIsInsecureVpn != isInsecureVpn) {
+            mIsInsecureVpn = isInsecureVpn;
+            notifyChanged();
+        }
+    }
+}
diff --git a/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java b/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java
index 211ceed..0c3f42d 100644
--- a/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java
+++ b/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java
@@ -42,6 +42,7 @@
 import android.net.NetworkRequest;
 import android.net.RouteInfo;
 import android.net.Uri;
+import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
@@ -155,6 +156,8 @@
     static final String KEY_IPV6_CATEGORY = "ipv6_category";
     @VisibleForTesting
     static final String KEY_IPV6_ADDRESSES_PREF = "ipv6_addresses";
+    @VisibleForTesting
+    static final String KEY_WIFI_TYPE_PREF = "type";
 
     private final WifiEntry mWifiEntry;
     private final ConnectivityManager mConnectivityManager;
@@ -186,6 +189,7 @@
     private Preference mGatewayPref;
     private Preference mSubnetPref;
     private Preference mDnsPref;
+    private Preference mTypePref;
     private PreferenceCategory mIpv6Category;
     private Preference mIpv6AddressPref;
     private Lifecycle mLifecycle;
@@ -382,6 +386,7 @@
         mGatewayPref = screen.findPreference(KEY_GATEWAY_PREF);
         mSubnetPref = screen.findPreference(KEY_SUBNET_MASK_PREF);
         mDnsPref = screen.findPreference(KEY_DNS_PREF);
+        mTypePref = screen.findPreference(KEY_WIFI_TYPE_PREF);
 
         mIpv6Category = screen.findPreference(KEY_IPV6_CATEGORY);
         mIpv6AddressPref = screen.findPreference(KEY_IPV6_ADDRESSES_PREF);
@@ -552,6 +557,8 @@
         refreshEapSimSubscription();
         // MAC Address Pref
         refreshMacAddress();
+        // Wifi Type
+        refreshWifiType();
     }
 
     private void refreshRssiViews() {
@@ -749,6 +756,36 @@
         }
     }
 
+    private void refreshWifiType() {
+        final ConnectedInfo connectedInfo = mWifiEntry.getConnectedInfo();
+        if (connectedInfo == null) {
+            mTypePref.setVisible(false);
+            return;
+        }
+
+        final int typeString = getWifiStandardTypeString(connectedInfo.wifiStandard);
+        if (typeString != -1) {
+            mTypePref.setSummary(typeString);
+            mTypePref.setVisible(true);
+        } else {
+            mTypePref.setVisible(false);
+        }
+    }
+
+    private int getWifiStandardTypeString(int wifiStandardType) {
+        Log.d(TAG, "Wifi Type " + wifiStandardType);
+        switch (wifiStandardType) {
+            case ScanResult.WIFI_STANDARD_11AX:
+                return R.string.wifi_type_11AX;
+            case ScanResult.WIFI_STANDARD_11AC:
+                return R.string.wifi_type_11AC;
+            case ScanResult.WIFI_STANDARD_11N:
+                return R.string.wifi_type_11N;
+            default:
+                return -1;
+        }
+    }
+
     private int getMacAddressTitle() {
         if (mWifiEntry.getPrivacy() == WifiEntry.PRIVACY_RANDOMIZED_MAC) {
             return mWifiEntry.getConnectedState() == WifiEntry.CONNECTED_STATE_CONNECTED
diff --git a/src/com/android/settings/wifi/slice/WifiSlice.java b/src/com/android/settings/wifi/slice/WifiSlice.java
index 898de56..e4a571d 100644
--- a/src/com/android/settings/wifi/slice/WifiSlice.java
+++ b/src/com/android/settings/wifi/slice/WifiSlice.java
@@ -164,7 +164,7 @@
         return rowBuilder;
     }
 
-    private IconCompat getWifiSliceItemLevelIcon(WifiSliceItem wifiSliceItem) {
+    protected IconCompat getWifiSliceItemLevelIcon(WifiSliceItem wifiSliceItem) {
         final @ColorInt int tint;
         if (wifiSliceItem.getConnectedState() == WifiEntry.CONNECTED_STATE_CONNECTED) {
             tint = Utils.getColorAccentDefaultColor(mContext);
diff --git a/src/com/android/settings/wifi/tether/WifiTetherBasePreferenceController.java b/src/com/android/settings/wifi/tether/WifiTetherBasePreferenceController.java
index 46da097..a950dc3 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherBasePreferenceController.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherBasePreferenceController.java
@@ -45,8 +45,8 @@
             OnTetherConfigUpdateListener listener) {
         super(context);
         mListener = listener;
-        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
-        mTm = (TetheringManager) context.getSystemService(Context.TETHERING_SERVICE);
+        mWifiManager = context.getSystemService(WifiManager.class);
+        mTm = context.getSystemService(TetheringManager.class);
         mWifiRegexs = mTm.getTetherableWifiRegexs();
     }
 
diff --git a/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceController.java b/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceController.java
index bc87d5c..41532d0 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceController.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceController.java
@@ -86,7 +86,11 @@
         if (mWifiManager.isBridgedApConcurrencySupported()) {
             final boolean isEnabled = config.isBridgedModeOpportunisticShutdownEnabled();
             Log.d(TAG, "isBridgedModeOpportunisticShutdownEnabled:" + isEnabled);
-            return isEnabled;
+            // Because the return value defined by the Wi-Fi framework API is opposite to the UI.
+            //   Compatibility on:  isBridgedModeOpportunisticShutdownEnabled() = false
+            //   Compatibility off: isBridgedModeOpportunisticShutdownEnabled() = true
+            // Need to return the reverse value.
+            return !isEnabled;
         }
 
         // If the BridgedAp Concurrency is not supported in early Pixel devices (e.g. Pixel 2~5),
@@ -112,7 +116,11 @@
                     SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ};
             builder.setBands(bands);
             Log.d(TAG, "setBridgedModeOpportunisticShutdownEnabled:" + enabled);
-            builder.setBridgedModeOpportunisticShutdownEnabled(enabled);
+            // Because the defined value by the Wi-Fi framework API is opposite to the UI.
+            //   Compatibility on:  setBridgedModeOpportunisticShutdownEnabled(false)
+            //   Compatibility off: setBridgedModeOpportunisticShutdownEnabled(true)
+            // Need to set the reverse value.
+            builder.setBridgedModeOpportunisticShutdownEnabled(!enabled);
         } else {
             int band = enabled
                     ? SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ
diff --git a/tests/robotests/src/com/android/settings/accessibility/ReduceBrightColorsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/ReduceBrightColorsPreferenceControllerTest.java
index 39a663e..01942f0 100644
--- a/tests/robotests/src/com/android/settings/accessibility/ReduceBrightColorsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/ReduceBrightColorsPreferenceControllerTest.java
@@ -19,7 +19,6 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import android.content.Context;
-import android.provider.Settings;
 
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -32,29 +31,14 @@
 @RunWith(AndroidJUnit4.class)
 public class ReduceBrightColorsPreferenceControllerTest {
     private static final String PREF_KEY = "rbc_preference";
-    private static final String RBC_ACTIVATED =
-            Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED;
-    private static final int ON = 1;
-    private static final int OFF = 0;
 
     private final Context mContext = ApplicationProvider.getApplicationContext();
     private final ReduceBrightColorsPreferenceController mController =
             new ReduceBrightColorsPreferenceController(mContext, PREF_KEY);
 
     @Test
-    public void getSummary_enabledRbc_shouldReturnOnSummary() {
-        Settings.Secure.putInt(mContext.getContentResolver(),
-                RBC_ACTIVATED, ON);
-
+    public void getSummary_returnSummary() {
         assertThat(mController.getSummary().toString().contains(
-                mContext.getText(R.string.accessibility_feature_state_on))).isTrue();
-    }
-    @Test
-    public void getSummary_disabledRbc_shouldReturnOffSummary() {
-        Settings.Secure.putInt(mContext.getContentResolver(),
-                RBC_ACTIVATED, OFF);
-
-        assertThat(mController.getSummary().toString().contains(
-                mContext.getText(R.string.accessibility_feature_state_off))).isTrue();
+                mContext.getText(R.string.reduce_bright_colors_preference_summary))).isTrue();
     }
 }
diff --git a/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java
index b22b156..4b6a6a8 100644
--- a/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java
@@ -39,6 +39,7 @@
 import android.text.TextUtils;
 
 import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
 import androidx.preference.PreferenceGroup;
 import androidx.preference.PreferenceManager;
 import androidx.preference.PreferenceScreen;
@@ -72,9 +73,13 @@
         ShadowSettingsLibUtils.class})
 public class AccountPreferenceControllerTest {
 
+    private static final String PREF_KEY_ACCOUNTS = "accounts_category";
+
     @Mock(answer = RETURNS_DEEP_STUBS)
     private PreferenceScreen mScreen;
     @Mock(answer = RETURNS_DEEP_STUBS)
+    private PreferenceCategory mAccountsCategory;
+    @Mock(answer = RETURNS_DEEP_STUBS)
     private UserManager mUserManager;
     @Mock(answer = RETURNS_DEEP_STUBS)
     private SettingsPreferenceFragment mFragment;
@@ -95,6 +100,9 @@
         shadowApp.setSystemService(Context.ACCOUNT_SERVICE, mAccountManager);
 
         when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
+        // This is a bit ugly, but hard to avoid because of how the mocks are used in these tests.
+        // TODO: Refactor these tests to not use RETURNS_DEEP_STUBS.
+        when(mScreen.findPreference(PREF_KEY_ACCOUNTS)).thenReturn(mScreen);
         when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext);
         when(mAccountManager.getAuthenticatorTypesAsUser(anyInt()))
                 .thenReturn(new AuthenticatorDescription[0]);
@@ -166,6 +174,7 @@
         // First time resume will build the UI
         mController.onResume();
         reset(mScreen);
+        when(mScreen.findPreference(PREF_KEY_ACCOUNTS)).thenReturn(mScreen);
 
         mController.onResume();
         verify(mScreen, never()).addPreference(any(PreferenceGroup.class));
@@ -184,6 +193,7 @@
         // add a new profile
         infos.add(new UserInfo(2, "user 2", UserInfo.FLAG_MANAGED_PROFILE));
         reset(mScreen);
+        when(mScreen.findPreference(PREF_KEY_ACCOUNTS)).thenReturn(mScreen);
 
         mController.onResume();
         verify(mScreen, times(1)).addPreference(any(PreferenceGroup.class));
diff --git a/tests/robotests/src/com/android/settings/accounts/AvatarViewMixinTest.java b/tests/robotests/src/com/android/settings/accounts/AvatarViewMixinTest.java
index 534d3c6..04db527 100644
--- a/tests/robotests/src/com/android/settings/accounts/AvatarViewMixinTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/AvatarViewMixinTest.java
@@ -27,7 +27,6 @@
 import static org.mockito.Mockito.verify;
 
 import android.accounts.Account;
-import android.app.ActivityManager;
 import android.content.ContentProvider;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -57,7 +56,6 @@
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
 import org.robolectric.shadow.api.Shadow;
-import org.robolectric.shadows.ShadowActivityManager;
 import org.robolectric.shadows.ShadowContentResolver;
 import org.robolectric.shadows.ShadowPackageManager;
 
@@ -97,31 +95,7 @@
     }
 
     @Test
-    public void onStart_configDisabled_doNothing() {
-        final AvatarViewMixin mixin = spy(new AvatarViewMixin(mActivity, mImageView));
-        mixin.onStart();
-
-        verify(mixin, never()).hasAccount();
-    }
-
-    @Test
-    public void onStart_lowRamDevice_doNothing() {
-        final AvatarViewMixin mixin = spy(new AvatarViewMixin(mActivity, mImageView));
-
-        final ShadowActivityManager activityManager =
-                Shadow.extract(mContext.getSystemService(ActivityManager.class));
-        activityManager.setIsLowRamDevice(true);
-
-        mixin.onStart();
-
-        verify(mixin, never()).hasAccount();
-    }
-
-    @Test
-    @Config(qualifiers = "mcc999",
-            shadows = {
-                    BatteryFixSliceTest.ShadowBatteryTipLoader.class
-            })
+    @Config(shadows = BatteryFixSliceTest.ShadowBatteryTipLoader.class)
     public void onStart_useMockAvatarViewMixin_shouldBeExecuted() {
         final AvatarViewMixin mockAvatar = spy(new AvatarViewMixin(mActivity, mImageView));
 
@@ -132,7 +106,6 @@
     }
 
     @Test
-    @Config(qualifiers = "mcc999")
     public void onStart_noAccount_mAccountNameShouldBeNull() {
         final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(mActivity, mImageView);
         avatarViewMixin.mAccountName = FAKE_ACCOUNT;
diff --git a/tests/robotests/src/com/android/settings/accounts/TopLevelAccountEntryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/TopLevelAccountEntryPreferenceControllerTest.java
index 3a67d7f..1d63cd1 100644
--- a/tests/robotests/src/com/android/settings/accounts/TopLevelAccountEntryPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/TopLevelAccountEntryPreferenceControllerTest.java
@@ -23,64 +23,33 @@
 
 import com.android.settings.R;
 import com.android.settings.core.FeatureFlags;
-import com.android.settings.testutils.shadow.ShadowAuthenticationHelper;
 
-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.annotation.Config;
 
 @RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowAuthenticationHelper.class})
 public class TopLevelAccountEntryPreferenceControllerTest {
 
     private TopLevelAccountEntryPreferenceController mController;
     private Context mContext;
-    private String[] LABELS;
-    private String[] TYPES;
 
     @Before
     public void setUp() {
         mContext = RuntimeEnvironment.application;
         mController = new TopLevelAccountEntryPreferenceController(mContext, "test_key");
-        LABELS = ShadowAuthenticationHelper.getLabels();
-        TYPES = ShadowAuthenticationHelper.getTypes();
         FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, false);
     }
 
-    @After
-    public void tearDown() {
-        ShadowAuthenticationHelper.reset();
-    }
-
-    @Test
-    public void updateSummary_hasAccount_shouldDisplayUpTo3AccountTypes() {
-        assertThat(mController.getSummary())
-                .isEqualTo(LABELS[0] + ", " + LABELS[1] + ", and " + LABELS[2]);
-    }
-
     @Test
     public void updateSummary_noAccount_shouldDisplayDefaultSummary() {
-        ShadowAuthenticationHelper.setEnabledAccount(null);
-
         assertThat(mController.getSummary()).isEqualTo(
                 mContext.getText(R.string.account_dashboard_default_summary));
     }
 
     @Test
-    public void updateSummary_noAccountTypeLabel_shouldNotDisplayNullEntry() {
-        final String[] enabledAccounts = {TYPES[0], "unlabeled_account_type", TYPES[1]};
-        ShadowAuthenticationHelper.setEnabledAccount(enabledAccounts);
-
-
-        // should only show the 2 accounts with labels
-        assertThat(mController.getSummary()).isEqualTo(LABELS[0] + " and " + LABELS[1]);
-    }
-
-    @Test
     public void getSummary_silkyHomeEnabled_shouldBeNull() {
         FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, true);
 
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceControllerTest.java
index 849f2ac..1073256 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceControllerTest.java
@@ -37,7 +37,7 @@
 import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 
-import com.android.settings.applications.AppLaunchSettings;
+import com.android.settings.applications.intentpicker.AppLaunchSettings;
 import com.android.settingslib.applications.AppUtils;
 import com.android.settingslib.applications.ApplicationsState.AppEntry;
 import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
diff --git a/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java
index c8891e5..8e03d68 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java
@@ -62,6 +62,9 @@
     private static final int BATTERY_LEVEL_RIGHT = 45;
     private static final int LOW_BATTERY_LEVEL = 15;
     private static final int CASE_LOW_BATTERY_LEVEL = 19;
+    private static final int LOW_BATTERY_LEVEL_THRESHOLD = 15;
+    private static final int BATTERY_LEVEL_5 = 5;
+    private static final int BATTERY_LEVEL_50 = 50;
     private static final String ICON_URI = "content://test.provider/icon.png";
     private static final String MAC_ADDRESS = "04:52:C7:0B:D8:3C";
 
@@ -202,6 +205,70 @@
     }
 
     @Test
+    public void refresh_underLowBatteryThreshold_showAlertIcon() {
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn(
+                BluetoothDevice.DEVICE_TYPE_WATCH.getBytes());
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_MAIN_BATTERY)).thenReturn(
+                String.valueOf(BATTERY_LEVEL_5).getBytes());
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD)).thenReturn(
+                String.valueOf(LOW_BATTERY_LEVEL_THRESHOLD).getBytes());
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_MAIN_CHARGING)).thenReturn(
+                String.valueOf(false).getBytes());
+        when(mCachedDevice.isConnected()).thenReturn(true);
+
+        mController.refresh();
+
+        assertBatteryIcon(mLayoutPreference.findViewById(R.id.layout_middle),
+                R.drawable.ic_battery_alert_24dp);
+    }
+
+    @Test
+    public void refresh_underLowBatteryThresholdInCharging_showAlertIcon() {
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn(
+                BluetoothDevice.DEVICE_TYPE_WATCH.getBytes());
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_MAIN_BATTERY)).thenReturn(
+                String.valueOf(BATTERY_LEVEL_5).getBytes());
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD)).thenReturn(
+                String.valueOf(LOW_BATTERY_LEVEL_THRESHOLD).getBytes());
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_MAIN_CHARGING)).thenReturn(
+                String.valueOf(true).getBytes());
+        when(mCachedDevice.isConnected()).thenReturn(true);
+
+        mController.refresh();
+
+        assertBatteryIcon(mLayoutPreference.findViewById(R.id.layout_middle), /* resId= */-1);
+    }
+
+    @Test
+    public void refresh_aboveLowBatteryThreshold_noAlertIcon() {
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn(
+                BluetoothDevice.DEVICE_TYPE_WATCH.getBytes());
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_MAIN_BATTERY)).thenReturn(
+                String.valueOf(BATTERY_LEVEL_50).getBytes());
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD)).thenReturn(
+                String.valueOf(LOW_BATTERY_LEVEL_THRESHOLD).getBytes());
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_MAIN_CHARGING)).thenReturn(
+                String.valueOf(false).getBytes());
+        when(mCachedDevice.isConnected()).thenReturn(true);
+
+        mController.refresh();
+
+        assertBatteryIcon(mLayoutPreference.findViewById(R.id.layout_middle), /* resId= */-1);
+    }
+
+    @Test
     public void refresh_withLowBatteryAndUncharged_showAlertIcon() {
         when(mBluetoothDevice.getMetadata(
                 BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn(
diff --git a/tests/robotests/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceControllerTest.java
index 68b2990..1262b50 100644
--- a/tests/robotests/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceControllerTest.java
@@ -24,6 +24,7 @@
 
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
 import android.app.time.Capabilities;
@@ -36,10 +37,13 @@
 import android.os.UserHandle;
 
 import com.android.settings.R;
+import com.android.settings.core.InstrumentedPreferenceFragment;
+import com.android.settingslib.core.lifecycle.Lifecycle;
 
 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;
@@ -53,6 +57,10 @@
     private LocationManager mLocationManager;
     private Context mContext;
     private LocationTimeZoneDetectionPreferenceController mController;
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private InstrumentedPreferenceFragment mFragment;
+    @Mock
+    private Lifecycle mLifecycle;
 
     @Before
     public void setUp() {
@@ -60,11 +68,14 @@
         mContext = spy(RuntimeEnvironment.application);
         when(mContext.getSystemService(TimeManager.class)).thenReturn(mTimeManager);
         when(mContext.getSystemService(LocationManager.class)).thenReturn(mLocationManager);
-        mController = new LocationTimeZoneDetectionPreferenceController(mContext, "key");
+        mController = new LocationTimeZoneDetectionPreferenceController(mContext);
+        mController.setFragment(mFragment);
     }
 
     @Test
-    public void setChecked_withTrue_shouldUpdateSetting() {
+    public void setChecked_withTrue_shouldUpdateSetting_whenLocationIsEnabled() {
+        when(mLocationManager.isLocationEnabled()).thenReturn(true);
+
         // Simulate the UI being clicked.
         mController.setChecked(true);
 
@@ -76,6 +87,17 @@
     }
 
     @Test
+    public void setChecked_withTrue_shouldDoNothing_whenLocationIsDisabled() {
+        when(mLocationManager.isLocationEnabled()).thenReturn(false);
+
+        // Simulate the UI being clicked.
+        mController.setChecked(true);
+
+        // Verify the TimeManager was not called.
+        verifyZeroInteractions(mTimeManager);
+    }
+
+    @Test
     public void setChecked_withFalse_shouldUpdateSetting() {
         // Simulate the UI being clicked.
         mController.setChecked(false);
diff --git a/tests/robotests/src/com/android/settings/datetime/timezone/model/TimeZoneDataTest.java b/tests/robotests/src/com/android/settings/datetime/timezone/model/TimeZoneDataTest.java
index d21aa04..784b3bb 100644
--- a/tests/robotests/src/com/android/settings/datetime/timezone/model/TimeZoneDataTest.java
+++ b/tests/robotests/src/com/android/settings/datetime/timezone/model/TimeZoneDataTest.java
@@ -92,4 +92,23 @@
                 .containsExactly("US", "GB");
         assertThat(timeZoneData.lookupCountryCodesForZoneId("Unknown/Secret_City2")).isEmpty();
     }
+
+    @Test
+    public void lookupCountryCodesForNonCanonicalZoneId_returnsCurrentZone() {
+        TimeZoneData timeZoneData = new TimeZoneData(mCountryZonesFinder);
+
+        CountryTimeZones greenland = mock(CountryTimeZones.class);
+        when(greenland.getCountryIso()).thenReturn("gl");
+        when(greenland.getTimeZoneMappings()).thenReturn(Arrays.asList(
+                TimeZoneMapping.createForTests(
+                        "America/Nuuk",
+                        true /* showInPicker */,
+                        null /* notUsedAfter */,
+                        Arrays.asList("America/Godthab"))));
+        when(mCountryZonesFinder.lookupCountryTimeZonesForZoneId("America/Godthab"))
+                .thenReturn(Arrays.asList(greenland));
+
+        assertThat(timeZoneData.lookupCountryCodesForZoneId("America/Godthab"))
+                .containsExactly("GL");
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/development/DefaultUsbConfigurationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/DefaultUsbConfigurationPreferenceControllerTest.java
index 15f4eb9..c9b13e27 100644
--- a/tests/robotests/src/com/android/settings/development/DefaultUsbConfigurationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/DefaultUsbConfigurationPreferenceControllerTest.java
@@ -91,4 +91,27 @@
         verify(mPreference).setDisabledByAdmin(eq(new RestrictedLockUtils.EnforcedAdmin(
                 TEST_COMPONENT_NAME, null, UserHandle.SYSTEM)));
     }
+
+    @Test
+    public void onDeveloperOptionsSwitchEnabled_usbEnabled_shouldNotDisablePreference() {
+        when(mDevicePolicyManager.isUsbDataSignalingEnabledForUser(
+                UserHandle.myUserId())).thenReturn(true);
+        when(mDevicePolicyManager.getProfileOwner()).thenReturn(TEST_COMPONENT_NAME);
+
+        mController.onDeveloperOptionsSwitchEnabled();
+
+        verify(mPreference).setDisabledByAdmin(null);
+    }
+
+    @Test
+    public void onDeveloperOptionsSwitchEnabled_usbDisabled_shouldDisablePreference() {
+        when(mDevicePolicyManager.isUsbDataSignalingEnabledForUser(
+                UserHandle.myUserId())).thenReturn(false);
+        when(mDevicePolicyManager.getProfileOwner()).thenReturn(TEST_COMPONENT_NAME);
+
+        mController.onDeveloperOptionsSwitchEnabled();
+
+        verify(mPreference).setDisabledByAdmin(eq(new RestrictedLockUtils.EnforcedAdmin(
+                TEST_COMPONENT_NAME, null, UserHandle.SYSTEM)));
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/development/UsbAudioRoutingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/UsbAudioRoutingPreferenceControllerTest.java
index 1d45c1b..69d2c99 100644
--- a/tests/robotests/src/com/android/settings/development/UsbAudioRoutingPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/UsbAudioRoutingPreferenceControllerTest.java
@@ -147,4 +147,27 @@
         verify(mPreference).setEnabled(false);
         verify(mPreference).setChecked(false);
     }
+
+    @Test
+    public void onDeveloperOptionsSwitchEnabled_usbEnabled_shouldNotDisablePreference() {
+        when(mDevicePolicyManager.isUsbDataSignalingEnabledForUser(
+                UserHandle.myUserId())).thenReturn(true);
+        when(mDevicePolicyManager.getProfileOwner()).thenReturn(TEST_COMPONENT_NAME);
+
+        mController.onDeveloperOptionsSwitchEnabled();
+
+        verify(mPreference).setDisabledByAdmin(null);
+    }
+
+    @Test
+    public void onDeveloperOptionsSwitchEnabled_usbDisabled_shouldDisablePreference() {
+        when(mDevicePolicyManager.isUsbDataSignalingEnabledForUser(
+                UserHandle.myUserId())).thenReturn(false);
+        when(mDevicePolicyManager.getProfileOwner()).thenReturn(TEST_COMPONENT_NAME);
+
+        mController.onDeveloperOptionsSwitchEnabled();
+
+        verify(mPreference).setDisabledByAdmin(eq(new RestrictedLockUtils.EnforcedAdmin(
+                TEST_COMPONENT_NAME, null, UserHandle.SYSTEM)));
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/StorageItemPreferenceTest.java b/tests/robotests/src/com/android/settings/deviceinfo/StorageItemPreferenceTest.java
index 06194b4..5795157 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/StorageItemPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/StorageItemPreferenceTest.java
@@ -69,4 +69,11 @@
         assertThat(progressBar).isNotNull();
         assertThat(progressBar.getProgress()).isEqualTo(10);
     }
+
+    @Test
+    public void getStorageSize_setStorageSize_getCorrectStorageSize() {
+        mPreference.setStorageSize(MEGABYTE_IN_BYTES, MEGABYTE_IN_BYTES * 10);
+
+        assertThat(mPreference.getStorageSize()).isEqualTo(MEGABYTE_IN_BYTES);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceControllerTest.java
index d1371a2..384ddc3 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceControllerTest.java
@@ -22,12 +22,14 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.res.Resources;
 import android.os.SystemProperties;
 import android.provider.Settings;
 
@@ -38,6 +40,7 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.os.RoSystemProperties;
+import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.deletionhelper.ActivationWarningFragment;
 import com.android.settings.overlay.FeatureFactory;
@@ -67,13 +70,16 @@
     private FragmentManager mFragmentManager;
 
     private Context mContext;
+    private Resources mResources;
     private AutomaticStorageManagementSwitchPreferenceController mController;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application.getApplicationContext();
+        mContext = spy(RuntimeEnvironment.application.getApplicationContext());
         FeatureFactory.getFactory(mContext);
+        mResources = spy(mContext.getResources());
+        when(mContext.getResources()).thenReturn(mResources);
 
         mController = new AutomaticStorageManagementSwitchPreferenceController(mContext, "testkey");
         mController.setFragmentManager(mFragmentManager);
@@ -81,14 +87,27 @@
     }
 
     @Test
-    public void isAvailable_shouldReturnTrue_forHighRamDevice() {
+    public void getAvailabilityStatus_configFalse_shouldUnsupportedOnDevice() {
+        when(mResources.getBoolean(R.bool.config_show_smart_storage_toggle)).thenReturn(false);
+
+        assertThat(mController.isAvailable()).isFalse();
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BasePreferenceController.UNSUPPORTED_ON_DEVICE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_forHighRamDevice_shouldAvailable() {
+        when(mResources.getBoolean(R.bool.config_show_smart_storage_toggle)).thenReturn(true);
+
         assertThat(mController.isAvailable()).isTrue();
         assertThat(mController.getAvailabilityStatus()).isEqualTo(
                 BasePreferenceController.AVAILABLE);
     }
 
     @Test
-    public void isAvailable_shouldAlwaysReturnFalse_forLowRamDevice() {
+    public void getAvailabilityStatus_forLowRamDevice_shouldUnsupportedOnDevice() {
+        when(mResources.getBoolean(R.bool.config_show_smart_storage_toggle)).thenReturn(true);
+
         ReflectionHelpers.setStaticField(RoSystemProperties.class, "CONFIG_LOW_RAM", true);
         assertThat(mController.isAvailable()).isFalse();
         assertThat(mController.getAvailabilityStatus()).isEqualTo(
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
index 5e49aa0..b7bf7f5 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
@@ -43,7 +43,6 @@
 import androidx.fragment.app.FragmentTransaction;
 import androidx.preference.PreferenceScreen;
 
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.SubSettings;
@@ -51,10 +50,8 @@
 import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
 import com.android.settings.deviceinfo.PrivateVolumeSettings;
 import com.android.settings.deviceinfo.StorageItemPreference;
-import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.shadow.ShadowUserManager;
 import com.android.settingslib.applications.StorageStatsSource;
-import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.deviceinfo.StorageVolumeProvider;
 
 import org.junit.Before;
@@ -84,8 +81,7 @@
     private FragmentTransaction mFragmentTransaction;
     private StorageItemPreferenceController mController;
     private StorageItemPreference mPreference;
-    private FakeFeatureFactory mFakeFeatureFactory;
-    private MetricsFeatureProvider mMetricsFeatureProvider;
+    private PreferenceScreen mPreferenceScreen;
 
     @Before
     public void setUp() {
@@ -94,8 +90,6 @@
         when(mFragment.getFragmentManager()).thenReturn(mFragmentManager);
         when(mFragmentManager.beginTransaction()).thenReturn(mFragmentTransaction);
         mContext = spy(RuntimeEnvironment.application.getApplicationContext());
-        mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
-        mMetricsFeatureProvider = mFakeFeatureFactory.getMetricsFeatureProvider();
         mVolume = spy(new VolumeInfo("id", 0, null, "id"));
         // Note: null is passed as the Lifecycle because we are handling it outside of the normal
         //       Settings fragment lifecycle for test purposes.
@@ -105,6 +99,51 @@
         // Inflate the preference and the widget.
         final LayoutInflater inflater = LayoutInflater.from(mContext);
         inflater.inflate(mPreference.getLayoutResource(), new LinearLayout(mContext), false);
+
+        mPreferenceScreen = getPreferenceScreen();
+    }
+
+    private PreferenceScreen getPreferenceScreen() {
+        final StorageItemPreference publicStorage = spy(new StorageItemPreference(mContext));
+        publicStorage.setIcon(R.drawable.ic_folder_vd_theme_24);
+        final StorageItemPreference images = spy(new StorageItemPreference(mContext));
+        images.setIcon(R.drawable.ic_photo_library);
+        final StorageItemPreference videos = spy(new StorageItemPreference(mContext));
+        videos.setIcon(R.drawable.ic_local_movies);
+        final StorageItemPreference audios = spy(new StorageItemPreference(mContext));
+        audios.setIcon(R.drawable.ic_media_stream);
+        final StorageItemPreference apps = spy(new StorageItemPreference(mContext));
+        apps.setIcon(R.drawable.ic_storage_apps);
+        final StorageItemPreference games = spy(new StorageItemPreference(mContext));
+        games.setIcon(R.drawable.ic_videogame_vd_theme_24);
+        final StorageItemPreference documentsAndOther = spy(new StorageItemPreference(mContext));
+        documentsAndOther.setIcon(R.drawable.ic_folder_vd_theme_24);
+        final StorageItemPreference system = spy(new StorageItemPreference(mContext));
+        system.setIcon(R.drawable.ic_system_update);
+        final StorageItemPreference trash = spy(new StorageItemPreference(mContext));
+        trash.setIcon(R.drawable.ic_trash_can);
+
+        final PreferenceScreen screen = mock(PreferenceScreen.class);
+        when(screen.findPreference(eq(StorageItemPreferenceController.PUBLIC_STORAGE_KEY)))
+                .thenReturn(publicStorage);
+        when(screen.findPreference(eq(StorageItemPreferenceController.IMAGES_KEY)))
+                .thenReturn(images);
+        when(screen.findPreference(eq(StorageItemPreferenceController.VIDEOS_KEY)))
+                .thenReturn(videos);
+        when(screen.findPreference(eq(StorageItemPreferenceController.AUDIOS_KEY)))
+                .thenReturn(audios);
+        when(screen.findPreference(eq(StorageItemPreferenceController.APPS_KEY)))
+                .thenReturn(apps);
+        when(screen.findPreference(eq(StorageItemPreferenceController.GAMES_KEY)))
+                .thenReturn(games);
+        when(screen.findPreference(eq(StorageItemPreferenceController.DOCUMENTS_AND_OTHER_KEY)))
+                .thenReturn(documentsAndOther);
+        when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
+                .thenReturn(system);
+        when(screen.findPreference(eq(StorageItemPreferenceController.TRASH_KEY)))
+                .thenReturn(trash);
+
+        return screen;
     }
 
     @Test
@@ -114,8 +153,26 @@
     }
 
     @Test
-    public void testClickPhotos() {
-        mPreference.setKey("pref_photos_videos");
+    public void launchPublicStorageIntent_nonNullBrowseIntent_settingsIntent() {
+        final String fakeBrowseAction = "FAKE_BROWSE_ACTION";
+        final Intent fakeBrowseIntent = new Intent(fakeBrowseAction);
+        // mContext is not the activity, add FLAG_ACTIVITY_NEW_TASK to avoid AndroidRuntimeException
+        // during this test.
+        fakeBrowseIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        when(mVolume.buildBrowseIntent()).thenReturn(fakeBrowseIntent);
+        mPreference.setKey(StorageItemPreferenceController.PUBLIC_STORAGE_KEY);
+        mController.handlePreferenceTreeClick(mPreference);
+
+        final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mContext).startActivity(argumentCaptor.capture());
+
+        final Intent intent = argumentCaptor.getValue();
+        assertThat(intent.getAction()).isEqualTo(fakeBrowseAction);
+    }
+
+    @Test
+    public void launchImagesIntent_resolveActionViewNull_settingsIntent() {
+        mPreference.setKey(StorageItemPreferenceController.IMAGES_KEY);
         mController.handlePreferenceTreeClick(mPreference);
 
         final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
@@ -132,8 +189,8 @@
     }
 
     @Test
-    public void testClickAudio() {
-        mPreference.setKey("pref_music_audio");
+    public void launchAudiosIntent_resolveActionViewNull_settingsIntent() {
+        mPreference.setKey(StorageItemPreferenceController.AUDIOS_KEY);
         mController.handlePreferenceTreeClick(mPreference);
 
         final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
@@ -151,16 +208,25 @@
     }
 
     @Test
-    public void handlePreferenceTreeClick_tappingAudioWhileUninitializedDoesntCrash() {
+    public void setVolume_nullVolume_hidePreferences() {
+        mController.displayPreference(mPreferenceScreen);
+
         mController.setVolume(null);
 
-        mPreference.setKey("pref_music_audio");
-        mController.handlePreferenceTreeClick(mPreference);
+        assertThat(mController.mPublicStoragePreference.isVisible()).isFalse();
+        assertThat(mController.mImagesPreference.isVisible()).isFalse();
+        assertThat(mController.mVideosPreference.isVisible()).isFalse();
+        assertThat(mController.mAudiosPreference.isVisible()).isFalse();
+        assertThat(mController.mAppsPreference.isVisible()).isFalse();
+        assertThat(mController.mGamesPreference.isVisible()).isFalse();
+        assertThat(mController.mDocumentsAndOtherPreference.isVisible()).isFalse();
+        assertThat(mController.mSystemPreference.isVisible()).isFalse();
+        assertThat(mController.mTrashPreference.isVisible()).isFalse();
     }
 
     @Test
-    public void testClickApps() {
-        mPreference.setKey("pref_other_apps");
+    public void launchAppsIntent_forPersonal_settingsIntent() {
+        mPreference.setKey(StorageItemPreferenceController.APPS_KEY);
         mController.handlePreferenceTreeClick(mPreference);
 
         final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
@@ -177,9 +243,9 @@
     }
 
     @Test
-    public void testClickAppsForWork() {
+    public void launchAppsIntent_forWork_settingsIntent() {
         mController = new StorageItemPreferenceController(mContext, mFragment, mVolume, mSvp, true);
-        mPreference.setKey("pref_other_apps");
+        mPreference.setKey(StorageItemPreferenceController.APPS_KEY);
         mController.handlePreferenceTreeClick(mPreference);
 
         final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
@@ -204,18 +270,10 @@
     }
 
     @Test
-    public void handlePreferenceTreeClick_tappingAppsWhileUninitializedDoesntCrash() {
-        mController.setVolume(null);
-
-        mPreference.setKey("pref_other_apps");
-        mController.handlePreferenceTreeClick(mPreference);
-    }
-
-    @Test
-    public void testClickFiles() {
+    public void launchDocumentsAndOtherIntent_resolveActionViewNull_settingsIntent() {
         when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(mVolume);
         when(mVolume.buildBrowseIntent()).thenReturn(new Intent());
-        mPreference.setKey("pref_files");
+        mPreference.setKey(StorageItemPreferenceController.DOCUMENTS_AND_OTHER_KEY);
         assertThat(mController.handlePreferenceTreeClick(mPreference))
             .isTrue();
 
@@ -227,13 +285,11 @@
         Intent browseIntent = mVolume.buildBrowseIntent();
         assertThat(intent.getAction()).isEqualTo(browseIntent.getAction());
         assertThat(intent.getData()).isEqualTo(browseIntent.getData());
-        verify(mMetricsFeatureProvider, times(1))
-            .action(nullable(Context.class), eq(MetricsEvent.STORAGE_FILES));
     }
 
     @Test
-    public void testClickGames() {
-        mPreference.setKey("pref_games");
+    public void launchGamesIntent_settingsIntent() {
+        mPreference.setKey(StorageItemPreferenceController.GAMES_KEY);
         mController.handlePreferenceTreeClick(mPreference);
 
         final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
@@ -250,8 +306,8 @@
     }
 
     @Test
-    public void testClickMovies() {
-        mPreference.setKey("pref_movies");
+    public void launchVideosIntent_resolveActionViewNull_settingsIntent() {
+        mPreference.setKey(StorageItemPreferenceController.VIDEOS_KEY);
         mController.handlePreferenceTreeClick(mPreference);
 
         final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
@@ -269,7 +325,7 @@
 
     @Test
     public void testClickSystem() {
-        mPreference.setKey("pref_system");
+        mPreference.setKey(StorageItemPreferenceController.SYSTEM_KEY);
         assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue();
 
         verify(mFragment.getFragmentManager().beginTransaction())
@@ -279,29 +335,7 @@
     @Test
     @Config(shadows = ShadowUserManager.class)
     public void testMeasurementCompletedUpdatesPreferences() {
-        final StorageItemPreference audio = new StorageItemPreference(mContext);
-        final StorageItemPreference image = new StorageItemPreference(mContext);
-        final StorageItemPreference games = new StorageItemPreference(mContext);
-        final StorageItemPreference movies = new StorageItemPreference(mContext);
-        final StorageItemPreference apps = new StorageItemPreference(mContext);
-        final StorageItemPreference system = new StorageItemPreference(mContext);
-        final StorageItemPreference files = new StorageItemPreference(mContext);
-        final PreferenceScreen screen = mock(PreferenceScreen.class);
-        when(screen.findPreference(eq(StorageItemPreferenceController.GAME_KEY)))
-            .thenReturn(games);
-        when(screen.findPreference(eq(StorageItemPreferenceController.AUDIO_KEY)))
-            .thenReturn(audio);
-        when(screen.findPreference(eq(StorageItemPreferenceController.PHOTO_KEY)))
-            .thenReturn(image);
-        when(screen.findPreference(eq(StorageItemPreferenceController.FILES_KEY)))
-            .thenReturn(files);
-        when(screen.findPreference(eq(StorageItemPreferenceController.MOVIES_KEY)))
-            .thenReturn(movies);
-        when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
-            .thenReturn(system);
-        when(screen.findPreference(eq(StorageItemPreferenceController.OTHER_APPS_KEY)))
-            .thenReturn(apps);
-        mController.displayPreference(screen);
+        mController.displayPreference(mPreferenceScreen);
 
         mController.setUsedSize(MEGABYTE_IN_BYTES * 970); // There should 870MB attributed.
         final StorageAsyncLoader.AppsStorageResult result =
@@ -321,211 +355,113 @@
         results.put(0, result);
         mController.onLoadFinished(results, 0);
 
-        assertThat(audio.getSummary().toString()).isEqualTo("0.14 GB");
-        assertThat(image.getSummary().toString()).isEqualTo("0.35 GB");
-        assertThat(games.getSummary().toString()).isEqualTo("0.08 GB");
-        assertThat(movies.getSummary().toString()).isEqualTo("0.16 GB");
-        assertThat(apps.getSummary().toString()).isEqualTo("0.09 GB");
-        assertThat(files.getSummary().toString()).isEqualTo("0.05 GB");
+        assertThat(mController.mImagesPreference.getSummary().toString()).isEqualTo("0.35 GB");
+        assertThat(mController.mVideosPreference.getSummary().toString()).isEqualTo("0.16 GB");
+        assertThat(mController.mAudiosPreference.getSummary().toString()).isEqualTo("0.14 GB");
+        assertThat(mController.mAppsPreference.getSummary().toString()).isEqualTo("0.09 GB");
+        assertThat(mController.mGamesPreference.getSummary().toString()).isEqualTo("0.08 GB");
+        assertThat(mController.mDocumentsAndOtherPreference.getSummary().toString())
+                .isEqualTo("0.05 GB");
     }
 
     @Test
     public void settingUserIdAppliesNewIcons() {
-        final StorageItemPreference audio = spy(new StorageItemPreference(mContext));
-        audio.setIcon(R.drawable.ic_media_stream);
-        final StorageItemPreference video = spy(new StorageItemPreference(mContext));
-        video.setIcon(R.drawable.ic_local_movies);
-        final StorageItemPreference image = spy(new StorageItemPreference(mContext));
-        image.setIcon(R.drawable.ic_photo_library);
-        final StorageItemPreference games = spy(new StorageItemPreference(mContext));
-        games.setIcon(R.drawable.ic_videogame_vd_theme_24);
-        final StorageItemPreference apps = spy(new StorageItemPreference(mContext));
-        apps.setIcon(R.drawable.ic_storage_apps);
-        final StorageItemPreference system = spy(new StorageItemPreference(mContext));
-        system.setIcon(R.drawable.ic_system_update);
-        final StorageItemPreference files = spy(new StorageItemPreference(mContext));
-        files.setIcon(R.drawable.ic_folder_vd_theme_24);
-        final PreferenceScreen screen = mock(PreferenceScreen.class);
-        when(screen.findPreference(eq(StorageItemPreferenceController.GAME_KEY)))
-            .thenReturn(games);
-        when(screen.findPreference(eq(StorageItemPreferenceController.AUDIO_KEY)))
-            .thenReturn(audio);
-        when(screen.findPreference(eq(StorageItemPreferenceController.PHOTO_KEY)))
-            .thenReturn(image);
-        when(screen.findPreference(eq(StorageItemPreferenceController.FILES_KEY)))
-            .thenReturn(files);
-        when(screen.findPreference(eq(StorageItemPreferenceController.MOVIES_KEY)))
-            .thenReturn(video);
-        when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
-            .thenReturn(system);
-        when(screen.findPreference(eq(StorageItemPreferenceController.OTHER_APPS_KEY)))
-            .thenReturn(apps);
-        mController.displayPreference(screen);
+        mController.displayPreference(mPreferenceScreen);
 
         mController.setUserId(new UserHandle(10));
 
-        verify(audio, times(2)).setIcon(nullable(Drawable.class));
-        verify(video, times(2)).setIcon(nullable(Drawable.class));
-        verify(image, times(2)).setIcon(nullable(Drawable.class));
-        verify(games, times(2)).setIcon(nullable(Drawable.class));
-        verify(apps, times(2)).setIcon(nullable(Drawable.class));
-        verify(system, times(2)).setIcon(nullable(Drawable.class));
-        verify(files, times(2)).setIcon(nullable(Drawable.class));
+        verify(mController.mPublicStoragePreference, times(2)).setIcon(nullable(Drawable.class));
+        verify(mController.mImagesPreference, times(2)).setIcon(nullable(Drawable.class));
+        verify(mController.mVideosPreference, times(2)).setIcon(nullable(Drawable.class));
+        verify(mController.mAudiosPreference, times(2)).setIcon(nullable(Drawable.class));
+        verify(mController.mAppsPreference, times(2)).setIcon(nullable(Drawable.class));
+        verify(mController.mGamesPreference, times(2)).setIcon(nullable(Drawable.class));
+        verify(mController.mDocumentsAndOtherPreference, times(2))
+                .setIcon(nullable(Drawable.class));
+        verify(mController.mSystemPreference, times(2)).setIcon(nullable(Drawable.class));
+        verify(mController.mTrashPreference, times(2)).setIcon(nullable(Drawable.class));
     }
 
     @Test
     public void displayPreference_dontHideFilePreferenceWhenEmulatedInternalStorageUsed() {
-        final StorageItemPreference audio = new StorageItemPreference(mContext);
-        final StorageItemPreference image = new StorageItemPreference(mContext);
-        final StorageItemPreference games = new StorageItemPreference(mContext);
-        final StorageItemPreference apps = new StorageItemPreference(mContext);
-        final StorageItemPreference system = new StorageItemPreference(mContext);
-        final StorageItemPreference files = new StorageItemPreference(mContext);
-        final PreferenceScreen screen = mock(PreferenceScreen.class);
-        when(screen.findPreference(eq(StorageItemPreferenceController.GAME_KEY)))
-            .thenReturn(games);
-        when(screen.findPreference(eq(StorageItemPreferenceController.AUDIO_KEY)))
-            .thenReturn(audio);
-        when(screen.findPreference(eq(StorageItemPreferenceController.PHOTO_KEY)))
-            .thenReturn(image);
-        when(screen.findPreference(eq(StorageItemPreferenceController.FILES_KEY)))
-            .thenReturn(files);
-        when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
-            .thenReturn(system);
-        when(screen.findPreference(eq(StorageItemPreferenceController.OTHER_APPS_KEY)))
-            .thenReturn(apps);
-
         when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(mVolume);
+        when(mVolume.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
+        when(mVolume.getState()).thenReturn(VolumeInfo.STATE_MOUNTED);
         when(mVolume.isMountedReadable()).thenReturn(true);
 
-        mController.displayPreference(screen);
+        mController.displayPreference(mPreferenceScreen);
 
-        verify(screen, times(0)).removePreference(files);
+        assertThat(mController.mDocumentsAndOtherPreference.isVisible()).isTrue();
     }
 
     @Test
     public void displayPreference_hideFilePreferenceWhenEmulatedStorageUnreadable() {
-        final StorageItemPreference audio = new StorageItemPreference(mContext);
-        final StorageItemPreference image = new StorageItemPreference(mContext);
-        final StorageItemPreference games = new StorageItemPreference(mContext);
-        final StorageItemPreference apps = new StorageItemPreference(mContext);
-        final StorageItemPreference system = new StorageItemPreference(mContext);
-        final StorageItemPreference files = new StorageItemPreference(mContext);
-        final PreferenceScreen screen = mock(PreferenceScreen.class);
-        when(screen.findPreference(eq(StorageItemPreferenceController.GAME_KEY)))
-            .thenReturn(games);
-        when(screen.findPreference(eq(StorageItemPreferenceController.AUDIO_KEY)))
-            .thenReturn(audio);
-        when(screen.findPreference(eq(StorageItemPreferenceController.PHOTO_KEY)))
-            .thenReturn(image);
-        when(screen.findPreference(eq(StorageItemPreferenceController.FILES_KEY)))
-            .thenReturn(files);
-        when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
-            .thenReturn(system);
-        when(screen.findPreference(eq(StorageItemPreferenceController.OTHER_APPS_KEY)))
-            .thenReturn(apps);
-
         when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(mVolume);
         when(mVolume.isMountedReadable()).thenReturn(false);
 
-        mController.displayPreference(screen);
+        mController.displayPreference(mPreferenceScreen);
 
-        verify(screen).removePreference(files);
+        assertThat(mController.mDocumentsAndOtherPreference.isVisible()).isFalse();
     }
 
     @Test
-    public void displayPreference_hideFilePreferenceWhenNoEmulatedInternalStorage() {
-        final StorageItemPreference audio = new StorageItemPreference(mContext);
-        final StorageItemPreference image = new StorageItemPreference(mContext);
-        final StorageItemPreference games = new StorageItemPreference(mContext);
-        final StorageItemPreference apps = new StorageItemPreference(mContext);
-        final StorageItemPreference system = new StorageItemPreference(mContext);
-        final StorageItemPreference files = new StorageItemPreference(mContext);
-        final PreferenceScreen screen = mock(PreferenceScreen.class);
-        when(screen.findPreference(eq(StorageItemPreferenceController.GAME_KEY)))
-            .thenReturn(games);
-        when(screen.findPreference(eq(StorageItemPreferenceController.AUDIO_KEY)))
-            .thenReturn(audio);
-        when(screen.findPreference(eq(StorageItemPreferenceController.PHOTO_KEY)))
-            .thenReturn(image);
-        when(screen.findPreference(eq(StorageItemPreferenceController.FILES_KEY)))
-            .thenReturn(files);
-        when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
-            .thenReturn(system);
-        when(screen.findPreference(eq(StorageItemPreferenceController.OTHER_APPS_KEY)))
-            .thenReturn(apps);
-
+    public void displayPreference_noEmulatedInternalStorage_hidePreference() {
         when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(null);
 
-        mController.displayPreference(screen);
+        mController.displayPreference(mPreferenceScreen);
 
-        verify(screen).removePreference(files);
+        assertThat(mController.mDocumentsAndOtherPreference.isVisible()).isFalse();
     }
 
     @Test
-    public void displayPreference_updateFilePreferenceToHideAfterSettingVolume() {
-        final StorageItemPreference audio = new StorageItemPreference(mContext);
-        final StorageItemPreference image = new StorageItemPreference(mContext);
-        final StorageItemPreference games = new StorageItemPreference(mContext);
-        final StorageItemPreference apps = new StorageItemPreference(mContext);
-        final StorageItemPreference system = new StorageItemPreference(mContext);
-        final StorageItemPreference files = new StorageItemPreference(mContext);
-        final PreferenceScreen screen = mock(PreferenceScreen.class);
-        when(screen.findPreference(eq(StorageItemPreferenceController.GAME_KEY)))
-            .thenReturn(games);
-        when(screen.findPreference(eq(StorageItemPreferenceController.AUDIO_KEY)))
-            .thenReturn(audio);
-        when(screen.findPreference(eq(StorageItemPreferenceController.PHOTO_KEY)))
-            .thenReturn(image);
-        when(screen.findPreference(eq(StorageItemPreferenceController.FILES_KEY)))
-            .thenReturn(files);
-        when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
-            .thenReturn(system);
-        when(screen.findPreference(eq(StorageItemPreferenceController.OTHER_APPS_KEY)))
-            .thenReturn(apps);
-
+    public void setVolume_updateFilePreferenceToHideAfterSettingVolume_hidePreference() {
         when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(mVolume);
+        when(mVolume.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
+        when(mVolume.getState()).thenReturn(VolumeInfo.STATE_MOUNTED);
         when(mVolume.isMountedReadable()).thenReturn(true);
 
-        mController.displayPreference(screen);
+        mController.displayPreference(mPreferenceScreen);
         when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(null);
         mController.setVolume(mVolume);
 
-        verify(screen).removePreference(files);
+        assertThat(mController.mDocumentsAndOtherPreference.isVisible()).isFalse();
     }
 
 
     @Test
-    public void displayPreference_updateFilePreferenceToShowAfterSettingVolume() {
-        final StorageItemPreference audio = new StorageItemPreference(mContext);
-        final StorageItemPreference image = new StorageItemPreference(mContext);
-        final StorageItemPreference games = new StorageItemPreference(mContext);
-        final StorageItemPreference apps = new StorageItemPreference(mContext);
-        final StorageItemPreference system = new StorageItemPreference(mContext);
-        final StorageItemPreference files = new StorageItemPreference(mContext);
-        final PreferenceScreen screen = mock(PreferenceScreen.class);
-        when(screen.findPreference(eq(StorageItemPreferenceController.GAME_KEY)))
-            .thenReturn(games);
-        when(screen.findPreference(eq(StorageItemPreferenceController.AUDIO_KEY)))
-            .thenReturn(audio);
-        when(screen.findPreference(eq(StorageItemPreferenceController.PHOTO_KEY)))
-            .thenReturn(image);
-        when(screen.findPreference(eq(StorageItemPreferenceController.FILES_KEY)))
-            .thenReturn(files);
-        when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
-            .thenReturn(system);
-        when(screen.findPreference(eq(StorageItemPreferenceController.OTHER_APPS_KEY)))
-            .thenReturn(apps);
-
+    public void setVolume_updateFilePreferenceToShowAfterSettingVolume_showPreference() {
         // This will hide it initially.
-        mController.displayPreference(screen);
-
+        mController.displayPreference(mPreferenceScreen);
         when(mSvp.findEmulatedForPrivate(nullable(VolumeInfo.class))).thenReturn(mVolume);
+        when(mVolume.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
+        when(mVolume.getState()).thenReturn(VolumeInfo.STATE_MOUNTED);
         when(mVolume.isMountedReadable()).thenReturn(true);
 
         // And we bring it back.
         mController.setVolume(mVolume);
 
-        verify(screen).addPreference(files);
+        assertThat(mController.mDocumentsAndOtherPreference.isVisible()).isTrue();
+    }
+
+    @Test
+    public void setVolume_publicStorage_showFilePreference() {
+        // This will hide it initially.
+        mController.displayPreference(mPreferenceScreen);
+        when(mVolume.getType()).thenReturn(VolumeInfo.TYPE_PUBLIC);
+        when(mVolume.getState()).thenReturn(VolumeInfo.STATE_MOUNTED);
+        when(mVolume.isMountedReadable()).thenReturn(true);
+
+        // And we bring it back.
+        mController.setVolume(mVolume);
+
+        assertThat(mController.mPublicStoragePreference.isVisible()).isTrue();
+        assertThat(mController.mImagesPreference.isVisible()).isFalse();
+        assertThat(mController.mVideosPreference.isVisible()).isFalse();
+        assertThat(mController.mAudiosPreference.isVisible()).isFalse();
+        assertThat(mController.mAppsPreference.isVisible()).isFalse();
+        assertThat(mController.mGamesPreference.isVisible()).isFalse();
+        assertThat(mController.mDocumentsAndOtherPreference.isVisible()).isFalse();
+        assertThat(mController.mSystemPreference.isVisible()).isFalse();
+        assertThat(mController.mTrashPreference.isVisible()).isFalse();
     }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatterySaverControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatterySaverControllerTest.java
index b3b8196..52f682c 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatterySaverControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatterySaverControllerTest.java
@@ -105,7 +105,8 @@
                 Settings.Global.AUTOMATIC_POWER_SAVE_MODE,
                 PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC);
 
-        assertThat(mBatterySaverController.getSummary()).isEqualTo("Based on your routine");
+        assertThat(mBatterySaverController.getSummary()).
+                isEqualTo("Will turn on based on your routine");
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/SmartBatteryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/SmartBatteryPreferenceControllerTest.java
index a1f3bda..b132a97 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/SmartBatteryPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/SmartBatteryPreferenceControllerTest.java
@@ -21,9 +21,10 @@
 import static org.mockito.Mockito.doReturn;
 
 import android.content.ContentResolver;
-import android.content.Context;
 import android.provider.Settings;
 
+import androidx.preference.SwitchPreference;
+
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settingslib.widget.MainSwitchPreference;
@@ -42,50 +43,48 @@
     private static final int OFF = 0;
 
     private SmartBatteryPreferenceController mController;
+    private SwitchPreference mPreference;
     private ContentResolver mContentResolver;
     private FakeFeatureFactory mFeatureFactory;
-    private Context mContext;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
-        mContext = RuntimeEnvironment.application;
         mFeatureFactory = FakeFeatureFactory.setupForTest();
         mContentResolver = RuntimeEnvironment.application.getContentResolver();
         mController = new SmartBatteryPreferenceController(RuntimeEnvironment.application);
+        mPreference = new SwitchPreference(RuntimeEnvironment.application);
     }
 
     @Test
     public void testUpdateState_smartBatteryOn_preferenceChecked() {
         putSmartBatteryValue(ON);
-        final MainSwitchPreference preference = new MainSwitchPreference(mContext);
 
-        mController.updateState(preference);
+        mController.updateState(mPreference);
 
-        assertThat(preference.isChecked()).isTrue();
+        assertThat(mPreference.isChecked()).isTrue();
     }
 
     @Test
     public void testUpdateState_smartBatteryOff_preferenceUnchecked() {
         putSmartBatteryValue(OFF);
-        final MainSwitchPreference preference = new MainSwitchPreference(mContext);
 
-        mController.updateState(preference);
+        mController.updateState(mPreference);
 
-        assertThat(preference.isChecked()).isFalse();
+        assertThat(mPreference.isChecked()).isFalse();
     }
 
     @Test
     public void testUpdateState_checkPreference_smartBatteryOn() {
-        mController.onSwitchChanged(null, true);
+        mController.onPreferenceChange(mPreference, true);
 
         assertThat(getSmartBatteryValue()).isEqualTo(ON);
     }
 
     @Test
     public void testUpdateState_unCheckPreference_smartBatteryOff() {
-        mController.onSwitchChanged(null, false);
+        mController.onPreferenceChange(mPreference, false);
 
         assertThat(getSmartBatteryValue()).isEqualTo(OFF);
     }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryManagerPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryManagerPreferenceControllerTest.java
index 435aa88..b01e3b1 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryManagerPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryManagerPreferenceControllerTest.java
@@ -63,31 +63,20 @@
     }
 
     @Test
-    public void updateState_smartBatteryOnWithRestrictApps_showSummary() {
-        mController.updateSummary(mPreference, true /* smartBatteryOn */, 2);
+    public void updateState_smartBatteryWithRestrictApps_showSummary() {
+        mController.updateSummary(mPreference, 2);
 
         assertThat(mPreference.getSummary()).isEqualTo("2 apps restricted");
     }
 
     @Test
-    public void updateState_smartBatteryOnWithoutRestriction_showSummary() {
+    public void updateState_smartBatteryWithoutRestriction_showSummary() {
         when(mFeatureFactory.powerUsageFeatureProvider.isSmartBatterySupported()).thenReturn(true);
         Settings.Global.putInt(mContext.getContentResolver(),
                 Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED, ON);
 
         mController.updateState(mPreference);
 
-        assertThat(mPreference.getSummary()).isEqualTo("On / Detecting when apps drain battery");
-    }
-
-    @Test
-    public void updateState_smartBatteryOff_showSummary() {
-        when(mFeatureFactory.powerUsageFeatureProvider.isSmartBatterySupported()).thenReturn(true);
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED, OFF);
-
-        mController.updateState(mPreference);
-
-        assertThat(mPreference.getSummary()).isEqualTo("Off");
+        assertThat(mPreference.getSummary()).isEqualTo("Detecting when apps drain battery");
     }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipUtilsTest.java
index 6199788..6954f9a 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipUtilsTest.java
@@ -24,7 +24,6 @@
 import com.android.settings.SettingsActivity;
 import com.android.settings.core.InstrumentedPreferenceFragment;
 import com.android.settings.fuelgauge.batterytip.actions.BatteryDefenderAction;
-import com.android.settings.fuelgauge.batterytip.actions.BatterySaverAction;
 import com.android.settings.fuelgauge.batterytip.actions.OpenBatterySaverAction;
 import com.android.settings.fuelgauge.batterytip.actions.OpenRestrictAppFragmentAction;
 import com.android.settings.fuelgauge.batterytip.actions.RestrictAppAction;
@@ -90,34 +89,18 @@
     }
 
     @Test
-    public void testGetActionForBatteryTip_typeEarlyWarningStateNew_returnActionBatterySaver() {
+    public void testGetActionForBatteryTip_typeEarlyWarningStateNew_returnActionOpen() {
         when(mEarlyWarningTip.getState()).thenReturn(BatteryTip.StateType.NEW);
 
         assertThat(BatteryTipUtils.getActionForBatteryTip(mEarlyWarningTip, mSettingsActivity,
-                mFragment)).isInstanceOf(BatterySaverAction.class);
-    }
-
-    @Test
-    public void testGetActionForBatteryTip_typeEarlyWarningStateHandled_returnActionOpen() {
-        when(mEarlyWarningTip.getState()).thenReturn(BatteryTip.StateType.HANDLED);
-
-        assertThat(BatteryTipUtils.getActionForBatteryTip(mEarlyWarningTip, mSettingsActivity,
                 mFragment)).isInstanceOf(OpenBatterySaverAction.class);
     }
 
     @Test
-    public void testGetActionForBatteryTip_typeLowBatteryStateNew_returnActionBatterySaver() {
+    public void testGetActionForBatteryTip_typeLowBatteryStateNew_returnActionOpen() {
         when(mLowBatteryTip.getState()).thenReturn(BatteryTip.StateType.NEW);
 
         assertThat(BatteryTipUtils.getActionForBatteryTip(mLowBatteryTip, mSettingsActivity,
-                mFragment)).isInstanceOf(BatterySaverAction.class);
-    }
-
-    @Test
-    public void testGetActionForBatteryTip_typeLowBatteryStateHandled_returnActionOpen() {
-        when(mLowBatteryTip.getState()).thenReturn(BatteryTip.StateType.HANDLED);
-
-        assertThat(BatteryTipUtils.getActionForBatteryTip(mLowBatteryTip, mSettingsActivity,
                 mFragment)).isInstanceOf(OpenBatterySaverAction.class);
     }
 
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/EarlyWarningDetectorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/EarlyWarningDetectorTest.java
index dbee7f1..84411a7 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/EarlyWarningDetectorTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/EarlyWarningDetectorTest.java
@@ -86,11 +86,11 @@
     }
 
     @Test
-    public void testDetect_batterySaverOn_tipHandled() {
+    public void testDetect_batterySaverOn_tipInvisible() {
         doReturn(true).when(mPowerManager).isPowerSaveMode();
 
         assertThat(mEarlyWarningDetector.detect().getState())
-                .isEqualTo(BatteryTip.StateType.HANDLED);
+                .isEqualTo(BatteryTip.StateType.INVISIBLE);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetectorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetectorTest.java
index 55020e2..245bacc 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetectorTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetectorTest.java
@@ -91,10 +91,11 @@
     }
 
     @Test
-    public void testDetect_batterySaverOn_tipHandled() {
+    public void testDetect_batterySaverOn_tipInvisible() {
         mShadowPowerManager.setIsPowerSaveMode(true);
 
-        assertThat(mLowBatteryDetector.detect().getState()).isEqualTo(BatteryTip.StateType.HANDLED);
+        assertThat(mLowBatteryDetector.detect().getState())
+                .isEqualTo(BatteryTip.StateType.INVISIBLE);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/SmartBatteryDetectorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/SmartBatteryDetectorTest.java
index 477bf49..00dcbd4 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/SmartBatteryDetectorTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/SmartBatteryDetectorTest.java
@@ -22,26 +22,37 @@
 
 import android.content.ContentResolver;
 import android.content.Context;
+import android.os.PowerManager;
 import android.provider.Settings;
 
+import com.android.settings.fuelgauge.BatteryInfo;
 import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy;
 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.Shadows;
+import org.robolectric.shadows.ShadowPowerManager;
 import org.robolectric.util.ReflectionHelpers;
 
 @RunWith(RobolectricTestRunner.class)
 public class SmartBatteryDetectorTest {
 
+    private static final int EXPECTED_BATTERY_LEVEL = 30;
+    private static final int UNEXPECTED_BATTERY_LEVEL = 31;
+
     private Context mContext;
     private ContentResolver mContentResolver;
     private SmartBatteryDetector mSmartBatteryDetector;
     private BatteryTipPolicy mPolicy;
+    private ShadowPowerManager mShadowPowerManager;
+    @Mock
+    private BatteryInfo mBatteryInfo;
 
     @Before
     public void setUp() {
@@ -50,7 +61,9 @@
         mContext = RuntimeEnvironment.application;
         mContentResolver = mContext.getContentResolver();
         mPolicy = spy(new BatteryTipPolicy(mContext));
-        mSmartBatteryDetector = new SmartBatteryDetector(mPolicy, mContentResolver);
+        mShadowPowerManager = Shadows.shadowOf(mContext.getSystemService(PowerManager.class));
+        mSmartBatteryDetector =
+                new SmartBatteryDetector(mContext, mPolicy, mBatteryInfo, mContentResolver);
     }
 
     @Test
@@ -64,14 +77,38 @@
     public void testDetect_smartBatteryOff_tipVisible() {
         Settings.Global.putInt(mContentResolver,
                 Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED, 0);
+        mShadowPowerManager.setIsPowerSaveMode(false);
+        mBatteryInfo.batteryLevel = EXPECTED_BATTERY_LEVEL;
 
         assertThat(mSmartBatteryDetector.detect().isVisible()).isTrue();
     }
 
     @Test
+    public void testDetect_batterySaverOn_tipInvisible() {
+        Settings.Global.putInt(mContentResolver,
+                Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED, 0);
+        mShadowPowerManager.setIsPowerSaveMode(true);
+        mBatteryInfo.batteryLevel = EXPECTED_BATTERY_LEVEL;
+
+        assertThat(mSmartBatteryDetector.detect().isVisible()).isFalse();
+    }
+
+    @Test
+    public void testDetect_unexpectedBatteryLevel_tipInvisible() {
+        Settings.Global.putInt(mContentResolver,
+                Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED, 0);
+        mShadowPowerManager.setIsPowerSaveMode(true);
+        mBatteryInfo.batteryLevel = UNEXPECTED_BATTERY_LEVEL;
+
+        assertThat(mSmartBatteryDetector.detect().isVisible()).isFalse();
+    }
+
+    @Test
     public void testDetect_smartBatteryOn_tipInvisible() {
         Settings.Global.putInt(mContentResolver,
                 Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED, 1);
+        mShadowPowerManager.setIsPowerSaveMode(false);
+        mBatteryInfo.batteryLevel = EXPECTED_BATTERY_LEVEL;
 
         assertThat(mSmartBatteryDetector.detect().isVisible()).isFalse();
     }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/SummaryDetectorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/SummaryDetectorTest.java
index 0fd3ccf..5794b6c 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/SummaryDetectorTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/SummaryDetectorTest.java
@@ -54,9 +54,9 @@
     }
 
     @Test
-    public void testDetect_notDisabled_tipVisible() {
+    public void testDetect_notDisabled_tipInvisible() {
         SummaryDetector detector = new SummaryDetector(mPolicy, AVERAGE_TIME_MS);
 
-        assertThat(detector.detect().isVisible()).isTrue();
+        assertThat(detector.detect().isVisible()).isFalse();
     }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/EarlyWarningTipTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/EarlyWarningTipTest.java
index 85b00c8..aeea10f 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/EarlyWarningTipTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/EarlyWarningTipTest.java
@@ -74,24 +74,13 @@
     }
 
     @Test
-    public void testInfo_stateHandled_displayPowerModeHandledInfo() {
-        final EarlyWarningTip tip =
-                new EarlyWarningTip(BatteryTip.StateType.HANDLED, false /* powerModeOn */);
-
-        assertThat(tip.getTitle(mContext)).isEqualTo("Battery Saver is on");
-        assertThat(tip.getSummary(mContext)).isEqualTo("Some features may be limited");
-        assertThat(tip.getIconId()).isEqualTo(R.drawable.ic_battery_status_maybe_24dp);
-        assertThat(tip.getIconTintColorId()).isEqualTo(R.color.battery_maybe_color_light);
-    }
-
-    @Test
-    public void testUpdate_powerModeTurnedOn_typeBecomeHandled() {
+    public void testUpdate_powerModeTurnedOn_typeBecomeInvisible() {
         final EarlyWarningTip nextTip =
                 new EarlyWarningTip(BatteryTip.StateType.INVISIBLE, true /* powerModeOn */);
 
         mEarlyWarningTip.updateState(nextTip);
 
-        assertThat(mEarlyWarningTip.getState()).isEqualTo(BatteryTip.StateType.HANDLED);
+        assertThat(mEarlyWarningTip.getState()).isEqualTo(BatteryTip.StateType.INVISIBLE);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTipTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTipTest.java
index 11dffcd..244faea 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTipTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTipTest.java
@@ -65,13 +65,6 @@
     }
 
     @Test
-    public void getSummary_tipHandled_showSummary() {
-        mLowBatteryTip.mState = BatteryTip.StateType.HANDLED;
-
-        assertThat(mLowBatteryTip.getSummary(mContext)).isEqualTo("Some features may be limited");
-    }
-
-    @Test
     public void getSummary_tipNew_showSummary() {
         mLowBatteryTip.mState = BatteryTip.StateType.NEW;
 
diff --git a/tests/robotests/src/com/android/settings/gestures/LongPressPowerButtonPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/LongPressPowerButtonPreferenceControllerTest.java
new file mode 100644
index 0000000..de58c99
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/gestures/LongPressPowerButtonPreferenceControllerTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2021 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.gestures;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.app.Application;
+import android.content.res.Resources;
+import android.provider.Settings;
+
+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 LongPressPowerButtonPreferenceControllerTest {
+
+    private static final String KEY_LONG_PRESS_POWER_BUTTON =
+            "gesture_power_menu_long_press_for_assist";
+
+    private Application mContext;
+    private Resources mResources;
+    private LongPressPowerButtonPreferenceController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        mResources = mock(Resources.class);
+        when(mContext.getResources()).thenReturn(mResources);
+        when(mResources.getBoolean(
+                com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable))
+                .thenReturn(true);
+        mController = new LongPressPowerButtonPreferenceController(mContext,
+                KEY_LONG_PRESS_POWER_BUTTON);
+    }
+
+    @Test
+    public void isAvailable_configIsTrue_shouldReturnTrue() {
+        when(mResources.getBoolean(
+                com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable))
+                .thenReturn(true);
+
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    public void isAvailable_configIsFalse_shouldReturnFalse() {
+        when(mResources.getBoolean(
+                com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable))
+                .thenReturn(false);
+
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void preferenceChecked_longPressPowerSettingSetToAssistant() {
+        mController.onPreferenceChange(null, true);
+
+        assertThat(Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.POWER_BUTTON_LONG_PRESS, -1)).isEqualTo(
+                LongPressPowerButtonPreferenceController.LONG_PRESS_POWER_ASSISTANT_VALUE);
+    }
+
+    @Test
+    public void preferenceUnchecked_longPressPowerSettingSetToDefaultValue() {
+        // Value out of range chosen deliberately.
+        when(mResources.getInteger(
+                com.android.internal.R.integer.config_longPressOnPowerBehavior))
+                .thenReturn(8);
+
+        mController.onPreferenceChange(null, false);
+        assertThat(Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.POWER_BUTTON_LONG_PRESS, -1)).isEqualTo(8);
+    }
+
+    @Test
+    public void preferenceUnchecked_assistDefault_setShutOff() {
+        // Value out of range chosen deliberately.
+        when(mResources.getInteger(
+                com.android.internal.R.integer.config_longPressOnPowerBehavior))
+                .thenReturn(
+                        LongPressPowerButtonPreferenceController.LONG_PRESS_POWER_ASSISTANT_VALUE);
+
+        mController.onPreferenceChange(null, false);
+        assertThat(Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.POWER_BUTTON_LONG_PRESS, -1)).isEqualTo(
+                LongPressPowerButtonPreferenceController.LONG_PRESS_POWER_SHUT_OFF);
+    }
+
+    @Test
+    public void preferenceUnchecked_assistDefaultGlobalActionsEnabled_setGlobalActions() {
+        // Value out of range chosen deliberately.
+        when(mResources.getInteger(
+                com.android.internal.R.integer.config_longPressOnPowerBehavior))
+                .thenReturn(
+                        LongPressPowerButtonPreferenceController.LONG_PRESS_POWER_ASSISTANT_VALUE);
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                LongPressPowerButtonPreferenceController.CARDS_AVAILABLE_KEY, 1);
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                LongPressPowerButtonPreferenceController.CARDS_ENABLED_KEY, 1);
+
+        mController.onPreferenceChange(null, false);
+        assertThat(Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.POWER_BUTTON_LONG_PRESS, -1)).isEqualTo(
+                LongPressPowerButtonPreferenceController.LONG_PRESS_POWER_GLOBAL_ACTIONS);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/gestures/OneHandedEnablePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/OneHandedEnablePreferenceControllerTest.java
index 11128f3..b53629e 100644
--- a/tests/robotests/src/com/android/settings/gestures/OneHandedEnablePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/OneHandedEnablePreferenceControllerTest.java
@@ -51,14 +51,16 @@
     public void setChecked_setBoolean_checkIsTrueOrFalse() {
         mController.setChecked(false);
         assertThat(OneHandedSettingsUtils.isOneHandedModeEnabled(mContext)).isFalse();
+        assertThat(OneHandedSettingsUtils.isSwipeDownNotificationEnabled(mContext)).isTrue();
 
         mController.setChecked(true);
         assertThat(OneHandedSettingsUtils.isOneHandedModeEnabled(mContext)).isTrue();
+        assertThat(OneHandedSettingsUtils.isSwipeDownNotificationEnabled(mContext)).isFalse();
     }
 
     @Test
     public void getAvailabilityStatus_setSupportOneHandedModeProperty_shouldAvailable() {
-        SystemProperties.set(OneHandedEnablePreferenceController.SUPPORT_ONE_HANDED_MODE, "true");
+        SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "true");
 
         assertThat(mController.getAvailabilityStatus())
                 .isEqualTo(BasePreferenceController.AVAILABLE);
@@ -66,7 +68,7 @@
 
     @Test
     public void getAvailabilityStatus_unsetSupportOneHandedModeProperty_shouldUnsupported() {
-        SystemProperties.set(OneHandedEnablePreferenceController.SUPPORT_ONE_HANDED_MODE, "false");
+        SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "false");
 
         assertThat(mController.getAvailabilityStatus())
                 .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
diff --git a/tests/robotests/src/com/android/settings/gestures/OneHandedSettingsTest.java b/tests/robotests/src/com/android/settings/gestures/OneHandedSettingsTest.java
index fcea919..2651708 100644
--- a/tests/robotests/src/com/android/settings/gestures/OneHandedSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/OneHandedSettingsTest.java
@@ -55,7 +55,7 @@
 
     @Test
     public void isPageSearchEnabled_setSupportOneHandedModeProperty_shouldReturnTrue() {
-        SystemProperties.set(OneHandedEnablePreferenceController.SUPPORT_ONE_HANDED_MODE, "true");
+        SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "true");
 
         final Object obj = ReflectionHelpers.callInstanceMethod(
                 OneHandedSettings.SEARCH_INDEX_DATA_PROVIDER, "isPageSearchEnabled",
@@ -66,7 +66,7 @@
 
     @Test
     public void isPageSearchEnabled_unsetSupportOneHandedModeProperty_shouldReturnFalse() {
-        SystemProperties.set(OneHandedEnablePreferenceController.SUPPORT_ONE_HANDED_MODE, "false");
+        SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "false");
 
         final Object obj = ReflectionHelpers.callInstanceMethod(
                 OneHandedSettings.SEARCH_INDEX_DATA_PROVIDER, "isPageSearchEnabled",
diff --git a/tests/robotests/src/com/android/settings/gestures/PowerMenuPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/PowerMenuPreferenceControllerTest.java
index 570a680..f8d81f2 100644
--- a/tests/robotests/src/com/android/settings/gestures/PowerMenuPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/PowerMenuPreferenceControllerTest.java
@@ -18,8 +18,13 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.content.res.Resources;
 import android.provider.Settings;
 
 import com.android.settings.core.BasePreferenceController;
@@ -35,6 +40,7 @@
 @RunWith(RobolectricTestRunner.class)
 public class PowerMenuPreferenceControllerTest {
     private Context mContext;
+    private Resources mResources;
     private PowerMenuPreferenceController mController;
     private ShadowPackageManager mShadowPackageManager;
 
@@ -44,17 +50,26 @@
     private static final String CARDS_ENABLED = Settings.Secure.GLOBAL_ACTIONS_PANEL_ENABLED;
     private static final String CARDS_AVAILABLE = Settings.Secure.GLOBAL_ACTIONS_PANEL_AVAILABLE;
 
+
     @Before
     public void setUp() {
-        mContext = RuntimeEnvironment.application;
+        mContext = spy(RuntimeEnvironment.application);
+        mResources = mock(Resources.class);
+        when(mResources.getBoolean(
+            com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable))
+                .thenReturn(true);
+        when(mContext.getResources()).thenReturn(mResources);
         mShadowPackageManager = Shadows.shadowOf(mContext.getPackageManager());
         mController = new PowerMenuPreferenceController(mContext, KEY_GESTURE_POWER_MENU);
     }
 
     @Test
-    public void getAvailabilityStatus_bothAvailable_available() {
+    public void getAvailabilityStatus_allAvailable_available() {
         Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 1);
         mShadowPackageManager.setSystemFeature(CONTROLS_FEATURE, true);
+        when(mResources.getBoolean(
+                com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable))
+                    .thenReturn(true);
 
         assertThat(mController.getAvailabilityStatus()).isEqualTo(
                 BasePreferenceController.AVAILABLE);
@@ -64,6 +79,9 @@
     public void getAvailabilityStatus_onlyCardsAvailable_available() {
         Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 1);
         mShadowPackageManager.setSystemFeature(CONTROLS_FEATURE, false);
+        when(mResources.getBoolean(
+                com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable))
+                    .thenReturn(false);
 
         assertThat(mController.getAvailabilityStatus()).isEqualTo(
                 BasePreferenceController.AVAILABLE);
@@ -73,15 +91,69 @@
     public void getAvailabilityStatus_onlyControlsAvailable_available() {
         Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 0);
         mShadowPackageManager.setSystemFeature(CONTROLS_FEATURE, true);
+        when(mResources.getBoolean(
+                com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable))
+                    .thenReturn(false);
 
         assertThat(mController.getAvailabilityStatus()).isEqualTo(
                 BasePreferenceController.AVAILABLE);
     }
 
     @Test
-    public void getAvailabilityStatus_bothUnavailable_unavailable() {
+    public void getAvailabilityStatus_controlsAndCardsAvailable_available() {
+        Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 1);
+        mShadowPackageManager.setSystemFeature(CONTROLS_FEATURE, true);
+        when(mResources.getBoolean(
+                com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable))
+                    .thenReturn(false);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BasePreferenceController.AVAILABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_controlsAndAssistAvailable_available() {
+        Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 0);
+        mShadowPackageManager.setSystemFeature(CONTROLS_FEATURE, true);
+        when(mResources.getBoolean(
+                com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable))
+                    .thenReturn(true);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BasePreferenceController.AVAILABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_cardsAndAssistAvailable_available() {
+        Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 1);
+        mShadowPackageManager.setSystemFeature(CONTROLS_FEATURE, false);
+        when(mResources.getBoolean(
+                com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable))
+                    .thenReturn(true);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BasePreferenceController.AVAILABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_onlyAssistAvailable_available() {
         Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 0);
         mShadowPackageManager.setSystemFeature(CONTROLS_FEATURE, false);
+        when(mResources.getBoolean(
+                com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable))
+                    .thenReturn(true);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BasePreferenceController.AVAILABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_allUnavailable_unavailable() {
+        Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 0);
+        mShadowPackageManager.setSystemFeature(CONTROLS_FEATURE, false);
+        when(mResources.getBoolean(
+                com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable))
+                    .thenReturn(true);
 
         assertThat(mController.getAvailabilityStatus()).isEqualTo(
                 BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
diff --git a/tests/robotests/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceControllerTest.java
index c6d8233..9f76800 100644
--- a/tests/robotests/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceControllerTest.java
@@ -16,10 +16,7 @@
 
 package com.android.settings.gestures;
 
-import static android.provider.Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED;
-
 import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -28,6 +25,7 @@
 import android.provider.Settings;
 
 import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -57,44 +55,33 @@
     public void setChecked_toggledOn_enablesSwipeBottomToNotification() {
         mController.setChecked(true);
 
-        assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
-                SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED, 0)).isEqualTo(1);
+        assertThat(OneHandedSettingsUtils.isSwipeDownNotificationEnabled(mContext)).isTrue();
+        assertThat(OneHandedSettingsUtils.isOneHandedModeEnabled(mContext)).isFalse();
     }
 
     @Test
     public void setChecked_toggledOff_disablesSwipeBottomToNotification() {
         mController.setChecked(false);
 
-        assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
-                SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED, 0)).isEqualTo(0);
+        assertThat(OneHandedSettingsUtils.isSwipeDownNotificationEnabled(mContext)).isFalse();
     }
 
     @Test
-    public void getAvailabilityStatus_oneHandedUnsupported_returnsAvailable() {
-        SystemProperties.set(OneHandedEnablePreferenceController.SUPPORT_ONE_HANDED_MODE, "false");
+    public void getAvailabilityStatus_oneHandedUnsupported_returnsUnsupport() {
+        SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "false");
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BasePreferenceController.UNSUPPORTED_ON_DEVICE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_oneHandedSupported_returnsAvailable() {
+        SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "true");
 
         assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
     }
 
     @Test
-    public void getAvailabilityStatus_oneHandedDisabled_returnsAvailable() {
-        SystemProperties.set(OneHandedEnablePreferenceController.SUPPORT_ONE_HANDED_MODE, "true");
-        Settings.Secure.putInt(mContext.getContentResolver(),
-                Settings.Secure.ONE_HANDED_MODE_ENABLED, 0);
-
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
-    }
-
-    @Test
-    public void getAvailabilityStatus_oneHandedEnabled_returnsDisabled() {
-        SystemProperties.set(OneHandedEnablePreferenceController.SUPPORT_ONE_HANDED_MODE, "true");
-        Settings.Secure.putInt(mContext.getContentResolver(),
-                Settings.Secure.ONE_HANDED_MODE_ENABLED, 1);
-
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
-    }
-
-    @Test
     public void getSummary_gestureEnabled_returnsOnSummary() {
         mController.setChecked(true);
 
@@ -111,8 +98,8 @@
     }
 
     @Test
-    public void getDefaultConfig_returnsOffState() {
-        SystemProperties.set(OneHandedEnablePreferenceController.SUPPORT_ONE_HANDED_MODE, "false");
+    public void isChecked_getDefaultConfig_returnFalse() {
+        SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "false");
         Settings.Secure.resetToDefaults(mContext.getContentResolver(),
                 Settings.Secure.ONE_HANDED_MODE_ENABLED);
 
diff --git a/tests/robotests/src/com/android/settings/gestures/SwipeBottomToNotificationSettingsTest.java b/tests/robotests/src/com/android/settings/gestures/SwipeBottomToNotificationSettingsTest.java
index ad8104c..3a65b26 100644
--- a/tests/robotests/src/com/android/settings/gestures/SwipeBottomToNotificationSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/SwipeBottomToNotificationSettingsTest.java
@@ -21,7 +21,6 @@
 import android.content.Context;
 import android.os.SystemProperties;
 import android.provider.SearchIndexableResource;
-import android.provider.Settings;
 
 import com.android.settings.R;
 
@@ -64,22 +63,21 @@
     }
 
     @Test
-    public void isPageSearchEnabled_oneHandedUnsupported_shouldReturnTrue() {
-        SystemProperties.set(OneHandedEnablePreferenceController.SUPPORT_ONE_HANDED_MODE, "false");
+    public void isPageSearchEnabled_oneHandedUnsupported_shouldReturnFalse() {
+        SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "false");
 
         final Object obj = ReflectionHelpers.callInstanceMethod(
                 SwipeBottomToNotificationSettings.SEARCH_INDEX_DATA_PROVIDER, "isPageSearchEnabled",
                 ReflectionHelpers.ClassParameter.from(Context.class, mContext));
 
         final boolean isEnabled = (Boolean) obj;
-        assertThat(isEnabled).isTrue();
+        assertThat(isEnabled).isFalse();
     }
 
     @Test
     public void isPageSearchEnabled_oneHandedDisabled_shouldReturnTrue() {
-        SystemProperties.set(OneHandedEnablePreferenceController.SUPPORT_ONE_HANDED_MODE, "true");
-        Settings.Secure.putInt(mContext.getContentResolver(),
-                Settings.Secure.ONE_HANDED_MODE_ENABLED, 0);
+        SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "true");
+        OneHandedSettingsUtils.setSettingsOneHandedModeEnabled(mContext, false);
 
         final Object obj = ReflectionHelpers.callInstanceMethod(
                 SwipeBottomToNotificationSettings.SEARCH_INDEX_DATA_PROVIDER, "isPageSearchEnabled",
@@ -91,9 +89,8 @@
 
     @Test
     public void isPageSearchEnabled_oneHandedEnabled_shouldReturnFalse() {
-        SystemProperties.set(OneHandedEnablePreferenceController.SUPPORT_ONE_HANDED_MODE, "true");
-        Settings.Secure.putInt(mContext.getContentResolver(),
-                Settings.Secure.ONE_HANDED_MODE_ENABLED, 1);
+        SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "true");
+        OneHandedSettingsUtils.setSettingsOneHandedModeEnabled(mContext, true);
 
         final Object obj = ReflectionHelpers.callInstanceMethod(
                 SwipeBottomToNotificationSettings.SEARCH_INDEX_DATA_PROVIDER, "isPageSearchEnabled",
diff --git a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
index 173f625..c7a2650 100644
--- a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
@@ -25,16 +25,20 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
 import android.os.Build;
-import android.util.FeatureFlagUtils;
+import android.view.View;
 import android.view.Window;
 import android.view.WindowManager;
 import android.widget.FrameLayout;
 
+import androidx.fragment.app.Fragment;
+
 import com.android.settings.R;
-import com.android.settings.core.FeatureFlags;
 import com.android.settings.core.HideNonSystemOverlayMixin;
+import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl;
 import com.android.settings.homepage.contextualcards.slices.BatteryFixSliceTest;
+import com.android.settings.testutils.shadow.ShadowUserManager;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -46,15 +50,20 @@
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.android.controller.ActivityController;
 import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowActivityManager;
 import org.robolectric.util.ReflectionHelpers;
 
 @RunWith(RobolectricTestRunner.class)
+@Config(shadows = {ShadowUserManager.class,
+        SettingsHomepageActivityTest.ShadowSuggestionFeatureProviderImpl.class})
 public class SettingsHomepageActivityTest {
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        FeatureFlagUtils.setEnabled(RuntimeEnvironment.application, FeatureFlags.SILKY_HOME, false);
     }
 
     @Test
@@ -67,6 +76,77 @@
     }
 
     @Test
+    public void launch_configDisabled_shouldHideAvatar() {
+        final SettingsHomepageActivity activity = Robolectric.buildActivity(
+                SettingsHomepageActivity.class).create().get();
+
+        final View avatarView = activity.findViewById(R.id.account_avatar);
+        assertThat(avatarView.getVisibility()).isNotEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    @Config(qualifiers = "mcc999")
+    public void launch_configEnabled_shouldShowAvatar() {
+        final SettingsHomepageActivity activity = Robolectric.buildActivity(
+                SettingsHomepageActivity.class).create().get();
+
+        final View avatarView = activity.findViewById(R.id.account_avatar);
+        assertThat(avatarView.getVisibility()).isEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    @Config(qualifiers = "mcc999")
+    public void launch_LowRamDevice_shouldHideAvatar() {
+        final ShadowActivityManager activityManager = Shadow.extract(
+                RuntimeEnvironment.application.getSystemService(ActivityManager.class));
+        activityManager.setIsLowRamDevice(true);
+
+        final SettingsHomepageActivity activity = Robolectric.buildActivity(
+                SettingsHomepageActivity.class).create().get();
+
+        final View avatarView = activity.findViewById(R.id.account_avatar);
+        assertThat(avatarView.getVisibility()).isNotEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void showHomepageWithSuggestion_showSuggestion() {
+        final SettingsHomepageActivity activity = Robolectric.buildActivity(
+                SettingsHomepageActivity.class).create().get();
+        final View viewRoot = activity.findViewById(R.id.settings_homepage_container);
+        final View suggestionTile = activity.findViewById(R.id.suggestion_content);
+
+        activity.showHomepageWithSuggestion(true);
+
+        assertThat(viewRoot.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(suggestionTile.getVisibility()).isEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void showHomepageWithSuggestion_hideSuggestion() {
+        final SettingsHomepageActivity activity = Robolectric.buildActivity(
+                SettingsHomepageActivity.class).create().get();
+        final View viewRoot = activity.findViewById(R.id.settings_homepage_container);
+        final View suggestionTile = activity.findViewById(R.id.suggestion_content);
+
+        activity.showHomepageWithSuggestion(false);
+
+        assertThat(viewRoot.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(suggestionTile.getVisibility()).isEqualTo(View.GONE);
+    }
+
+    @Test
+    public void showHomepageWithSuggestion_callTwice_shouldKeepPreviousVisibility() {
+        final SettingsHomepageActivity activity = Robolectric.buildActivity(
+                SettingsHomepageActivity.class).create().get();
+        final View suggestionTile = activity.findViewById(R.id.suggestion_content);
+
+        activity.showHomepageWithSuggestion(false);
+        activity.showHomepageWithSuggestion(true);
+
+        assertThat(suggestionTile.getVisibility()).isEqualTo(View.GONE);
+    }
+
+    @Test
     @Config(shadows = {
             BatteryFixSliceTest.ShadowBatteryTipLoader.class
     })
@@ -114,4 +194,13 @@
         assertThat(paramCaptor.getValue().privateFlags
                 & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS).isEqualTo(0);
     }
+
+    @Implements(SuggestionFeatureProviderImpl.class)
+    public static class ShadowSuggestionFeatureProviderImpl {
+
+        @Implementation
+        public Class<? extends Fragment> getContextualSuggestionFragment() {
+            return Fragment.class;
+        }
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/location/LocationFooterPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationFooterPreferenceControllerTest.java
deleted file mode 100644
index 180f3e2..0000000
--- a/tests/robotests/src/com/android/settings/location/LocationFooterPreferenceControllerTest.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.location;
-
-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.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ResolveInfo;
-import android.content.res.Resources;
-import android.location.LocationManager;
-import android.os.Bundle;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@RunWith(RobolectricTestRunner.class)
-public class LocationFooterPreferenceControllerTest {
-
-    @Mock
-    private PreferenceCategory mPreferenceCategory;
-    @Mock
-    private PackageManager mPackageManager;
-    @Mock
-    private Resources mResources;
-    private LocationFooterPreferenceController mController;
-    private static final int TEST_RES_ID = 1234;
-    private static final String TEST_TEXT = "text";
-
-    @Before
-    public void setUp() throws NameNotFoundException {
-        MockitoAnnotations.initMocks(this);
-        Context context = spy(RuntimeEnvironment.application);
-        when(context.getPackageManager()).thenReturn(mPackageManager);
-        when(mPreferenceCategory.getContext()).thenReturn(context);
-        mController = spy(new LocationFooterPreferenceController(context, "key"));
-        when(mPackageManager.getResourcesForApplication(any(ApplicationInfo.class)))
-                .thenReturn(mResources);
-        when(mResources.getString(TEST_RES_ID)).thenReturn(TEST_TEXT);
-        doNothing().when(mPreferenceCategory).removeAll();
-    }
-
-    @Test
-    public void isAvailable_hasValidFooter_returnsTrue() {
-        final List<ResolveInfo> testResolveInfos = new ArrayList<>();
-        testResolveInfos.add(
-                getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ true));
-        when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt()))
-                .thenReturn(testResolveInfos);
-
-        assertThat(mController.isAvailable()).isTrue();
-    }
-
-    @Test
-    public void isAvailable_noSystemApp_returnsFalse() {
-        final List<ResolveInfo> testResolveInfos = new ArrayList<>();
-        testResolveInfos.add(
-                getTestResolveInfo(/*isSystemApp*/ false, /*hasRequiredMetadata*/ true));
-        when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt()))
-                .thenReturn(testResolveInfos);
-        assertThat(mController.isAvailable()).isFalse();
-    }
-
-    @Test
-    public void isAvailable_noRequiredMetadata_returnsFalse() {
-        final List<ResolveInfo> testResolveInfos = new ArrayList<>();
-        testResolveInfos.add(
-                getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ false));
-        when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt()))
-                .thenReturn(testResolveInfos);
-        assertThat(mController.isAvailable()).isFalse();
-    }
-
-    @Test
-    public void updateState_addPreferences() {
-        final List<ResolveInfo> testResolveInfos = new ArrayList<>();
-        testResolveInfos.add(
-                getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ true));
-        when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt()))
-                .thenReturn(testResolveInfos);
-        mController.updateState(mPreferenceCategory);
-        ArgumentCaptor<Preference> pref = ArgumentCaptor.forClass(Preference.class);
-        verify(mPreferenceCategory).addPreference(pref.capture());
-        assertThat(pref.getValue().getTitle()).isEqualTo(TEST_TEXT);
-    }
-
-    @Test
-    public void updateState_notSystemApp_ignore() {
-        final List<ResolveInfo> testResolveInfos = new ArrayList<>();
-        testResolveInfos.add(
-                getTestResolveInfo(/*isSystemApp*/ false, /*hasRequiredMetadata*/ true));
-        when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt()))
-                .thenReturn(testResolveInfos);
-        mController.updateState(mPreferenceCategory);
-        verify(mPreferenceCategory, never()).addPreference(any(Preference.class));
-    }
-
-    /**
-     * Returns a ResolveInfo object for testing
-     * @param isSystemApp If true, the application is a system app.
-     * @param hasRequiredMetaData If true, the broadcast receiver has a valid value for
-     *                            {@link LocationManager#METADATA_SETTINGS_FOOTER_STRING}
-     */
-    private ResolveInfo getTestResolveInfo(boolean isSystemApp, boolean hasRequiredMetaData) {
-        ResolveInfo testResolveInfo = new ResolveInfo();
-        ApplicationInfo testAppInfo = new ApplicationInfo();
-        if (isSystemApp) {
-            testAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
-        }
-        ActivityInfo testActivityInfo = new ActivityInfo();
-        testActivityInfo.name = "TestActivityName";
-        testActivityInfo.packageName = "TestPackageName";
-        testActivityInfo.applicationInfo = testAppInfo;
-        if (hasRequiredMetaData) {
-            testActivityInfo.metaData = new Bundle();
-            testActivityInfo.metaData.putInt(
-                    LocationManager.METADATA_SETTINGS_FOOTER_STRING, TEST_RES_ID);
-        }
-        testResolveInfo.activityInfo = testActivityInfo;
-        return testResolveInfo;
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/network/NetworkProviderSettingsTest.java b/tests/robotests/src/com/android/settings/network/NetworkProviderSettingsTest.java
index d7c0ffe..c1377ff 100644
--- a/tests/robotests/src/com/android/settings/network/NetworkProviderSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/network/NetworkProviderSettingsTest.java
@@ -44,6 +44,7 @@
 import android.os.PowerManager;
 import android.os.UserManager;
 import android.provider.Settings;
+import android.util.FeatureFlagUtils;
 import android.view.ContextMenu;
 import android.view.MenuItem;
 import android.view.View;
@@ -131,6 +132,7 @@
         mNetworkProviderSettings.mResetInternetPreference = mResetInternetPreference;
         mNetworkProviderSettings.mAirplaneModeMsgPreference = mAirplaneModeMsgPreference;
         mNetworkProviderSettings.mAirplaneModeEnabler = mAirplaneModeEnabler;
+        FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL, false);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/notification/app/RecentConversationsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/RecentConversationsPreferenceControllerTest.java
index 660b4e1..15bc598 100644
--- a/tests/robotests/src/com/android/settings/notification/app/RecentConversationsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/app/RecentConversationsPreferenceControllerTest.java
@@ -47,8 +47,10 @@
 import androidx.preference.PreferenceScreen;
 import androidx.preference.PreferenceViewHolder;
 
+import com.android.settings.R;
 import com.android.settings.applications.AppInfoBase;
 import com.android.settings.notification.NotificationBackend;
+import com.android.settingslib.widget.LayoutPreference;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -105,9 +107,9 @@
         ps.addPreference(outerContainer);
 
         ConversationChannel ccw = new ConversationChannel(mock(ShortcutInfo.class), 6,
-        new NotificationChannel("hi", "hi", 4),
-        new NotificationChannelGroup("hi", "hi"), 7,
-        true);
+                new NotificationChannel("hi", "hi", 4),
+                new NotificationChannelGroup("hi", "hi"), 7,
+                false);
 
         ArrayList<ConversationChannel> list = new ArrayList<>();
         list.add(ccw);
@@ -124,19 +126,19 @@
         ConversationChannel ccw = new ConversationChannel(mock(ShortcutInfo.class), 6,
                 new NotificationChannel("hi", "hi", 4),
                 new NotificationChannelGroup("hi", "hi"), 7,
-                true);
+                false);
 
         ConversationChannel ccw2 = new ConversationChannel(mock(ShortcutInfo.class), 6,
                 new NotificationChannel("hi", "hi", 0),
                 new NotificationChannelGroup("hi", "hi"), 7,
-                true);
+                false);
 
         NotificationChannelGroup blockedGroup = new NotificationChannelGroup("hi", "hi");
         blockedGroup.setBlocked(true);
         ConversationChannel ccw3 = new ConversationChannel(mock(ShortcutInfo.class), 6,
                 new NotificationChannel("hi", "hi", 4),
                 blockedGroup, 7,
-                true);
+                false);
 
         ArrayList<ConversationChannel> list = new ArrayList<>();
         list.add(ccw);
@@ -198,7 +200,6 @@
                 new NotificationChannelGroup("hi", "group"), 7,
                 true);
 
-
         Intent intent = mController.getSubSettingLauncher(ccw, "title").toIntent();
 
         Bundle extras = intent.getExtras();
@@ -258,6 +259,51 @@
     }
 
     @Test
+    public void testRemoveConversations() throws Exception {
+        ShortcutInfo si = mock(ShortcutInfo.class);
+        when(si.getId()).thenReturn("person");
+        when(si.getPackage()).thenReturn("pkg");
+        ConversationChannel ccw = new ConversationChannel(si, 6,
+                new NotificationChannel("hi", "hi", 4),
+                new NotificationChannelGroup("hi", "group"), 7,
+                false);
+
+        ConversationChannel ccw2 = new ConversationChannel(si, 6,
+                new NotificationChannel("bye", "bye", 4),
+                new NotificationChannelGroup("hi", "group"), 7,
+                true);
+
+        PreferenceCategory group = new PreferenceCategory(mContext);
+        PreferenceScreen screen = new PreferenceManager(mContext).createPreferenceScreen(mContext);
+        screen.addPreference(group);
+
+        RecentConversationPreference pref = mController.createConversationPref(
+                        new PreferenceCategory(mContext), ccw, 100);
+        final View view = View.inflate(mContext, pref.getLayoutResource(), null);
+        PreferenceViewHolder holder = spy(PreferenceViewHolder.createInstanceForTests(view));
+        View delete = View.inflate(mContext, pref.getSecondTargetResId(), null);
+        when(holder.findViewById(pref.getClearId())).thenReturn(delete);
+        group.addPreference(pref);
+
+        RecentConversationPreference pref2 = mController.createConversationPref(
+                        new PreferenceCategory(mContext), ccw2, 100);
+        final View view2 = View.inflate(mContext, pref2.getLayoutResource(), null);
+        PreferenceViewHolder holder2 = spy(PreferenceViewHolder.createInstanceForTests(view2));
+        View delete2 = View.inflate(mContext, pref2.getSecondTargetResId(), null);
+        when(holder2.findViewById(pref.getClearId())).thenReturn(delete2);
+        group.addPreference(pref2);
+
+        LayoutPreference clearAll = mController.getClearAll(group);
+        group.addPreference(clearAll);
+
+        clearAll.findViewById(R.id.conversation_settings_clear_recents).performClick();
+
+        verify(mPs).removeAllRecentConversations();
+        assertThat((Preference) group.findPreference("hi:person")).isNull();
+        assertThat((Preference) group.findPreference("bye:person")).isNotNull();
+    }
+
+    @Test
     public void testNonremoveableConversation() throws Exception {
         ShortcutInfo si = mock(ShortcutInfo.class);
         when(si.getId()).thenReturn("person");
@@ -272,4 +318,24 @@
                         new PreferenceCategory(mContext), ccw, 100);
         assertThat(pref.hasClearListener()).isFalse();
     }
+
+    @Test
+    public void testPopulateList_onlyNonremoveableConversations() {
+        final PreferenceManager preferenceManager = new PreferenceManager(mContext);
+        PreferenceScreen ps = preferenceManager.createPreferenceScreen(mContext);
+        PreferenceCategory outerContainer = spy(new PreferenceCategory(mContext));
+        ps.addPreference(outerContainer);
+
+        ConversationChannel ccw = new ConversationChannel(mock(ShortcutInfo.class), 6,
+                new NotificationChannel("hi", "hi", 4),
+                new NotificationChannelGroup("hi", "hi"), 7,
+                true /* hasactivenotifs */);
+
+        ArrayList<ConversationChannel> list = new ArrayList<>();
+        list.add(ccw);
+
+        mController.populateList(list, outerContainer);
+        // one for the preference, none for 'clear all'
+        verify(outerContainer, times(1)).addPreference(any());
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
index 7bd7813..b7e6ffd 100644
--- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -43,6 +43,7 @@
 import com.android.settings.panel.PanelFeatureProvider;
 import com.android.settings.search.SearchFeatureProvider;
 import com.android.settings.security.SecurityFeatureProvider;
+import com.android.settings.security.SecuritySettingsFeatureProvider;
 import com.android.settings.slices.SlicesFeatureProvider;
 import com.android.settings.users.UserFeatureProvider;
 import com.android.settings.wifi.WifiTrackerLibProvider;
@@ -83,6 +84,7 @@
 
     public WifiTrackerLibProvider wifiTrackerLibProvider;
     public ExtraAppInfoFeatureProvider extraAppInfoFeatureProvider;
+    public SecuritySettingsFeatureProvider securitySettingsFeatureProvider;
 
     /**
      * Call this in {@code @Before} method of the test class to use fake factory.
@@ -130,6 +132,7 @@
         mFaceFeatureProvider = mock(FaceFeatureProvider.class);
         wifiTrackerLibProvider = mock(WifiTrackerLibProvider.class);
         extraAppInfoFeatureProvider = mock(ExtraAppInfoFeatureProvider.class);
+        securitySettingsFeatureProvider = mock(SecuritySettingsFeatureProvider.class);
     }
 
     @Override
@@ -256,4 +259,9 @@
     public ExtraAppInfoFeatureProvider getExtraAppInfoFeatureProvider() {
         return extraAppInfoFeatureProvider;
     }
+
+    @Override
+    public SecuritySettingsFeatureProvider getSecuritySettingsFeatureProvider() {
+        return securitySettingsFeatureProvider;
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/users/UserSettingsTest.java b/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
index 3494c63..c542c55 100644
--- a/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
@@ -34,6 +34,7 @@
 import static org.mockito.Mockito.verify;
 import static org.robolectric.Shadows.shadowOf;
 
+import android.app.settings.SettingsEnums;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -61,6 +62,7 @@
 import com.android.settings.testutils.shadow.ShadowUserManager;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.RestrictedPreference;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.After;
 import org.junit.Before;
@@ -111,6 +113,8 @@
     private RestrictedPreference mAddGuestPreference;
     @Mock
     private UserManager mUserManager;
+    @Mock
+    private MetricsFeatureProvider mMetricsFeatureProvider;
 
     private FragmentActivity mActivity;
     private Context mContext;
@@ -134,6 +138,7 @@
         ReflectionHelpers.setField(mFragment, "mUserCaps", mUserCapabilities);
         ReflectionHelpers.setField(mFragment, "mDefaultIconDrawable", mDefaultIconDrawable);
         ReflectionHelpers.setField(mFragment, "mAddingUser", false);
+        ReflectionHelpers.setField(mFragment, "mMetricsFeatureProvider", mMetricsFeatureProvider);
 
         doReturn(mUserManager).when(mActivity).getSystemService(UserManager.class);
 
@@ -616,6 +621,7 @@
                 .isEqualTo(createdGuest.id);
         assertThat(arguments.getBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, false))
                 .isEqualTo(true);
+        verify(mMetricsFeatureProvider).action(any(), eq(SettingsEnums.ACTION_USER_GUEST_ADD));
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiNoInternetDialogTest.java b/tests/robotests/src/com/android/settings/wifi/WifiNoInternetDialogTest.java
index dc5ccb4..6cbb19d 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiNoInternetDialogTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiNoInternetDialogTest.java
@@ -44,6 +44,7 @@
 import com.android.settings.R;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
@@ -87,6 +88,7 @@
                 Robolectric.setupActivity(WifiNoInternetDialog.class);
     }
 
+    @Ignore
     @Test
     public void setupPromptUnvalidated_shouldShowNoInternetAccessRemember() {
         setupActivityWithAction(ACTION_PROMPT_UNVALIDATED, FAKE_URL);
@@ -98,6 +100,7 @@
                 mActivity.getString(R.string.no_internet_access_remember));
     }
 
+    @Ignore
     @Test
     public void setupPromptPartialConnectivity_shouldShowNoInternetAccessRemember() {
         setupActivityWithAction(ACTION_PROMPT_PARTIAL_CONNECTIVITY, FAKE_URL);
@@ -109,6 +112,7 @@
                 mActivity.getString(R.string.no_internet_access_remember));
     }
 
+    @Ignore
     @Test
     public void setupPromptLostValidationAction_shouldShowLostInternetAccessPersist() {
         setupActivityWithAction(ACTION_PROMPT_LOST_VALIDATION, FAKE_URL);
@@ -120,6 +124,7 @@
                 mActivity.getString(R.string.lost_internet_access_persist));
     }
 
+    @Ignore
     @Test
     public void clickPositiveButton_whenPromptUnvalidated_shouldCallSetAcceptUnvalidated() {
         setupActivityWithAction(ACTION_PROMPT_UNVALIDATED, FAKE_URL);
@@ -131,6 +136,7 @@
         verify(mConnectivityManager).setAcceptUnvalidated(any(Network.class), eq(true), eq(false));
     }
 
+    @Ignore
     @Test
     public void positiveButton_withPartialConnectivity_shouldCallSetAcceptPartialConnectivity() {
         setupActivityWithAction(ACTION_PROMPT_PARTIAL_CONNECTIVITY, FAKE_URL);
@@ -143,6 +149,7 @@
                 eq(false));
     }
 
+    @Ignore
     @Test
     public void positiveButton_withLostValidation_shouldCallSetAvoidUnvalidated() {
         setupActivityWithAction(ACTION_PROMPT_LOST_VALIDATION, FAKE_URL);
@@ -154,6 +161,7 @@
         verify(mConnectivityManager).setAvoidUnvalidated(any(Network.class));
     }
 
+    @Ignore
     @Test
     public void destroyWithNoClick_inPartialConnectivity_shouldCallSetAcceptPartialConnectivity() {
         setupActivityWithAction(ACTION_PROMPT_PARTIAL_CONNECTIVITY, FAKE_URL);
@@ -167,6 +175,7 @@
                 eq(false));
     }
 
+    @Ignore
     @Test
     public void destroyWithNoClick_whenUnvalidated_shouldCallSetAcceptUnvalidated() {
         setupActivityWithAction(ACTION_PROMPT_UNVALIDATED, FAKE_URL);
@@ -179,6 +188,7 @@
         verify(mConnectivityManager).setAcceptUnvalidated(any(Network.class), eq(false), eq(false));
     }
 
+    @Ignore
     @Test
     public void networkCallbackOnLost_shouldFinish() {
         setupActivityWithAction(ACTION_PROMPT_UNVALIDATED, FAKE_URL);
@@ -192,6 +202,7 @@
         verify(mActivity).finish();
     }
 
+    @Ignore
     @Test
     public void networkCallbackOnCapabilitiesChanged_shouldFinish() {
         setupActivityWithAction(ACTION_PROMPT_UNVALIDATED, FAKE_URL);
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/WifiSettingsTest.java
index 7eba586..1f5abd3 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiSettingsTest.java
@@ -43,6 +43,7 @@
 import android.os.PowerManager;
 import android.os.UserManager;
 import android.provider.Settings;
+import android.util.FeatureFlagUtils;
 import android.view.ContextMenu;
 import android.view.View;
 
@@ -105,6 +106,7 @@
         mWifiSettings.mConfigureWifiSettingsPreference = new Preference(mContext);
         mWifiSettings.mWifiPickerTracker = mMockWifiPickerTracker;
         mWifiSettings.mWifiManager = mWifiManager;
+        FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL, false);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2Test.java b/tests/robotests/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2Test.java
index c5f2a7f..3e0e22f 100644
--- a/tests/robotests/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2Test.java
+++ b/tests/robotests/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2Test.java
@@ -52,6 +52,7 @@
 import android.net.NetworkRequest;
 import android.net.RouteInfo;
 import android.net.Uri;
+import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiEnterpriseConfig;
 import android.net.wifi.WifiInfo;
@@ -83,6 +84,7 @@
 import com.android.wifitrackerlib.NetworkDetailsTracker;
 import com.android.wifitrackerlib.WifiEntry;
 import com.android.wifitrackerlib.WifiEntry.ConnectCallback;
+import com.android.wifitrackerlib.WifiEntry.ConnectedInfo;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -189,6 +191,8 @@
     @Mock
     private Preference mMockDnsPref;
     @Mock
+    private Preference mMockTypePref;
+    @Mock
     private PreferenceCategory mMockIpv6Category;
     @Mock
     private Preference mMockIpv6AddressesPref;
@@ -390,6 +394,8 @@
                 .thenReturn(mMockSubnetPref);
         when(mMockScreen.findPreference(WifiDetailPreferenceController2.KEY_DNS_PREF))
                 .thenReturn(mMockDnsPref);
+        when(mMockScreen.findPreference(WifiDetailPreferenceController2.KEY_WIFI_TYPE_PREF))
+                .thenReturn(mMockTypePref);
         when(mMockScreen.findPreference(WifiDetailPreferenceController2.KEY_IPV6_CATEGORY))
                 .thenReturn(mMockIpv6Category);
         when(mMockScreen.findPreference(WifiDetailPreferenceController2.KEY_IPV6_ADDRESSES_PREF))
@@ -931,6 +937,44 @@
     }
 
     @Test
+    public void onConnectedNetwork_getKnownNetworkType_visibleWifiTypePref() {
+        setUpForConnectedNetwork();
+        setUpSpyController();
+        setWifiType(ScanResult.WIFI_STANDARD_11AX);
+
+        displayAndResume();
+
+        verify(mMockTypePref).setSummary(R.string.wifi_type_11AX);
+        verify(mMockTypePref).setVisible(true);
+    }
+
+    @Test
+    public void onConnectedNetwork_getUnKnownNetworkType_invisibleWifiTypePref() {
+        setUpForConnectedNetwork();
+        setUpSpyController();
+        setWifiType(ScanResult.WIFI_STANDARD_UNKNOWN);
+
+        displayAndResume();
+
+        verify(mMockTypePref).setVisible(false);
+    }
+
+    @Test
+    public void onDisconnectedNetwork_resumeUI_invisibleWifiTypePref() {
+        setUpForDisconnectedNetwork();
+
+        displayAndResume();
+
+        verify(mMockTypePref).setVisible(false);
+    }
+
+    private void setWifiType(int type) {
+        ConnectedInfo connectedInfo = new ConnectedInfo();
+        connectedInfo.wifiStandard = type;
+        when(mMockWifiEntry.getConnectedInfo()).thenReturn(connectedInfo);
+    }
+
+    @Test
     public void noCurrentNetwork_shouldNotFinishActivityForConnectedNetwork() {
         setUpForConnectedNetwork();
         setUpSpyController();
diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherFooterPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherFooterPreferenceControllerTest.java
index a423071..c1d6c16 100644
--- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherFooterPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherFooterPreferenceControllerTest.java
@@ -17,6 +17,7 @@
 package com.android.settings.wifi.tether;
 
 import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -57,7 +58,8 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
-        when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
+        doReturn(mWifiManager).when(mContext).getSystemService(WifiManager.class);
+        doReturn(mTetheringManager).when(mContext).getSystemService(TetheringManager.class);
         when(mContext.getSystemService(Context.TETHERING_SERVICE)).thenReturn(mTetheringManager);
         when(mTetheringManager.getTetherableWifiRegexs()).thenReturn(new String[]{"1", "2"});
         mController = new WifiTetherFooterPreferenceController(mContext);
diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceControllerTest.java
index 8f8477f..bb61eb9 100644
--- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceControllerTest.java
@@ -19,6 +19,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -75,9 +76,9 @@
                 .setPassphrase(INITIAL_PASSWORD, SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
                 .build();
 
-        when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
+        doReturn(mWifiManager).when(mContext).getSystemService(WifiManager.class);
         when(mWifiManager.getSoftApConfiguration()).thenReturn(mConfig);
-        when(mContext.getSystemService(Context.TETHERING_SERVICE)).thenReturn(mTetheringManager);
+        doReturn(mTetheringManager).when(mContext).getSystemService(TetheringManager.class);
         when(mTetheringManager.getTetherableWifiRegexs()).thenReturn(new String[]{"1", "2"});
         when(mContext.getResources()).thenReturn(RuntimeEnvironment.application.getResources());
         when(mScreen.findPreference(anyString())).thenReturn(mPreference);
diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceControllerTest.java
index 147cd64..2d88722 100644
--- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceControllerTest.java
@@ -19,6 +19,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -67,8 +68,8 @@
         MockitoAnnotations.initMocks(this);
         mPreference = new WifiTetherSsidPreference(RuntimeEnvironment.application);
 
-        when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
-        when(mContext.getSystemService(Context.TETHERING_SERVICE)).thenReturn(mTetheringManager);
+        doReturn(mWifiManager).when(mContext).getSystemService(WifiManager.class);
+        doReturn(mTetheringManager).when(mContext).getSystemService(TetheringManager.class);
         when(mTetheringManager.getTetherableWifiRegexs()).thenReturn(new String[]{"1", "2"});
         when(mContext.getResources()).thenReturn(RuntimeEnvironment.application.getResources());
         when(mScreen.findPreference(anyString())).thenReturn(mPreference);
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index b7ac4b1..5582ff4 100644
--- a/tests/unit/Android.bp
+++ b/tests/unit/Android.bp
@@ -34,6 +34,8 @@
         "ub-uiautomator",
         "SettingsLibSettingsSpinner",
         "SettingsLibUsageProgressBarPreference",
+        "SettingsLibTwoTargetPreference",
+        "SettingsLibMainSwitchPreference",
     ],
 
     // Include all test java files.
diff --git a/tests/unit/src/com/android/settings/applications/HibernatedAppsPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/HibernatedAppsPreferenceControllerTest.java
index cf4c53e..a34e634 100644
--- a/tests/unit/src/com/android/settings/applications/HibernatedAppsPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/applications/HibernatedAppsPreferenceControllerTest.java
@@ -23,9 +23,18 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+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.apphibernation.AppHibernationManager;
 import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
 import android.provider.DeviceConfig;
 
 import androidx.test.core.app.ApplicationProvider;
@@ -34,23 +43,40 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
-/**
- * TODO(b/181172051): test getNumberHibernated() when the API implemented
- */
+import java.util.Arrays;
+
 @RunWith(AndroidJUnit4.class)
 public class HibernatedAppsPreferenceControllerTest {
 
+    public static final String HIBERNATED_PACKAGE_NAME = "hibernated_package";
+    public static final String AUTO_REVOKED_PACKAGE_NAME = "auto_revoked_package";
+    public static final String PERMISSION = "permission";
+    @Mock
+    PackageManager mPackageManager;
+    @Mock
+    AppHibernationManager mAppHibernationManager;
     private static final String KEY = "key";
     private Context mContext;
     private HibernatedAppsPreferenceController mController;
+    private PackageInfo mHibernatedPackage;
+    private PackageInfo mAutoRevokedPackage;
 
     @Before
     public void setUp() {
+        MockitoAnnotations.initMocks(this);
         DeviceConfig.setProperty(NAMESPACE_APP_HIBERNATION, PROPERTY_APP_HIBERNATION_ENABLED,
                 "true", false);
         mContext = spy(ApplicationProvider.getApplicationContext());
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
+        when(mContext.getSystemService(AppHibernationManager.class))
+                .thenReturn(mAppHibernationManager);
         mController = new HibernatedAppsPreferenceController(mContext, KEY);
+        mHibernatedPackage =
+                getHibernatedPackage(mAppHibernationManager, mPackageManager, mContext);
+        mAutoRevokedPackage = getAutoRevokedPackage(mPackageManager, mContext);
     }
 
     @Test
@@ -60,4 +86,38 @@
 
         assertThat((mController).getAvailabilityStatus()).isNotEqualTo(AVAILABLE);
     }
+
+    @Test
+    public void getSummary_shouldReturnCorrectly() {
+        when(mPackageManager.getInstalledPackages(anyInt())).thenReturn(
+                Arrays.asList(mHibernatedPackage, mAutoRevokedPackage, new PackageInfo()));
+        when(mContext.getResources()).thenReturn(mock(Resources.class));
+        final int totalHibernated = 2;
+
+        mController.getSummary();
+        verify(mContext.getResources()).getQuantityString(
+                anyInt(), eq(totalHibernated), eq(totalHibernated));
+    }
+
+    private static PackageInfo getHibernatedPackage(
+            AppHibernationManager apm, PackageManager pm, Context context) {
+        final PackageInfo pi = new PackageInfo();
+        pi.packageName = HIBERNATED_PACKAGE_NAME;
+        pi.requestedPermissions = new String[] {PERMISSION};
+        when(apm.getHibernatingPackagesForUser()).thenReturn(Arrays.asList(pi.packageName));
+        when(pm.getPermissionFlags(
+                pi.requestedPermissions[0], pi.packageName, context.getUser()))
+                .thenReturn(PackageManager.FLAG_PERMISSION_AUTO_REVOKED);
+        return pi;
+    }
+
+    private static PackageInfo getAutoRevokedPackage(PackageManager pm, Context context) {
+        final PackageInfo pi = new PackageInfo();
+        pi.packageName = AUTO_REVOKED_PACKAGE_NAME;
+        pi.requestedPermissions = new String[] {PERMISSION};
+        when(pm.getPermissionFlags(
+                pi.requestedPermissions[0], pi.packageName, context.getUser()))
+                .thenReturn(PackageManager.FLAG_PERMISSION_AUTO_REVOKED);
+        return pi;
+    }
 }
diff --git a/tests/unit/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceControllerTest.java
index e27942a..65ffe4b 100644
--- a/tests/unit/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceControllerTest.java
@@ -70,9 +70,9 @@
         MockitoAnnotations.initMocks(this);
         mContext = spy(ApplicationProvider.getApplicationContext());
         when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager);
-        when(mPackageManager.getPackageUidAsUser(eq(VALID_PACKAGE_NAME), anyInt()))
+        when(mPackageManager.getPackageUid(eq(VALID_PACKAGE_NAME), anyInt()))
                 .thenReturn(PACKAGE_UID);
-        when(mPackageManager.getPackageUidAsUser(eq(INVALID_PACKAGE_NAME), anyInt()))
+        when(mPackageManager.getPackageUid(eq(INVALID_PACKAGE_NAME), anyInt()))
                 .thenThrow(new PackageManager.NameNotFoundException());
         when(mPackageManager.getTargetSdkVersion(eq(EXEMPTED_PACKAGE_NAME)))
                 .thenReturn(android.os.Build.VERSION_CODES.Q);
diff --git a/tests/unit/src/com/android/settings/applications/autofill/PasswordsPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/autofill/PasswordsPreferenceControllerTest.java
index 216658f..25d9893 100644
--- a/tests/unit/src/com/android/settings/applications/autofill/PasswordsPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/applications/autofill/PasswordsPreferenceControllerTest.java
@@ -21,21 +21,26 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.mock;
+
 import android.content.ComponentName;
 import android.content.Context;
 import android.os.Looper;
 import android.service.autofill.AutofillServiceInfo;
 
+import androidx.lifecycle.Lifecycle;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceCategory;
 import androidx.preference.PreferenceManager;
 import androidx.preference.PreferenceScreen;
+import androidx.test.annotation.UiThreadTest;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
 import com.google.android.collect.Lists;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -100,11 +105,15 @@
         assertThat(mPasswordsPreferenceCategory.getPreferenceCount()).isEqualTo(0);
     }
 
+    @Ignore("TODO: Fix the test to handle the service binding.")
     @Test
+    @UiThreadTest
     public void displayPreference_withPasswords_addsPreference() {
         AutofillServiceInfo service = createServiceWithPasswords();
         PasswordsPreferenceController controller =
                 createControllerWithServices(Lists.newArrayList(service));
+        controller.onCreate(() -> mock(Lifecycle.class));
+
         controller.displayPreference(mScreen);
 
         assertThat(mPasswordsPreferenceCategory.getPreferenceCount()).isEqualTo(1);
diff --git a/tests/unit/src/com/android/settings/deviceinfo/storage/StorageEntryTest.java b/tests/unit/src/com/android/settings/deviceinfo/storage/StorageEntryTest.java
index cf1b6b2..3cd3539 100644
--- a/tests/unit/src/com/android/settings/deviceinfo/storage/StorageEntryTest.java
+++ b/tests/unit/src/com/android/settings/deviceinfo/storage/StorageEntryTest.java
@@ -209,6 +209,24 @@
     }
 
     @Test
+    public void isPublic_prublicVolume_shouldReturnTrue() {
+        final VolumeInfo publicVolumeInfo = mock(VolumeInfo.class);
+        final StorageEntry publicStorage = new StorageEntry(mContext, publicVolumeInfo);
+        when(publicVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PUBLIC);
+
+        assertThat(publicStorage.isPublic()).isTrue();
+    }
+
+    @Test
+    public void isStub_stubVolume_shouldReturnTrue() {
+        final VolumeInfo stubVolumeInfo = mock(VolumeInfo.class);
+        final StorageEntry stubStorage = new StorageEntry(mContext, stubVolumeInfo);
+        when(stubVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_STUB);
+
+        assertThat(stubStorage.isStub()).isTrue();
+    }
+
+    @Test
     public void isPrivate_nonVolumeInfo_shouldReturnFalse() {
         final DiskInfo diskInfo = mock(DiskInfo.class);
         final StorageEntry diskStorage = new StorageEntry(diskInfo);
diff --git a/tests/unit/src/com/android/settings/network/EraseEuiccDataControllerTest.java b/tests/unit/src/com/android/settings/network/EraseEuiccDataControllerTest.java
index 6ddef5d..879b9f7 100644
--- a/tests/unit/src/com/android/settings/network/EraseEuiccDataControllerTest.java
+++ b/tests/unit/src/com/android/settings/network/EraseEuiccDataControllerTest.java
@@ -18,8 +18,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.Mockito.spy;
-
 import android.content.Context;
 
 import androidx.test.core.app.ApplicationProvider;
diff --git a/tests/unit/src/com/android/settings/network/InternetUpdaterTest.java b/tests/unit/src/com/android/settings/network/InternetUpdaterTest.java
index 94456fe..3e9cdc7 100644
--- a/tests/unit/src/com/android/settings/network/InternetUpdaterTest.java
+++ b/tests/unit/src/com/android/settings/network/InternetUpdaterTest.java
@@ -38,6 +38,7 @@
 import android.content.Context;
 import android.content.IntentFilter;
 import android.net.ConnectivityManager;
+import android.net.NetworkCapabilities;
 import android.net.wifi.WifiManager;
 
 import androidx.lifecycle.Lifecycle;
@@ -107,57 +108,80 @@
     }
 
     @Test
-    public void update_apmOnWifiOff_getInternetApm() {
+    public void updateInternetAvailable_wifiConnectedAndNoValidated_internetUnavailable() {
+        final NetworkCapabilities networkCapabilities = new NetworkCapabilities();
+        networkCapabilities.addTransportType(TRANSPORT_WIFI);
+        networkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+
+        mInternetUpdater.updateInternetAvailable(networkCapabilities);
+
+        assertThat(mInternetUpdater.mInternetAvailable).isEqualTo(false);
+    }
+
+    @Test
+    public void updateInternetAvailable_wifiConnectedAndValidated_internetAvailable() {
+        final NetworkCapabilities networkCapabilities = new NetworkCapabilities();
+        networkCapabilities.addTransportType(TRANSPORT_WIFI);
+        networkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+        networkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
+
+        mInternetUpdater.updateInternetAvailable(networkCapabilities);
+
+        assertThat(mInternetUpdater.mInternetAvailable).isEqualTo(true);
+    }
+
+    @Test
+    public void updateInternetType_apmOnWifiOff_getInternetApm() {
         doReturn(true).when(mAirplaneModeEnabler).isAirplaneModeOn();
         doReturn(WifiManager.WIFI_STATE_DISABLED).when(mWifiManager).getWifiState();
         mInternetUpdater.mInternetAvailable = false;
 
-        mInternetUpdater.update();
+        mInternetUpdater.updateInternetType();
 
         assertThat(mInternetUpdater.getInternetType()).isEqualTo(INTERNET_OFF);
     }
 
     @Test
-    public void update_apmOnWifiOnNotConnected_getInternetNetworksAvailable() {
+    public void updateInternetType_apmOnWifiOnNotConnected_getInternetNetworksAvailable() {
         doReturn(true).when(mAirplaneModeEnabler).isAirplaneModeOn();
         doReturn(WifiManager.WIFI_STATE_ENABLED).when(mWifiManager).getWifiState();
         mInternetUpdater.mInternetAvailable = false;
 
-        mInternetUpdater.update();
+        mInternetUpdater.updateInternetType();
 
         assertThat(mInternetUpdater.getInternetType()).isEqualTo(INTERNET_NETWORKS_AVAILABLE);
     }
 
     @Test
-    public void update_apmOnWifiConnected_getInternetWifi() {
+    public void updateInternetType_apmOnWifiConnected_getInternetWifi() {
         doReturn(true).when(mAirplaneModeEnabler).isAirplaneModeOn();
         doReturn(true).when(mWifiManager).isWifiEnabled();
         mInternetUpdater.mInternetAvailable = true;
         mInternetUpdater.mTransport = TRANSPORT_WIFI;
 
-        mInternetUpdater.update();
+        mInternetUpdater.updateInternetType();
 
         assertThat(mInternetUpdater.getInternetType()).isEqualTo(INTERNET_WIFI);
     }
 
     @Test
-    public void update_apmOnCellularConnected_getInternetCellular() {
+    public void updateInternetType_apmOnCellularConnected_getInternetCellular() {
         doReturn(true).when(mAirplaneModeEnabler).isAirplaneModeOn();
         mInternetUpdater.mInternetAvailable = true;
         mInternetUpdater.mTransport = TRANSPORT_CELLULAR;
 
-        mInternetUpdater.update();
+        mInternetUpdater.updateInternetType();
 
         assertThat(mInternetUpdater.getInternetType()).isEqualTo(INTERNET_CELLULAR);
     }
 
     @Test
-    public void update_apmOnEthernetConnected_getInternetEthernet() {
+    public void updateInternetType_apmOnEthernetConnected_getInternetEthernet() {
         doReturn(true).when(mAirplaneModeEnabler).isAirplaneModeOn();
         mInternetUpdater.mInternetAvailable = true;
         mInternetUpdater.mTransport = TRANSPORT_ETHERNET;
 
-        mInternetUpdater.update();
+        mInternetUpdater.updateInternetType();
 
         assertThat(mInternetUpdater.getInternetType()).isEqualTo(INTERNET_ETHERNET);
     }
diff --git a/tests/unit/src/com/android/settings/network/ProviderModelSliceTest.java b/tests/unit/src/com/android/settings/network/ProviderModelSliceTest.java
index 4760daa..a323ed6 100644
--- a/tests/unit/src/com/android/settings/network/ProviderModelSliceTest.java
+++ b/tests/unit/src/com/android/settings/network/ProviderModelSliceTest.java
@@ -236,7 +236,8 @@
         mWifiList.add(mMockWifiSliceItem2);
         mMockNetworkProviderWorker.updateSelfResults(mWifiList);
         mockHelperCondition(false, true, true, null);
-        when(mMockNetworkProviderWorker.isEthernetConnected()).thenReturn(true);
+        when(mMockNetworkProviderWorker.getInternetType())
+                .thenReturn(InternetUpdater.INTERNET_ETHERNET);
 
         final Slice slice = mMockProviderModelSlice.getSlice();
 
@@ -258,7 +259,8 @@
         mWifiList.add(mMockWifiSliceItem2);
         mMockNetworkProviderWorker.updateSelfResults(mWifiList);
         mockHelperCondition(false, true, true, mWifiList.get(0));
-        when(mMockNetworkProviderWorker.isEthernetConnected()).thenReturn(true);
+        when(mMockNetworkProviderWorker.getInternetType())
+                .thenReturn(InternetUpdater.INTERNET_ETHERNET);
 
         final Slice slice = mMockProviderModelSlice.getSlice();
 
diff --git a/tests/robotests/src/com/android/settings/network/VpnPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/VpnPreferenceControllerTest.java
similarity index 72%
rename from tests/robotests/src/com/android/settings/network/VpnPreferenceControllerTest.java
rename to tests/unit/src/com/android/settings/network/VpnPreferenceControllerTest.java
index fb66d29..ee239ba 100644
--- a/tests/robotests/src/com/android/settings/network/VpnPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/network/VpnPreferenceControllerTest.java
@@ -22,7 +22,6 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
@@ -32,34 +31,38 @@
 import android.net.ConnectivityManager;
 import android.net.NetworkRequest;
 import android.net.VpnManager;
+import android.os.Looper;
 import android.os.UserHandle;
+import android.provider.Settings;
 import android.provider.SettingsSlicesContract;
 
 import androidx.lifecycle.LifecycleOwner;
 import androidx.preference.Preference;
+import androidx.preference.PreferenceManager;
 import androidx.preference.PreferenceScreen;
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 
 import com.android.internal.net.VpnConfig;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 
 import org.junit.Before;
+import org.junit.Ignore;
 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)
+@RunWith(AndroidJUnit4.class)
 public class VpnPreferenceControllerTest {
+    private static final String VPN_PREFERENCE_KEY = "vpn_settings";
 
-    @Mock
     private Context mContext;
     @Mock
     private ConnectivityManager mConnectivityManager;
     @Mock
     private VpnManager mVpnManager;
-    @Mock
     private PreferenceScreen mScreen;
     @Mock
     private Preference mPreference;
@@ -68,12 +71,21 @@
     private LifecycleOwner mLifecycleOwner;
 
     @Before
+    @UiThreadTest
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        mContext = spy(ApplicationProvider.getApplicationContext());
         when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE))
                 .thenReturn(mConnectivityManager);
         when(mContext.getSystemService(VpnManager.class)).thenReturn(mVpnManager);
-        when(mScreen.findPreference(anyString())).thenReturn(mPreference);
+
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+        PreferenceManager preferenceManager = new PreferenceManager(mContext);
+        mScreen = preferenceManager.createPreferenceScreen(mContext);
+        when(mPreference.getKey()).thenReturn(VPN_PREFERENCE_KEY);
+        mScreen.addPreference(mPreference);
 
         mController = spy(new VpnPreferenceController(mContext));
         mLifecycleOwner = () -> mLifecycle;
@@ -83,13 +95,20 @@
 
     @Test
     public void displayPreference_available_shouldSetDependency() {
-        doReturn(true).when(mController).isAvailable();
-        mController.displayPreference(mScreen);
+        Settings.Global.putString(mContext.getContentResolver(),
+                Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS, "");
+        VpnPreferenceController controller = spy(new VpnPreferenceController(mContext));
+        doReturn(true).when(controller).isAvailable();
+
+        controller.displayPreference(mScreen);
 
         verify(mPreference).setDependency(SettingsSlicesContract.KEY_AIRPLANE_MODE);
     }
 
     @Test
+    // TODO(b/176821216) re-enable this test once VpnPreferenceController is edited to notify
+    // the preference of legacy VPNs
+    @Ignore
     public void goThroughLifecycle_shouldRegisterUnregisterListener() {
         doReturn(true).when(mController).isAvailable();
 
@@ -107,7 +126,7 @@
         final VpnConfig config = new VpnConfig();
         config.legacy = true;
         final VpnPreferenceController controller =
-                new VpnPreferenceController(RuntimeEnvironment.application);
+                new VpnPreferenceController(ApplicationProvider.getApplicationContext());
 
         final String summary = controller.getNameForVpnConfig(config, UserHandle.CURRENT);
 
diff --git a/tests/unit/src/com/android/settings/network/telephony/NetworkProviderWorkerTest.java b/tests/unit/src/com/android/settings/network/telephony/NetworkProviderWorkerTest.java
index 97f8e11..d052f31 100644
--- a/tests/unit/src/com/android/settings/network/telephony/NetworkProviderWorkerTest.java
+++ b/tests/unit/src/com/android/settings/network/telephony/NetworkProviderWorkerTest.java
@@ -261,24 +261,24 @@
     }
 
     @Test
-    public void isEthernetConnected_connectedEthernet_shouldBeTrue() {
+    public void getInternetType_connectedEthernet_returnInternetEthernet() {
         mMockNetworkProviderWorker.onInternetTypeChanged(INTERNET_ETHERNET);
 
-        assertThat(mMockNetworkProviderWorker.isEthernetConnected()).isTrue();
+        assertThat(mMockNetworkProviderWorker.getInternetType()).isEqualTo(INTERNET_ETHERNET);
     }
 
     @Test
-    public void isEthernetConnected_connectedWifi_shouldBeFalse() {
+    public void getInternetType_connectedWifi_returnInternetWifi() {
         mMockNetworkProviderWorker.onInternetTypeChanged(INTERNET_WIFI);
 
-        assertThat(mMockNetworkProviderWorker.isEthernetConnected()).isFalse();
+        assertThat(mMockNetworkProviderWorker.getInternetType()).isEqualTo(INTERNET_WIFI);
     }
 
     @Test
-    public void isEthernetConnected_connectedCarrier_shouldBeFalse() {
+    public void getInternetType__connectedCarrier_returnInternetCellular() {
         mMockNetworkProviderWorker.onInternetTypeChanged(INTERNET_CELLULAR);
 
-        assertThat(mMockNetworkProviderWorker.isEthernetConnected()).isFalse();
+        assertThat(mMockNetworkProviderWorker.getInternetType()).isEqualTo(INTERNET_CELLULAR);
     }
 
     public class MockNetworkProviderWorker extends NetworkProviderWorker {
diff --git a/tests/unit/src/com/android/settings/security/SecuritySettingsFeatureProviderImplTest.java b/tests/unit/src/com/android/settings/security/SecuritySettingsFeatureProviderImplTest.java
new file mode 100644
index 0000000..5b0c7b5
--- /dev/null
+++ b/tests/unit/src/com/android/settings/security/SecuritySettingsFeatureProviderImplTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2021 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.security;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class SecuritySettingsFeatureProviderImplTest {
+
+    private SecuritySettingsFeatureProviderImpl mSecuritySettingsFeatureProvider;
+
+    @Before
+    public void setUp() {
+        mSecuritySettingsFeatureProvider = new SecuritySettingsFeatureProviderImpl();
+    }
+
+    @Test
+    public void hasAlternativeSecuritySettingsFragment_returnsFalse() {
+        assertThat(mSecuritySettingsFeatureProvider.hasAlternativeSecuritySettingsFragment())
+                .isFalse();
+    }
+
+    @Test
+    public void getAlternativeSecuritySettingsFragmentClassname_returnsNull() {
+        String alternativeFragmentClassname =
+                mSecuritySettingsFeatureProvider.getAlternativeSecuritySettingsFragmentClassname();
+        assertThat(alternativeFragmentClassname).isNull();
+    }
+}
diff --git a/tests/unit/src/com/android/settings/security/TopLevelSecurityEntryPreferenceControllerTest.java b/tests/unit/src/com/android/settings/security/TopLevelSecurityEntryPreferenceControllerTest.java
new file mode 100644
index 0000000..a9acd2a
--- /dev/null
+++ b/tests/unit/src/com/android/settings/security/TopLevelSecurityEntryPreferenceControllerTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2021 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.security;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.Intent;
+
+import androidx.preference.Preference;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.settings.SettingsActivity;
+import com.android.settings.testutils.FakeFeatureFactory;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class TopLevelSecurityEntryPreferenceControllerTest {
+
+    private static final String PREFERENCE_KEY = "top_level_security";
+    private static final String ALTERNATIVE_FRAGMENT_CLASSNAME = "AlternativeFragmentClassname";
+
+    private TopLevelSecurityEntryPreferenceController mTopLevelSecurityEntryPreferenceController;
+    private Preference mPreference;
+    private FakeFeatureFactory mFeatureFactory;
+    private SecuritySettingsFeatureProvider mSecuritySettingsFeatureProvider;
+
+    @Mock
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mFeatureFactory = FakeFeatureFactory.setupForTest();
+        mSecuritySettingsFeatureProvider = mFeatureFactory.getSecuritySettingsFeatureProvider();
+
+        mPreference = new Preference(ApplicationProvider.getApplicationContext());
+        mPreference.setKey(PREFERENCE_KEY);
+
+        doNothing().when(mContext).startActivity(any(Intent.class));
+        mTopLevelSecurityEntryPreferenceController =
+                new TopLevelSecurityEntryPreferenceController(mContext, PREFERENCE_KEY);
+    }
+
+    @Test
+    public void handlePreferenceTreeClick_forDifferentPreferenceKey_isNotHandled() {
+        Preference preference = new Preference(ApplicationProvider.getApplicationContext());
+        preference.setKey("some_other_preference");
+
+        boolean preferenceHandled =
+                mTopLevelSecurityEntryPreferenceController.handlePreferenceTreeClick(preference);
+
+        assertThat(preferenceHandled).isFalse();
+    }
+
+    @Test
+    public void handlePreferenceTreeClick_withAlternativeFragment_launchesAlternativeFragment() {
+        when(mSecuritySettingsFeatureProvider.hasAlternativeSecuritySettingsFragment())
+                .thenReturn(true);
+        when(mSecuritySettingsFeatureProvider.getAlternativeSecuritySettingsFragmentClassname())
+                .thenReturn(ALTERNATIVE_FRAGMENT_CLASSNAME);
+        final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+
+        boolean preferenceHandled =
+                mTopLevelSecurityEntryPreferenceController.handlePreferenceTreeClick(mPreference);
+
+        assertThat(preferenceHandled).isTrue();
+        verify(mContext).startActivity(intentCaptor.capture());
+        assertThat(intentCaptor.getValue().getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
+                .isEqualTo(ALTERNATIVE_FRAGMENT_CLASSNAME);
+    }
+
+    @Test
+    public void handlePreferenceTreeClick_withDisabledAlternative_isNotHandled() {
+        when(mSecuritySettingsFeatureProvider.hasAlternativeSecuritySettingsFragment())
+                .thenReturn(false);
+        when(mSecuritySettingsFeatureProvider.getAlternativeSecuritySettingsFragmentClassname())
+                .thenReturn(ALTERNATIVE_FRAGMENT_CLASSNAME);
+
+        boolean preferenceHandled =
+                mTopLevelSecurityEntryPreferenceController.handlePreferenceTreeClick(mPreference);
+
+        assertThat(preferenceHandled).isFalse();
+    }
+
+    @Test
+    public void handlePreferenceTreeClick_withoutAlternativeFragmentName_isNotHandled() {
+        when(mSecuritySettingsFeatureProvider.hasAlternativeSecuritySettingsFragment())
+                .thenReturn(true);
+        when(mSecuritySettingsFeatureProvider.getAlternativeSecuritySettingsFragmentClassname())
+                .thenReturn(null);
+
+        boolean preferenceHandled =
+                mTopLevelSecurityEntryPreferenceController.handlePreferenceTreeClick(mPreference);
+
+        assertThat(preferenceHandled).isFalse();
+    }
+}
diff --git a/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java
index a90c9bf..b6f330b 100644
--- a/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -41,6 +41,7 @@
 import com.android.settings.panel.PanelFeatureProvider;
 import com.android.settings.search.SearchFeatureProvider;
 import com.android.settings.security.SecurityFeatureProvider;
+import com.android.settings.security.SecuritySettingsFeatureProvider;
 import com.android.settings.slices.SlicesFeatureProvider;
 import com.android.settings.users.UserFeatureProvider;
 import com.android.settings.wifi.WifiTrackerLibProvider;
@@ -78,6 +79,7 @@
 
     public WifiTrackerLibProvider wifiTrackerLibProvider;
     public ExtraAppInfoFeatureProvider extraAppInfoFeatureProvider;
+    public SecuritySettingsFeatureProvider securitySettingsFeatureProvider;
 
     /**
      * Call this in {@code @Before} method of the test class to use fake factory.
@@ -116,6 +118,7 @@
         mFaceFeatureProvider = mock(FaceFeatureProvider.class);
         wifiTrackerLibProvider = mock(WifiTrackerLibProvider.class);
         extraAppInfoFeatureProvider = mock(ExtraAppInfoFeatureProvider.class);
+        securitySettingsFeatureProvider = mock(SecuritySettingsFeatureProvider.class);
     }
 
     @Override
@@ -242,4 +245,9 @@
     public ExtraAppInfoFeatureProvider getExtraAppInfoFeatureProvider() {
         return extraAppInfoFeatureProvider;
     }
+
+    @Override
+    public SecuritySettingsFeatureProvider getSecuritySettingsFeatureProvider() {
+        return securitySettingsFeatureProvider;
+    }
 }
diff --git a/tests/unit/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceControllerTest.java b/tests/unit/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceControllerTest.java
index a2b99bf..0729780 100644
--- a/tests/unit/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceControllerTest.java
@@ -121,20 +121,20 @@
     }
 
     @Test
-    public void isMaximizeCompatibilityEnabled_concurrencySupportedAndEnabled_returnTure() {
+    public void isMaximizeCompatibilityEnabled_concurrencySupportedAndEnabled_returnFalse() {
         // The preconditions are ready in setup().
 
-        assertThat(mController.isMaximizeCompatibilityEnabled()).isEqualTo(true);
+        assertThat(mController.isMaximizeCompatibilityEnabled()).isEqualTo(false);
     }
 
     @Test
-    public void isMaximizeCompatibilityEnabled_concurrencySupportedAndDisabled_returnFalse() {
+    public void isMaximizeCompatibilityEnabled_concurrencySupportedAndDisabled_returnTrue() {
         SoftApConfiguration config = new SoftApConfiguration.Builder()
                 .setBridgedModeOpportunisticShutdownEnabled(false)
                 .build();
         doReturn(config).when(mWifiManager).getSoftApConfiguration();
 
-        assertThat(mController.isMaximizeCompatibilityEnabled()).isEqualTo(false);
+        assertThat(mController.isMaximizeCompatibilityEnabled()).isEqualTo(true);
     }
 
     @Test
@@ -171,25 +171,25 @@
     }
 
     @Test
-    public void setupMaximizeCompatibility_concurrencySupportedAndDisabled_setDisabled() {
+    public void setupMaximizeCompatibility_concurrencySupportedAndDisabled_setEnabled() {
         // The precondition of the concurrency supported is ready in setup().
         mController.onPreferenceChange(mPreference, false);
 
         SoftApConfiguration.Builder builder = new SoftApConfiguration.Builder();
         mController.setupMaximizeCompatibility(builder);
 
-        assertThat(builder.build().isBridgedModeOpportunisticShutdownEnabled()).isEqualTo(false);
+        assertThat(builder.build().isBridgedModeOpportunisticShutdownEnabled()).isEqualTo(true);
     }
 
     @Test
-    public void setupMaximizeCompatibility_concurrencySupportedAndEnabled_setEnabled() {
+    public void setupMaximizeCompatibility_concurrencySupportedAndEnabled_setDisabled() {
         // The precondition of the concurrency supported is ready in setup().
         mController.onPreferenceChange(mPreference, true);
 
         SoftApConfiguration.Builder builder = new SoftApConfiguration.Builder();
         mController.setupMaximizeCompatibility(builder);
 
-        assertThat(builder.build().isBridgedModeOpportunisticShutdownEnabled()).isEqualTo(true);
+        assertThat(builder.build().isBridgedModeOpportunisticShutdownEnabled()).isEqualTo(false);
     }
 
     @Test