Merge "Refine NFC settings UX"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index bf64ebe..290f84e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1951,7 +1951,6 @@
             android:targetActivity=".accessibility.AccessibilitySettingsForSetupWizardActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
-                <category android:name="com.android.settings.suggested.category.DISPLAY_SETTINGS" />
             </intent-filter>
             <meta-data android:name="com.android.settings.title"
                 android:resource="@string/vision_settings_suggestion_title" />
@@ -1961,6 +1960,29 @@
                 android:value="com.android.settings.accessibility.AccessibilitySettingsForSetupWizard" />
         </activity-alias>
 
+        <activity-alias
+            android:name=".TextReadingForSetupWizardActivity"
+            android:exported="true"
+            android:icon="@drawable/ic_font_download"
+            android:targetActivity=".accessibility.AccessibilitySettingsForSetupWizardActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <!-- TODO(b/1352717): Consider replacing it with another category, temporarily
+                using an older one to avoid side problems. -->
+                <category android:name="com.android.settings.suggested.category.DISPLAY_SETTINGS" />
+            </intent-filter>
+
+            <meta-data
+                android:name="com.android.settings.title"
+                android:resource="@string/accessibility_text_reading_options_suggestion_title" />
+            <meta-data
+                android:name="com.android.settings.icon_tintable"
+                android:value="true" />
+            <meta-data
+                android:name="com.android.settings.FRAGMENT_CLASS"
+                android:value="com.android.settings.accessibility.TextReadingPreferenceFragmentForSetupWizard" />
+        </activity-alias>
+
         <activity
             android:name=".accessibility.AccessibilityScreenSizeForSetupWizardActivity"
             android:theme="@android:style/Theme.DeviceDefault.Settings"
@@ -2920,24 +2942,6 @@
                 android:value="true" />
         </activity>
 
-        <activity android:name=".dream.DreamSetupActivity"
-                  android:exported="true"
-                  android:immersive="true"
-                  android:theme="@style/SudThemeGlif.DayNight"
-                  android:icon="@drawable/ic_settings_display">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="com.android.settings.suggested.category.SCREEN_SAVER"/>
-            </intent-filter>
-            <meta-data android:name="com.android.settings.is_supported"
-                       android:resource="@bool/dream_setup_supported"/>
-            <meta-data android:name="com.android.settings.title"
-                       android:resource="@string/dream_setup_title"/>
-            <meta-data android:name="com.android.settings.summary"
-                       android:resource="@string/dream_setup_description"/>
-            <meta-data android:name="com.android.settings.icon_tintable" android:value="true"/>
-        </activity>
-
         <activity
             android:name="Settings$UserSettingsActivity"
             android:label="@string/user_settings_title"
@@ -2968,7 +2972,8 @@
         <activity
             android:name=".users.AddSupervisedUserActivity"
             android:label="@*android:string/supervised_user_creation_label"
-            android:icon="@drawable/ic_settings_multiuser">
+            android:icon="@drawable/ic_settings_multiuser"
+            android:exported="true">
         </activity>
 
         <activity
@@ -4340,6 +4345,13 @@
                        android:value="true" />
         </activity>
 
+        <receiver android:name=".safetycenter.SafetySourceBroadcastReceiver"
+                  android:exported="true">
+            <intent-filter>
+                <action android:name="android.safetycenter.action.REFRESH_SAFETY_SOURCES"/>
+            </intent-filter>
+        </receiver>
+
         <!-- This is the longest AndroidManifest.xml ever. -->
     </application>
 </manifest>
diff --git a/color-check-baseline.xml b/color-check-baseline.xml
index 559a589..ba4d2f6 100644
--- a/color-check-baseline.xml
+++ b/color-check-baseline.xml
@@ -2885,6 +2885,22 @@
         priority="4"
         summary="Using hardcoded color"
         explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+        errorLine1="            android:color=&quot;@color/accessibility_feature_background&quot;/>"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/drawable/ic_audio_description.xml"
+            line="22"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="HardCodedColor"
+        severity="Error"
+        message="Avoid using hardcoded color"
+        category="Correctness"
+        priority="4"
+        summary="Using hardcoded color"
+        explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
         errorLine1="        android:fillColor=&quot;@color/battery_good_color_light&quot;"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -3720,7 +3736,7 @@
         errorLine1="            android:color=&quot;@color/accessibility_feature_background&quot;/>"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="res/drawable/ic_text_and_display.xml"
+            file="res/drawable/ic_color_and_motion.xml"
             line="22"
             column="13"/>
     </issue>
diff --git a/res/drawable/accessibility_text_reading_reset_button_background.xml b/res/drawable/accessibility_text_reading_reset_button_background.xml
new file mode 100644
index 0000000..b86facf
--- /dev/null
+++ b/res/drawable/accessibility_text_reading_reset_button_background.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2022 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.
+-->
+
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+    android:shape="rectangle">
+
+    <corners android:radius="100dp" />
+    <solid android:color="?androidprv:attr/colorAccentPrimary" />
+</shape>
diff --git a/res/drawable/dream_preview_icon.xml b/res/drawable/dream_preview_icon.xml
new file mode 100644
index 0000000..c4bd739
--- /dev/null
+++ b/res/drawable/dream_preview_icon.xml
@@ -0,0 +1,24 @@
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path android:fillColor="@android:color/white"
+          android:pathData="M12,16Q13.875,16 15.188,14.688Q16.5,13.375 16.5,11.5Q16.5,9.625 15.188,8.312Q13.875,7 12,7Q10.125,7 8.812,8.312Q7.5,9.625 7.5,11.5Q7.5,13.375 8.812,14.688Q10.125,16 12,16ZM12,14.2Q10.875,14.2 10.088,13.412Q9.3,12.625 9.3,11.5Q9.3,10.375 10.088,9.587Q10.875,8.8 12,8.8Q13.125,8.8 13.913,9.587Q14.7,10.375 14.7,11.5Q14.7,12.625 13.913,13.412Q13.125,14.2 12,14.2ZM12,19Q8.35,19 5.35,16.962Q2.35,14.925 1,11.5Q2.35,8.075 5.35,6.037Q8.35,4 12,4Q15.65,4 18.65,6.037Q21.65,8.075 23,11.5Q21.65,14.925 18.65,16.962Q15.65,19 12,19ZM12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5ZM12,17Q14.825,17 17.188,15.512Q19.55,14.025 20.8,11.5Q19.55,8.975 17.188,7.487Q14.825,6 12,6Q9.175,6 6.812,7.487Q4.45,8.975 3.2,11.5Q4.45,14.025 6.812,15.512Q9.175,17 12,17Z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_audio_description.xml b/res/drawable/ic_audio_description.xml
new file mode 100644
index 0000000..0226582
--- /dev/null
+++ b/res/drawable/ic_audio_description.xml
@@ -0,0 +1,35 @@
+<!--
+  Copyright 2022 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.
+  -->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item>
+        <com.android.settingslib.widget.AdaptiveIconShapeDrawable
+            android:width="@dimen/accessibility_icon_size"
+            android:height="@dimen/accessibility_icon_size"
+            android:color="@color/accessibility_feature_background"/>
+    </item>
+    <item android:gravity="center">
+        <vector
+            android:width="@dimen/accessibility_icon_foreground_size"
+            android:height="@dimen/accessibility_icon_foreground_size"
+            android:viewportWidth="24"
+            android:viewportHeight="24">
+            <path
+                android:fillColor="@android:color/white"
+                android:pathData="M10,18v-4L8,14v-2q0,-1.65 1.175,-2.825Q10.35,8 12,8q1.65,0 2.825,1.175Q16,10.35 16,12v2h-2v4h2.8q0.5,0 0.85,-0.35t0.35,-0.85L18,12q0,-2.5 -1.75,-4.25T12,6Q9.5,6 7.75,7.75T6,12v4.8q0,0.5 0.35,0.85t0.85,0.35zM5,21q-0.825,0 -1.413,-0.587Q3,19.825 3,19L3,5q0,-0.825 0.587,-1.413Q4.175,3 5,3h14q0.825,0 1.413,0.587Q21,4.175 21,5v14q0,0.825 -0.587,1.413Q19.825,21 19,21zM5,19h14L19,5L5,5v14zM5,19L5,5v14z"/>
+        </vector>
+    </item>
+</layer-list>
\ No newline at end of file
diff --git a/res/drawable/ic_text_and_display.xml b/res/drawable/ic_color_and_motion.xml
similarity index 100%
rename from res/drawable/ic_text_and_display.xml
rename to res/drawable/ic_color_and_motion.xml
diff --git a/res/layout/accessibility_text_reading_reset_button.xml b/res/layout/accessibility_text_reading_reset_button.xml
new file mode 100644
index 0000000..43800df
--- /dev/null
+++ b/res/layout/accessibility_text_reading_reset_button.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2022 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.
+-->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart">
+
+    <Button
+        android:id="@+id/reset_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:background="@drawable/accessibility_text_reading_reset_button_background"
+        android:paddingHorizontal="24dp"
+        android:paddingVertical="14dp"
+        android:text="@string/accessibility_text_reading_reset_button_title"
+        android:textAppearance="?android:attr/textAppearanceMedium" />
+</FrameLayout>
diff --git a/res/layout/dream_picker_layout.xml b/res/layout/dream_picker_layout.xml
index 6530ea2..6de7ff6 100644
--- a/res/layout/dream_picker_layout.xml
+++ b/res/layout/dream_picker_layout.xml
@@ -40,17 +40,6 @@
                 app:layout_constraintStart_toStartOf="parent"
                 app:layout_constraintEnd_toEndOf="parent"/>
 
-            <Button
-                android:id="@+id/preview_button"
-                style="@style/ActionPrimaryButton"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:visibility="gone"
-                android:text="@string/dream_preview_button_title"
-                app:layout_constraintTop_toBottomOf="@+id/dream_list"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintEnd_toEndOf="parent"/>
-
         </androidx.constraintlayout.widget.ConstraintLayout>
 
     </androidx.cardview.widget.CardView>
diff --git a/res/layout/dream_preview_button.xml b/res/layout/dream_preview_button.xml
new file mode 100644
index 0000000..b347863
--- /dev/null
+++ b/res/layout/dream_preview_button.xml
@@ -0,0 +1,33 @@
+<!--
+  ~ Copyright (C) 2022 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.material.floatingactionbutton.ExtendedFloatingActionButton
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/dream_preview_button"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:text="@string/dream_preview_button_title"
+    android:textAllCaps="false"
+    android:textColor="?androidprv:attr/textColorOnAccent"
+    android:theme="@style/Theme.CollapsingToolbar.Settings"
+    android:layout_marginBottom="16dp"
+    android:layout_gravity="bottom|center"
+    app:backgroundTint="?androidprv:attr/colorAccentPrimaryVariant"
+    app:iconTint="?androidprv:attr/textColorOnAccent"
+    app:icon="@drawable/dream_preview_icon"/>
diff --git a/res/layout/dream_setup_layout.xml b/res/layout/dream_setup_layout.xml
deleted file mode 100644
index 31a0fb1..0000000
--- a/res/layout/dream_setup_layout.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2022 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"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/setup_wizard_layout"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:icon="@drawable/ic_settings_display"
-    app:sucHeaderText="@string/dream_setup_title"
-    app:sudDescriptionText="@string/dream_setup_description">
-
-    <RelativeLayout
-        android:id="@+id/dream_container"
-        style="@style/SudContentFrame"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent">
-        <androidx.recyclerview.widget.RecyclerView
-            android:id="@+id/dream_setup_list"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"/>
-    </RelativeLayout>
-
-</com.google.android.setupdesign.GlifLayout>
\ No newline at end of file
diff --git a/res/layout/lockscreen_remote_input.xml b/res/layout/lockscreen_remote_input.xml
deleted file mode 100644
index 4fa44ce..0000000
--- a/res/layout/lockscreen_remote_input.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2016 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content">
-
-    <CheckBox
-            android:id="@+id/lockscreen_remote_input"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:layout_marginStart="20dp"
-            android:paddingStart="20dp"
-            android:paddingEnd="?android:attr/dialogPreferredPadding"
-            android:minHeight="?android:attr/listPreferredItemHeightSmall"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textColor="?android:attr/textColorAlertDialogListItem"
-            android:gravity="center_vertical"
-            android:text="@string/lockscreen_remote_input"
-        />
-
-    <ImageView
-            android:id="@+id/restricted_lock_icon_remote_input"
-            android:layout_width="@*android:dimen/config_restrictedIconSize"
-            android:layout_height="@*android:dimen/config_restrictedIconSize"
-            android:tint="?android:attr/colorAccent"
-            android:src="@*android:drawable/ic_info"
-            android:layout_marginEnd="?android:attr/dialogPreferredPadding"
-            android:layout_gravity="center_vertical"
-            android:scaleType="centerInside" />
-</LinearLayout>
diff --git a/res/layout/restricted_dialog_singlechoice.xml b/res/layout/restricted_dialog_singlechoice.xml
index a9984a8..9b19884 100644
--- a/res/layout/restricted_dialog_singlechoice.xml
+++ b/res/layout/restricted_dialog_singlechoice.xml
@@ -35,14 +35,4 @@
             android:drawableStart="?android:attr/listChoiceIndicatorSingle"
             android:drawablePadding="20dp"
             android:ellipsize="marquee" />
-    <ImageView
-            android:id="@+id/restricted_lock_icon"
-            android:layout_width="@*android:dimen/config_restrictedIconSize"
-            android:layout_height="@*android:dimen/config_restrictedIconSize"
-            android:tint="?android:attr/colorAccent"
-            android:src="@*android:drawable/ic_info"
-            android:layout_marginLeft="@dimen/restricted_icon_padding"
-            android:baselineAlignBottom="true"
-            android:scaleType="centerInside"
-            android:visibility="gone" />
 </com.android.settings.CheckableLinearLayout>
diff --git a/res/layout/restricted_preference_dropdown.xml b/res/layout/restricted_preference_dropdown.xml
deleted file mode 100644
index 8930e24..0000000
--- a/res/layout/restricted_preference_dropdown.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2016 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
-  -->
-<FrameLayout
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content">
-
-    <view android:id="@+id/spinner"
-            class="com.android.settings.notification.RestrictedDropDownPreference$ReselectionSpinner"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:visibility="invisible"
-            android:layout_marginStart="@dimen/preference_no_icon_padding_start"/>
-
-    <include layout="@layout/settingslib_preference" />
-
-</FrameLayout>
\ No newline at end of file
diff --git a/res/layout/restricted_radio_with_summary.xml b/res/layout/restricted_radio_with_summary.xml
deleted file mode 100644
index 5e7fcd8..0000000
--- a/res/layout/restricted_radio_with_summary.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2016 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.android.settings.CheckableLinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical"
-    android:background="?android:attr/selectableItemBackground"
-    android:minHeight="?android:attr/listPreferredItemHeightSmall">
-
-    <com.android.settings.CheckableLinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingStart="20dp"
-        android:paddingEnd="?android:attr/dialogPreferredPadding">
-        <CheckedTextView
-            android:id="@android:id/title"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textColor="?android:attr/textColorAlertDialogListItem"
-            android:gravity="center_vertical"
-            android:drawableStart="?android:attr/listChoiceIndicatorSingle"
-            android:ellipsize="marquee" />
-        <ImageView
-            android:id="@+id/restricted_icon"
-            android:layout_width="@*android:dimen/config_restrictedIconSize"
-            android:layout_height="match_parent"
-            android:scaleType="centerInside"
-            android:tint="?android:attr/colorAccent"
-            android:src="@*android:drawable/ic_info"
-            android:layout_marginLeft="@dimen/restricted_icon_padding"
-            android:visibility="gone" />
-    </com.android.settings.CheckableLinearLayout>
-
-
-    <TextView android:id="@android:id/summary"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingBottom="8dp"
-        android:paddingStart="52dp"
-        android:textAppearance="?android:attr/textAppearanceListItemSecondary"
-        android:textColor="?android:attr/textColorSecondary"
-        android:maxLines="10" />
-
-</com.android.settings.CheckableLinearLayout>
diff --git a/res/layout/spinner_dropdown_restricted_item.xml b/res/layout/spinner_dropdown_restricted_item.xml
deleted file mode 100644
index d95e4be..0000000
--- a/res/layout/spinner_dropdown_restricted_item.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:gravity="center_vertical">
-    <TextView android:id="@android:id/text1"
-            style="?android:attr/spinnerDropDownItemStyle"
-            android:singleLine="true"
-            android:layout_width="0dp"
-            android:layout_weight="1"
-            android:layout_height="?android:attr/listPreferredItemHeightSmall"
-            android:ellipsize="marquee" />
-    <ImageView android:id="@+id/restricted_icon"
-            android:layout_width="@*android:dimen/config_restrictedIconSize"
-            android:layout_height="@*android:dimen/config_restrictedIconSize"
-            android:tint="?android:attr/colorAccent"
-            android:src="@*android:drawable/ic_info"
-            android:baselineAlignBottom="true"
-            android:layout_marginEnd="@dimen/restricted_icon_padding"
-            android:gravity="end|center_vertical"
-            android:visibility="gone" />
-</LinearLayout>
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index a3e53f5..5ebaeed 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -816,20 +816,11 @@
     <string-array name="captioning_font_size_selector_titles">
         <item>Very small</item>
         <item>Small</item>
-        <item>Default</item>
+        <item>Medium</item>
         <item>Large</item>
         <item>Very large</item>
     </string-array>
 
-    <!-- Summary for Captions settings, explaining important settings under it. [CHAR LIMIT=NONE] -->
-    <string-array name="captioning_font_size_selector_summaries">
-        <item>Very small text size</item>
-        <item>Small text size</item>
-        <item>Default text size</item>
-        <item>Large text size</item>
-        <item>Very large text size</item>
-    </string-array>
-
     <!-- Values for captioning font size preference. -->
     <string-array name="captioning_font_size_selector_values" translatable="false" >
         <item>0.25</item>
diff --git a/res/values/config.xml b/res/values/config.xml
index 6a7c15b..88e7c7e 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -567,7 +567,19 @@
         <item>2</item>
         <item>3</item>
     </integer-array>
-    
+
+    <!-- The settings/preference description for each settable device state defined in the array
+         "config_perDeviceStateRotationLockDefaults".
+         The item in position "i" describes the auto-rotation setting for the device state also in
+         position "i" in the array "config_perDeviceStateRotationLockDefaults". -->
+    <string-array name="config_settableAutoRotationDeviceStatesDescriptions">
+        <!-- Example:
+            <item>Auto-rotate when folded</item>
+            <item>@null</item> No description for state in position 1
+            <item>Auto-rotate when unfolded</item>
+        -->
+    </string-array>
+
     <!-- Whether to aggregate for network selection list-->
     <bool name="config_network_selection_list_aggregation_enabled">false</bool>
 
@@ -593,4 +605,5 @@
 
     <!-- Whether the dream setup activity should be enabled as part of setupwizard -->
     <bool name="dream_setup_supported">false</bool>
+
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 5a8e233..96b31f2 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -491,6 +491,12 @@
     <!-- Category for the app's locale picker activity. [CHAR LIMIT=50]-->
     <string name="all_supported_app_locales_title">All languages</string>
 
+    <!-- Title for preference of the system default locale. [CHAR LIMIT=50]-->
+    <string name="preference_of_system_locale_title">System language</string>
+
+    <!-- Summary for preference of the system default locale. [CHAR LIMIT=50]-->
+    <string name="preference_of_system_locale_summary">System default - <xliff:g id="default_language" example="English (United States)">%1$s</xliff:g></string>
+
     <!-- Description for the app without any supported languages. [CHAR LIMIT=NONE]-->
     <string name="no_multiple_language_supported">The app is set to <xliff:g id="default_language" example="English (United States)">%1$s</xliff:g> by default and doesn\u2019t support multiple languages.</string>
     <!-- The title of the confirmation dialog shown when the user selects one / several languages and tries to remove them [CHAR LIMIT=60] -->
@@ -597,7 +603,7 @@
     <string name="date_and_time_settings_title_setup_wizard">Set date and time</string>
     <!-- Main Settings screen setting option summary text for the item to go into the date and time settings. -->
     <string name="date_and_time_settings_summary">Set date, time, time zone, &amp; formats</string>
-    <!-- Date & time setting screen setting switch title: whether the system clock (UTC time) should be determined automatically [CHAR LIMIT=100] -->
+    <!-- Date & time setting screen setting switch title: whether the system clock (Unix epoch time) should be determined automatically [CHAR LIMIT=100] -->
     <string name="date_time_auto">Set time automatically</string>
     <!-- Date & time setting screen setting switch title: whether the time zone should be determined automatically [CHAR LIMIT=100]  -->
     <string name="zone_auto_title">Set time zone automatically</string>
@@ -4983,6 +4989,9 @@
     <!-- Summary text for keyboards when no layout has been selected. [CHAR LIMIT=35] -->
     <string name="default_keyboard_layout">Default</string>
 
+    <!-- Title for the 'Speech' preference category. [CHAR LIMIT=45] -->
+    <string name="speech_category_title">Speech</string>
+
     <!-- On Languages & input settings screen, setting summary.  Setting for mouse pointer speed. [CHAR LIMIT=35] -->
     <string name="pointer_speed">Pointer speed</string>
 
@@ -5147,8 +5156,8 @@
     <string name="general_category_title">General</string>
     <!-- Title for the accessibility preference category of display services and settings. [CHAR LIMIT=50] -->
     <string name="display_category_title">Display</string>
-    <!-- Title for the accessibility text options page. [CHAR LIMIT=50] -->
-    <string name="accessibility_text_and_display_title">Text and display</string>
+    <!-- Title for the accessibility color and motion page. [CHAR LIMIT=50] -->
+    <string name="accessibility_color_and_motion_title">Color and motion</string>
     <!-- Title for the accessibility text options page. [CHAR LIMIT=50] -->
     <string name="accessibility_turn_screen_darker_title">Turn screen darker</string>
     <!-- Title for the accessibility preference category of interaction control services and settings. [CHAR LIMIT=50] -->
@@ -5226,13 +5235,17 @@
     <!-- Title for the footer text to explain what accessibility service does. [CHAR LIMIT=35] -->
     <string name="accessibility_introduction_title">About <xliff:g id="service" example="Select to Speak">%1$s</xliff:g></string>
     <!-- Title for the accessibility preference to adjust the display size, font size, bold text, and high contrast text features. [CHAR LIMIT=NONE] -->
-    <string name="accessibility_text_reading_options_title">Text and reading options</string>
+    <string name="accessibility_text_reading_options_title">Display size and text</string>
+    <!-- Title for the entry of the text reading options. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_text_reading_options_suggestion_title">Change how text displays</string>
     <!-- Subject for the mail content of the accessibility text reading preview. [CHAR LIMIT=NONE] -->
     <string name="accessibility_text_reading_preview_mail_subject">Email: Plans for time machine, v2</string>
     <!-- Message for the mail content of the accessibility text reading preview. [CHAR LIMIT=NONE] -->
     <string name="accessibility_text_reading_preview_mail_from">From: bill@email.com</string>
     <!-- Content for the mail content of the accessibility text reading preview. [CHAR LIMIT=NONE] -->
     <string name="accessibility_text_reading_preview_mail_content">Good morning! Following up on our last conversation, I’d like to check in on the progress of your time machine development plan. Will you be able to have a prototype ready to demo at E3 this year?</string>
+    <!-- Title for the reset button of the accessibility text reading page to reset all preferences state. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_text_reading_reset_button_title">Reset</string>
     <!-- Title for the footer text to explain what option accessibility service does. [CHAR LIMIT=35] -->
     <string name="accessibility_screen_option">Options</string>
     <!-- Summary for the accessibility preference to enable screen magnification. [CHAR LIMIT=25] -->
@@ -5241,9 +5254,11 @@
     <string name="accessibility_screen_magnification_short_summary">Tap 3 times to zoom</string>
     <!-- Short summary for nav bar Magnification. Tells the user that this feature allows the user to magnify the screen using a button in the nav bar -->
     <string name="accessibility_screen_magnification_navbar_short_summary">Tap a button to zoom</string>
+    <!-- Intro for the accessibility preference screen to enable screen magnification gestures. [CHAR LIMIT=none] -->
+    <string name="accessibility_screen_magnification_intro_text">Quickly zoom in on the screen to make content larger</string>
     <!-- Summary for the accessibility preference screen to enable screen magnification gestures. [CHAR LIMIT=none] -->
     <string name="accessibility_screen_magnification_summary">
-        <![CDATA[Quickly zoom in on the screen to make content larger.<br/><br/>
+        <![CDATA[
         <b>To zoom in:</b><br/>
         {0,number,integer}. Use shortcut to start magnification<br/>
         {1,number,integer}. Tap the screen<br/>
@@ -5251,10 +5266,11 @@
         {3,number,integer}. Pinch with 2 fingers to adjust zoom<br/>
         {4,number,integer}. Use shortcut to stop magnification<br/><br/>
         <b>To zoom in temporarily:</b><br/>
-        {0,number,integer}. Use shortcut to start magnification<br/>
-        {1,number,integer}. Touch & hold anywhere on the screen<br/>
-        {2,number,integer}. Drag finger to move around screen<br/>
-        {3,number,integer}. Lift finger to stop magnification
+        {0,number,integer}. Make sure your magnification type is set to full screen<br/>
+        {1,number,integer}. Use shortcut to start magnification<br/>
+        {2,number,integer}. Touch & hold anywhere on the screen<br/>
+        {3,number,integer}. Drag finger to move around screen<br/>
+        {4,number,integer}. Lift finger to stop magnification
         ]]>
     </string>
     <!-- Summary for the accessibility preference screen to enable screen magnification via the nav bar. [CHAR LIMIT=none] -->
@@ -5345,6 +5361,8 @@
     <string name="accessibility_button_title">Accessibility button</string>
     <!-- Title for the accessibility button & gesture page. [CHAR LIMIT=35] -->
     <string name="accessibility_button_gesture_title">Accessibility button &amp; gesture</string>
+    <!-- Introduction for the accessibility button page. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_button_intro_text">Quickly access accessibility features from any screen</string>
     <!-- Title for the accessibility button footer. [CHAR LIMIT=35] -->
     <string name="accessibility_button_about_title">About accessibility button</string>
     <!-- Title for the accessibility button & gesture footer. [CHAR LIMIT=55] -->
@@ -5356,9 +5374,9 @@
     <!-- Summary text for the accessibility button preference. [CHAR LIMIT=50] -->
     <string name="accessibility_button_summary">Quickly access accessibility features</string>
     <!-- Description for the accessibility button in gesture navigation. Explain how this page works. [CHAR LIMIT=NONE] -->
-    <string name="accessibility_button_gesture_description">Quickly access accessibility features from any screen.\n\nTo get started, go to accessibility settings and select a feature. Tap on the shortcut and select the accessibility button or gesture.</string>
+    <string name="accessibility_button_gesture_description"><b>How to use the button or gesture</b>\n\n1. Go to accessibility settings\n2. Select a feature and tap the shortcut\n3. To use the feature, tap the accessibility button or gesture</string>
     <!-- Description for the accessibility button page. Explain how this page works. [CHAR LIMIT=NONE] -->
-    <string name="accessibility_button_description">Quickly access accessibility features from any screen.\n\nTo get started, go to accessibility settings and select a feature. Tap on the shortcut and select the accessibility button.</string>
+    <string name="accessibility_button_description"><b>How to use the button</b>\n\n1. Go to accessibility settings\n2. Select a feature and tap the shortcut\n3. To use the feature, tap the accessibility button</string>
     <!-- Title for the button or gesture of the accessibility button. [CHAR LIMIT=35] -->
     <string name="accessibility_button_or_gesture_title">Use button or gesture</string>
     <!-- Title for the location of the accessibility button. [CHAR LIMIT=35] -->
@@ -5377,6 +5395,8 @@
     <string name="accessibility_button_high_label">Non-transparent</string>
     <!-- Title for the accessibility preference to high contrast text. [CHAR LIMIT=35] -->
     <string name="accessibility_toggle_high_text_contrast_preference_title">High contrast text</string>
+    <!-- Summary for the accessibility preference to high contrast text. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_toggle_high_text_contrast_preference_summary">Change text color to black or white. Maximizes contrast with the background.</string>
     <!-- Title for the accessibility preference to auto update screen magnification. [CHAR LIMIT=35] -->
     <string name="accessibility_toggle_screen_magnification_auto_update_preference_title">Auto
         update screen magnification</string>
@@ -5419,7 +5439,9 @@
     <!-- Title for accessibility preference to accessibility timeout. [CHAR LIMIT=35] -->
     <string name="accessibility_control_timeout_preference_title">Time to take action</string>
     <!-- Descriptive text for accessibility preference to accessibility control timeout. [CHAR LIMIT=NONE] -->
-    <string name="accessibility_control_timeout_preference_summary">Choose how long to show messages that ask you to take action, but are visible only temporarily.\n\nNot all apps support this setting.</string>
+    <string name="accessibility_control_timeout_preference_summary">This timing preference isn\u2019t supported by all apps</string>
+    <!-- Intro text for accessibility preference to accessibility control timeout. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_control_timeout_preference_intro_text">Choose how long to show temporary messages that ask you to take action</string>
 
     <!-- Title for accessibility preference to choose long-press delay i.e. timeout before it is detected. [CHAR LIMIT=35] -->
     <string name="accessibility_long_press_timeout_preference_title">Touch &amp; hold delay</string>
@@ -5429,14 +5451,15 @@
     <string name="accessibility_display_inversion_switch_title">Use color inversion</string>
     <!-- Title for accessibility shortcut preference for color inversion. [CHAR LIMIT=60] -->
     <string name="accessibility_display_inversion_shortcut_title">Color inversion shortcut</string>
+    <!-- Intro for the accessibility preference to configure display color inversion. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_display_inversion_preference_intro_text">Color inversion turns light screens dark. It also turns dark screens light.</string>
     <!-- Subtitle for the accessibility preference to configure display color inversion. [CHAR LIMIT=NONE] -->
     <string name="accessibility_display_inversion_preference_subtitle">
-        <![CDATA[Color inversion turns light screens dark.<br/><br/>
-        Note:
+        <![CDATA[<b>Keep in mind</b><br/>
         <ol>
-            <li>\u00a0Color inversion also turns dark screens light.</li>
-            <li>\u00a0Colors will change in media and images.</li>
-            <li>\u00a0Dark theme can be used to display a dark background. Dark theme works with supported apps. Color inversion works on all apps.</li>
+            <li>\u00a0Colors will change in media and images</li>
+            <li>\u00a0Color inversion works on all apps</li>
+            <li>\u00a0To display a dark background, Dark theme can be used instead</li>
         </ol>
         ]]>
     </string>
@@ -5446,10 +5469,12 @@
     <string name="accessibility_autoclick_about_title">About autoclick (dwell timing)</string>
     <!-- Accessibility dwell timing footer link content description [CHAR LIMIT=NONE] -->
     <string name="accessibility_autoclick_footer_learn_more_content_description">Learn more about autoclick (dwell timing)</string>
-    <!-- Footer text to explain what autoclick does -->
-    <string name="accessibility_autoclick_description">Autoclick works with a connected mouse. You can set the mouse cursor to click automatically when the cursor stops moving for a certain amount of time.</string>
+    <!-- Intro text to explain what autoclick does. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_autoclick_intro_text">You can set a connected mouse to click automatically when the cursor stops moving for a certain amount of time</string>
+    <!-- Footer text to explain what autoclick does. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_autoclick_description">Autoclick can be helpful if clicking the mouse is difficult</string>
     <!-- Option heading to leave the auto click requirement for accessibility users at its default level. [CHAR LIMIT=50] -->
-    <string name="accessibility_autoclick_default_title">Off</string>
+    <string name="accessibility_autoclick_default_title">Autoclick off</string>
     <!-- Option heading to leave the auto click requirement for accessibility users at its short level. [CHAR LIMIT=35] -->
     <string name="accessibility_autoclick_short_title">Short</string>
     <!-- Option summary text for the auto click delay 0.2 seconds radio button. [CHAR LIMIT=35] -->
@@ -5499,9 +5524,13 @@
     <!-- Used in the accessibility service settings to open the activity. [CHAR LIMIT=NONE] -->
     <string name="accessibility_service_primary_open_title">Open <xliff:g id="accessibility_app_name" example="TalkBack">%1$s</xliff:g></string>
     <!-- Used in the accessibility service settings to show quick settings tooltips. [CHAR LIMIT=NONE] -->
-    <string name="accessibility_service_quick_settings_tooltips_content">Swipe down to quickly turn <xliff:g id="accessibility_app_name" example="TalkBack">%1$s</xliff:g> on or off in quick settings</string>
+    <string name="accessibility_service_quick_settings_tooltips_content"><xliff:g id="accessibility_app_name" example="TalkBack">%1$s</xliff:g> added to Quick Settings. Swipe down to turn it on or off anytime.</string>
     <!-- Used in the accessibility action for accessibility quick settings tooltips to dismiss. [CHAR LIMIT=NONE] -->
     <string name="accessibility_quick_settings_tooltips_dismiss">Dismiss</string>
+    <!-- Intro for color correction settings screen to control turning on/off the feature entirely. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_daltonizer_about_intro_text" product="default">Adjust how colors display on your phone</string>
+    <!-- Intro for color correction settings screen to control turning on/off the feature entirely. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_daltonizer_about_intro_text" product="tablet">Adjust how colors display on your tablet</string>
     <!-- Used in the Color correction settings screen to control turning on/off the feature entirely [CHAR LIMIT=60] -->
     <string name="accessibility_daltonizer_primary_switch_title">Use color correction</string>
     <!-- Title for accessibility shortcut preference for color correction. [CHAR LIMIT=60] -->
@@ -5524,8 +5553,10 @@
     <string name="captioning_caption_appearance_summary"><xliff:g id="accessibility_font_size" example="Large">%1$s</xliff:g> text size</string>
     <!-- Title for Caption preference settings screen for configuring language. [CHAR LIMIT=NONE] -->
     <string name="captioning_more_options_title">More options</string>
-    <!-- Used in the Captions preference to tell users that the setting doesn't support all apps. [CHAR LIMIT=NONE] -->
-    <string name="accessibility_caption_preference_summary">Not all apps support these caption preferences</string>
+    <!-- Introduction for the captions preference page. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_caption_preference_intro">Customize caption size and style to make them easier to read</string>
+    <!-- Summary for the captions preference page. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_caption_preference_summary">These caption preferences aren\u2019t supported by all media apps</string>
     <!-- Summary for accessibility shortcut preference for software shortcut type. [CHAR LIMIT=NONE] -->
     <string name="accessibility_shortcut_type_software">Accessibility button</string>
     <!-- Summary for accessibility shortcut preference for software shortcut type when gesture mode is on. [CHAR LIMIT=NONE] -->
@@ -5554,6 +5585,13 @@
     </plurals>
     <!-- Title for the accessibility audio adjustment page. [CHAR LIMIT=50] -->
     <string name="accessibility_audio_adjustment_title">Audio adjustment</string>
+    <!-- Title for control audio description preference. [CHAR LIMIT=50] -->
+    <string name="accessibility_toggle_audio_description_preference_title">Audio Description</string>
+    <!-- Summary for accessibility preference for audio description when need
+    audio description in adopted apps. [CHAR_LIMIT=NONE] -->
+    <string name="accessibility_audio_description_summary">Select audio sound track with audio description by default</string>
+    <!-- List of synonyms used in the settings search bar to find the "Audio Description. [CHAR LIMIT=NONE] -->
+    <string name="keywords_audio_description">audio description, audio, description, low vision,</string>
 
     <!-- Preference's shortcut when enabled. [CHAR LIMIT=NONE] -->
     <string name="accessibility_summary_shortcut_enabled">Shortcut on</string>
@@ -5572,22 +5610,20 @@
 
     <!-- Title for the preference to show a tile for a particular feature in the Quick Settings pane. [CHAR LIMIT=NONE] -->
     <string name="enable_quick_setting">Show in Quick Settings</string>
-    <!-- Title for the preference to configure the type of color space correction to apply. [CHAR LIMIT=NONE] -->
-    <string name="daltonizer_type">Correction mode</string>
     <!-- Title shown for deuteranomaly (red-green color blindness) [CHAR LIMIT=45] -->
-    <string name="daltonizer_mode_deuteranomaly_title">Deuteranomaly</string>
+    <string name="daltonizer_mode_deuteranomaly_title">Red-green</string>
     <!-- Title shown for protanomaly (red-green color blindness) [CHAR LIMIT=45] -->
-    <string name="daltonizer_mode_protanomaly_title">Protanomaly</string>
+    <string name="daltonizer_mode_protanomaly_title">Red-green</string>
     <!-- Title shown for tritanomaly (blue-yellow color blindness) [CHAR LIMIT=45] -->
-    <string name="daltonizer_mode_tritanomaly_title">Tritanomaly</string>
+    <string name="daltonizer_mode_tritanomaly_title">Blue-yellow</string>
     <!-- Title shown for grayscale [CHAR LIMIT=45] -->
     <string name="daltonizer_mode_grayscale_title">Grayscale</string>
     <!-- Summary shown for deuteranomaly (red-green color blindness) [CHAR LIMIT=45] -->
-    <string name="daltonizer_mode_deuteranomaly_summary">Red-green</string>
+    <string name="daltonizer_mode_deuteranomaly_summary">Green weak, deuteranomaly</string>
     <!-- Summary shown for protanomaly (red-green color blindness) [CHAR LIMIT=45] -->
-    <string name="daltonizer_mode_protanomaly_summary">Red-green</string>
+    <string name="daltonizer_mode_protanomaly_summary">Red weak, protanomaly</string>
     <!-- Summary shown for tritanomaly (blue-yellow color blindness) [CHAR LIMIT=45] -->
-    <string name="daltonizer_mode_tritanomaly_summary">Blue-yellow</string>
+    <string name="daltonizer_mode_tritanomaly_summary">Tritanomaly</string>
 
     <!-- Title for the accessibility preference of the Extra Dim/Reduce Brightness feature that dims your screen. [CHAR LIMIT=NONE] -->
     <string name="reduce_bright_colors_preference_title">Extra dim</string>
@@ -5601,10 +5637,11 @@
     <string name="reduce_bright_colors_preference_summary" product="default">Dim screen beyond your phone\u2019s minimum brightness</string>
     <!-- Summary for the accessibility preference to configure Reduce Brightness feature. [CHAR LIMIT=NONE] -->
     <string name="reduce_bright_colors_preference_summary" product="tablet">Dim screen beyond your tablet\u2019s minimum brightness</string>
+    <!-- Intro that describes Reduce Brightness. [CHAR LIMIT=NONE] -->
+    <string name="reduce_bright_colors_preference_intro_text">Make your screen dimmer so it\u2019s more comfortable to read</string>
     <!-- Subtitle that describes Reduce Brightness. [CHAR LIMIT=NONE] -->
     <string name="reduce_bright_colors_preference_subtitle" product="default">
-        <![CDATA[Make your screen dimmer so it\u2019s more comfortable to read.<br/><br/>
-        This can be helpful when:
+        <![CDATA[Extra dim can be helpful when:
         <ol>
             <li>\u00a0Your phone\u2019s default minimum brightness is still too bright</li>
             <li>\u00a0You\u2019re using your phone in dark situations, like at night or in a dark room before bed</li>
@@ -5613,8 +5650,7 @@
     </string>
     <!-- Subtitle that describes Reduce Brightness. [CHAR LIMIT=NONE] -->
     <string name="reduce_bright_colors_preference_subtitle" product="tablet">
-        <![CDATA[Make your screen darker so it\u2019s more comfortable to read.<br/><br/>
-        This can be helpful when:
+        <![CDATA[Extra dim can be helpful when:
         <ol>
             <li>\u00a0Your tablet\u2019s default minimum brightness is still too bright</li>
             <li>\u00a0You\u2019re using your tablet in dark situations, like at night or in a dark room before bed</li>
diff --git a/res/xml/accessibility_autoclick_settings.xml b/res/xml/accessibility_autoclick_settings.xml
index 617f22a..943bc67 100644
--- a/res/xml/accessibility_autoclick_settings.xml
+++ b/res/xml/accessibility_autoclick_settings.xml
@@ -19,18 +19,21 @@
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:title="@string/accessibility_autoclick_preference_title">
 
+    <com.android.settingslib.widget.TopIntroPreference
+        android:key="accessibility_autoclick_intro"
+        android:persistent="false"
+        android:title="@string/accessibility_autoclick_intro_text" />
+
     <com.android.settingslib.widget.IllustrationPreference
         android:key="accessibility_autoclick_banner"
         android:persistent="false"
         android:selectable="false"
-        settings:allowDividerBelow="true"
         settings:searchable="false"
         settings:lottie_rawRes="@drawable/accessibility_dwell" />
 
     <com.android.settingslib.widget.SelectorWithWidgetPreference
         android:key="accessibility_control_autoclick_default"
-        android:title="@string/accessibility_autoclick_default_title"
-        settings:allowDividerAbove="true" />
+        android:title="@string/accessibility_autoclick_default_title" />
 
     <com.android.settingslib.widget.SelectorWithWidgetPreference
         android:key="accessibility_control_autoclick_200ms"
@@ -56,7 +59,6 @@
         android:layout="@layout/accessibility_autoclick_custom_seekbar"
         android:selectable="false"
         android:visibility="gone"
-        settings:allowDividerBelow="true"
         settings:controller="com.android.settings.accessibility.ToggleAutoclickCustomSeekbarController" />
 
     <com.android.settings.accessibility.AccessibilityFooterPreference
diff --git a/res/xml/accessibility_button_settings.xml b/res/xml/accessibility_button_settings.xml
index 86dd087..ab9fc41 100644
--- a/res/xml/accessibility_button_settings.xml
+++ b/res/xml/accessibility_button_settings.xml
@@ -14,61 +14,65 @@
      limitations under the License.
 -->
 
-<PreferenceScreen
-    xmlns:android="http://schemas.android.com/apk/res/android"
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:settings="http://schemas.android.com/apk/res-auto">
 
+    <com.android.settingslib.widget.TopIntroPreference
+        android:key="accessibility_button_intro"
+        android:persistent="false"
+        android:title="@string/accessibility_button_intro_text" />
+
     <com.android.settingslib.widget.IllustrationPreference
         android:key="accessibility_button_preview"
-        android:selectable="false"
-        settings:searchable="false"
         android:persistent="false"
-        settings:controller="com.android.settings.accessibility.AccessibilityButtonPreviewPreferenceController"/>
+        android:selectable="false"
+        settings:controller="com.android.settings.accessibility.AccessibilityButtonPreviewPreferenceController"
+        settings:searchable="false" />
 
     <ListPreference
         android:entries="@array/accessibility_button_location_selector_titles"
         android:entryValues="@array/accessibility_button_location_selector_values"
         android:key="accessibility_button_location"
-        android:title="@string/accessibility_button_location_title"
-        android:summary="%s"
         android:persistent="false"
-        settings:controller="com.android.settings.accessibility.AccessibilityButtonLocationPreferenceController"/>
+        android:summary="%s"
+        android:title="@string/accessibility_button_location_title"
+        settings:controller="com.android.settings.accessibility.AccessibilityButtonLocationPreferenceController" />
 
     <ListPreference
         android:entries="@array/accessibility_button_gesture_selector_titles"
         android:entryValues="@array/accessibility_button_gesture_selector_values"
         android:key="accessibility_button_or_gesture"
-        android:title="@string/accessibility_button_or_gesture_title"
-        android:summary="%s"
         android:persistent="false"
-        settings:controller="com.android.settings.accessibility.AccessibilityButtonGesturePreferenceController"/>
+        android:summary="%s"
+        android:title="@string/accessibility_button_or_gesture_title"
+        settings:controller="com.android.settings.accessibility.AccessibilityButtonGesturePreferenceController" />
 
     <ListPreference
         android:entries="@array/accessibility_button_size_selector_titles"
         android:entryValues="@array/accessibility_button_size_selector_values"
         android:key="accessibility_button_size"
-        android:title="@string/accessibility_button_size_title"
-        android:summary="%s"
         android:persistent="false"
-        settings:controller="com.android.settings.accessibility.FloatingMenuSizePreferenceController"/>
+        android:summary="%s"
+        android:title="@string/accessibility_button_size_title"
+        settings:controller="com.android.settings.accessibility.FloatingMenuSizePreferenceController" />
 
     <SwitchPreference
         android:key="accessibility_button_fade"
-        android:title="@string/accessibility_button_fade_title"
-        android:summary="@string/accessibility_button_fade_summary"
         android:persistent="false"
-        settings:controller="com.android.settings.accessibility.FloatingMenuFadePreferenceController"/>
+        android:summary="@string/accessibility_button_fade_summary"
+        android:title="@string/accessibility_button_fade_title"
+        settings:controller="com.android.settings.accessibility.FloatingMenuFadePreferenceController" />
 
     <com.android.settings.widget.SeekBarPreference
         android:key="accessibility_button_opacity"
-        android:title="@string/accessibility_button_opacity_title"
         android:persistent="false"
-        settings:controller="com.android.settings.accessibility.FloatingMenuTransparencyPreferenceController"/>
+        android:title="@string/accessibility_button_opacity_title"
+        settings:controller="com.android.settings.accessibility.FloatingMenuTransparencyPreferenceController" />
 
     <com.android.settings.accessibility.AccessibilityFooterPreference
         android:key="accessibility_button_footer"
         android:persistent="false"
         android:selectable="false"
-        settings:searchable="false"
-        settings:controller="com.android.settings.accessibility.AccessibilityButtonFooterPreferenceController"/>
+        settings:controller="com.android.settings.accessibility.AccessibilityButtonFooterPreferenceController"
+        settings:searchable="false" />
 </PreferenceScreen>
diff --git a/res/xml/accessibility_text_and_display.xml b/res/xml/accessibility_color_and_motion.xml
similarity index 62%
rename from res/xml/accessibility_text_and_display.xml
rename to res/xml/accessibility_color_and_motion.xml
index 659acab..f251d1e 100644
--- a/res/xml/accessibility_text_and_display.xml
+++ b/res/xml/accessibility_color_and_motion.xml
@@ -17,34 +17,9 @@
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:settings="http://schemas.android.com/apk/res-auto"
-    android:key="accessibility_text_and_display"
+    android:key="accessibility_color_and_motion"
     android:persistent="false"
-    android:title="@string/accessibility_text_and_display_title">
-
-    <Preference
-        android:fragment="com.android.settings.display.ToggleFontSizePreferenceFragment"
-        android:icon="@drawable/ic_font_size"
-        android:key="font_size_preference_screen"
-        android:persistent="false"
-        android:title="@string/title_font_size"
-        settings:controller="com.android.settings.display.FontSizePreferenceController"
-        settings:searchable="false"/>
-
-    <com.android.settings.display.ScreenZoomPreference
-        android:fragment="com.android.settings.display.ScreenZoomSettings"
-        android:icon="@drawable/ic_screen_zoom"
-        android:key="accessibility_settings_screen_zoom"
-        android:persistent="false"
-        android:title="@string/screen_zoom_title"
-        settings:searchable="false"/>
-
-    <SwitchPreference
-        android:key="toggle_force_bold_text"
-        android:icon="@drawable/ic_force_bold"
-        android:persistent="false"
-        android:title="@string/force_bold_text"
-        settings:keywords="@string/keywords_bold_text"
-        settings:controller="com.android.settings.accessibility.FontWeightAdjustmentPreferenceController"/>
+    android:title="@string/accessibility_color_and_motion_title">
 
     <Preference
         android:fragment="com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment"
@@ -76,12 +51,6 @@
         android:title="@string/accessibility_toggle_large_pointer_icon_title"
         settings:controller="com.android.settings.accessibility.LargePointerIconPreferenceController"/>
 
-    <SwitchPreference
-        android:key="toggle_high_text_contrast_preference"
-        android:persistent="false"
-        android:title="@string/accessibility_toggle_high_text_contrast_preference_title"
-        settings:controller="com.android.settings.accessibility.HighTextContrastPreferenceController"/>
-
     <PreferenceCategory
         android:key="experimental_category"
         android:persistent="false"
diff --git a/res/xml/accessibility_control_timeout_settings.xml b/res/xml/accessibility_control_timeout_settings.xml
index aaa2c06..3cd0dd6 100644
--- a/res/xml/accessibility_control_timeout_settings.xml
+++ b/res/xml/accessibility_control_timeout_settings.xml
@@ -21,6 +21,11 @@
     android:title="@string/accessibility_control_timeout_preference_title"
     android:persistent="false" >
 
+    <com.android.settingslib.widget.TopIntroPreference
+        android:key="accessibility_control_timeout_intro"
+        android:persistent="false"
+        android:title="@string/accessibility_control_timeout_preference_intro_text" />
+
     <com.android.settingslib.widget.IllustrationPreference
         android:key="accessibility_control_timeout_banner"
         settings:lottie_rawRes="@raw/accessibility_timeout_banner"/>
@@ -28,7 +33,6 @@
     <com.android.settingslib.widget.SelectorWithWidgetPreference
         android:key="accessibility_control_timeout_default"
         android:title="@string/accessibility_timeout_default"
-        settings:allowDividerAbove="true"
         android:persistent="false" />
 
     <com.android.settingslib.widget.SelectorWithWidgetPreference
diff --git a/res/xml/accessibility_daltonizer_settings.xml b/res/xml/accessibility_daltonizer_settings.xml
index 1b69dc6..91b163b 100644
--- a/res/xml/accessibility_daltonizer_settings.xml
+++ b/res/xml/accessibility_daltonizer_settings.xml
@@ -28,32 +28,27 @@
         settings:allowDividerBelow="true"
         settings:searchable="false"/>
 
-    <PreferenceCategory
-        android:title="@string/daltonizer_type"
-        android:key="daltonizer_mode_category" >
+    <com.android.settingslib.widget.SelectorWithWidgetPreference
+        android:key="daltonizer_mode_deuteranomaly"
+        android:persistent="false"
+        android:summary="@string/daltonizer_mode_deuteranomaly_summary"
+        android:title="@string/daltonizer_mode_deuteranomaly_title" />
 
-        <com.android.settingslib.widget.SelectorWithWidgetPreference
-            android:key="daltonizer_mode_deuteranomaly"
-            android:persistent="false"
-            android:summary="@string/daltonizer_mode_deuteranomaly_summary"
-            android:title="@string/daltonizer_mode_deuteranomaly_title" />
+    <com.android.settingslib.widget.SelectorWithWidgetPreference
+        android:key="daltonizer_mode_protanomaly"
+        android:persistent="false"
+        android:summary="@string/daltonizer_mode_protanomaly_summary"
+        android:title="@string/daltonizer_mode_protanomaly_title" />
 
-        <com.android.settingslib.widget.SelectorWithWidgetPreference
-            android:key="daltonizer_mode_protanomaly"
-            android:persistent="false"
-            android:summary="@string/daltonizer_mode_protanomaly_summary"
-            android:title="@string/daltonizer_mode_protanomaly_title" />
+    <com.android.settingslib.widget.SelectorWithWidgetPreference
+        android:key="daltonizer_mode_tritanomaly"
+        android:persistent="false"
+        android:summary="@string/daltonizer_mode_tritanomaly_summary"
+        android:title="@string/daltonizer_mode_tritanomaly_title" />
 
-        <com.android.settingslib.widget.SelectorWithWidgetPreference
-            android:key="daltonizer_mode_tritanomaly"
-            android:persistent="false"
-            android:summary="@string/daltonizer_mode_tritanomaly_summary"
-            android:title="@string/daltonizer_mode_tritanomaly_title" />
-        <com.android.settingslib.widget.SelectorWithWidgetPreference
-            android:key="daltonizer_mode_grayscale"
-            android:persistent="false"
-            android:title="@string/daltonizer_mode_grayscale_title" />
-
-    </PreferenceCategory>
+    <com.android.settingslib.widget.SelectorWithWidgetPreference
+        android:key="daltonizer_mode_grayscale"
+        android:persistent="false"
+        android:title="@string/daltonizer_mode_grayscale_title" />
 
 </PreferenceScreen>
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index dcf3fc2..22226a1 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -36,21 +36,19 @@
         android:persistent="false"
         android:title="@string/display_category_title">
 
-        <!-- After completely finishing the Text and reading options feature, it will be visible. -->
         <Preference
             android:fragment="com.android.settings.accessibility.TextReadingPreferenceFragment"
             android:icon="@drawable/ic_adaptive_font_download"
             android:key="text_reading_options"
             android:persistent="false"
-            android:title="@string/accessibility_text_reading_options_title"
-            settings:isPreferenceVisible="false"/>
+            android:title="@string/accessibility_text_reading_options_title" />
 
         <Preference
-            android:fragment="com.android.settings.accessibility.TextAndDisplayFragment"
-            android:key="text_and_display_preference_screen"
-            android:icon="@drawable/ic_text_and_display"
+            android:fragment="com.android.settings.accessibility.ColorAndMotionFragment"
+            android:key="color_and_motion"
+            android:icon="@drawable/ic_color_and_motion"
             android:persistent="false"
-            android:title="@string/accessibility_text_and_display_title"
+            android:title="@string/accessibility_color_and_motion_title"
             settings:searchable="true"/>
 
         <com.android.settingslib.PrimarySwitchPreference
@@ -81,6 +79,16 @@
             settings:keywords="@string/keywords_magnification"
             settings:controller="com.android.settings.accessibility.MagnificationPreferenceController"/>
 
+        <SwitchPreference
+            android:key="toggle_audio_description"
+            android:persistent="false"
+            android:icon="@drawable/ic_audio_description"
+            android:summary="@string/accessibility_audio_description_summary"
+            android:title="@string/accessibility_toggle_audio_description_preference_title"
+            settings:keywords="@string/keywords_audio_description"
+            settings:searchable="true"
+            settings:controller="com.android.settings.accessibility.AudioDescriptionPreferenceController"/>
+
     </PreferenceCategory>
 
     <PreferenceCategory
diff --git a/res/xml/accessibility_settings_for_setup_wizard.xml b/res/xml/accessibility_settings_for_setup_wizard.xml
index 3272ae5..78d8f72 100644
--- a/res/xml/accessibility_settings_for_setup_wizard.xml
+++ b/res/xml/accessibility_settings_for_setup_wizard.xml
@@ -26,24 +26,9 @@
         android:key="text_reading_options"
         android:persistent="false"
         android:title="@string/accessibility_text_reading_options_title"
-        settings:isPreferenceVisible="false"
         settings:keywords="text_reading_options" />
 
     <Preference
-        android:key="font_size_preference"
-        android:icon="@drawable/ic_font_size"
-        android:summary="@string/short_summary_font_size"
-        android:title="@string/title_font_size"
-        settings:controller="com.android.settings.accessibility.FontSizePreferenceController" />
-
-    <com.android.settings.display.ScreenZoomPreference
-        android:key="force_density_preference"
-        android:icon="@drawable/ic_screen_zoom"
-        android:summary="@string/screen_zoom_short_summary"
-        android:title="@string/screen_zoom_title"
-        settings:controller="com.android.settings.accessibility.ScreenSizePreferenceController" />
-
-    <Preference
         android:fragment="com.android.settings.accessibility.ToggleScreenMagnificationPreferenceFragmentForSetupWizard"
         android:key="screen_magnification_preference"
         android:icon="@drawable/ic_accessibility_magnification"
diff --git a/res/xml/accessibility_system_controls.xml b/res/xml/accessibility_system_controls.xml
index 71e1143..37c4d67 100644
--- a/res/xml/accessibility_system_controls.xml
+++ b/res/xml/accessibility_system_controls.xml
@@ -42,9 +42,22 @@
         android:title="@string/accessibility_power_button_ends_call_prerefence_title"
         settings:controller="com.android.settings.accessibility.PowerButtonEndsCallPreferenceController"/>
 
+    <!-- Standard auto-rotation preference that will be shown when device state based auto-rotation
+         settings are NOT available. -->
     <SwitchPreference
         android:key="toggle_lock_screen_rotation_preference"
         android:persistent="false"
         android:title="@string/accelerometer_title"
         settings:controller="com.android.settings.accessibility.LockScreenRotationPreferenceController"/>
+
+    <!-- Auto-rotation preference that will be shown when device state based auto-rotation settings
+         are available. -->
+    <Preference
+        android:key="device_state_auto_rotate_accessibility"
+        android:persistent="false"
+        android:title="@string/accelerometer_title"
+        android:fragment="com.android.settings.display.DeviceStateAutoRotateDetailsFragment"
+        settings:keywords="@string/keywords_auto_rotate"
+        settings:controller="com.android.settings.display.DeviceStateAutoRotateOverviewController"/>
+
 </PreferenceScreen>
diff --git a/res/xml/accessibility_text_reading_options.xml b/res/xml/accessibility_text_reading_options.xml
index 4bc9317..d55882d 100644
--- a/res/xml/accessibility_text_reading_options.xml
+++ b/res/xml/accessibility_text_reading_options.xml
@@ -21,16 +21,45 @@
     android:persistent="false"
     android:title="@string/accessibility_text_reading_options_title">
 
+    <com.android.settings.accessibility.TextReadingPreviewPreference
+        android:key="preview"
+        android:selectable="false"/>
+
+    <com.android.settings.widget.LabeledSeekBarPreference
+        android:key="font_size"
+        android:selectable="false"
+        android:summary="@string/short_summary_font_size"
+        android:title="@string/title_font_size"
+        settings:iconEnd="@drawable/ic_add_24dp"
+        settings:iconEndContentDescription="@string/font_size_make_larger_desc"
+        settings:iconStart="@drawable/ic_remove_24dp"
+        settings:iconStartContentDescription="@string/font_size_make_smaller_desc"/>
+
+    <com.android.settings.widget.LabeledSeekBarPreference
+        android:key="display_size"
+        android:selectable="false"
+        android:summary="@string/screen_zoom_short_summary"
+        android:title="@string/screen_zoom_title"
+        settings:iconEnd="@drawable/ic_add_24dp"
+        settings:iconEndContentDescription="@string/screen_zoom_make_larger_desc"
+        settings:iconStart="@drawable/ic_remove_24dp"
+        settings:iconStartContentDescription="@string/screen_zoom_make_smaller_desc"/>
+
     <SwitchPreference
         android:key="toggle_force_bold_text"
         android:persistent="false"
         android:title="@string/force_bold_text"
-        settings:keywords="@string/keywords_bold_text"
-        settings:controller="com.android.settings.accessibility.FontWeightAdjustmentPreferenceController"/>
+        settings:keywords="@string/keywords_bold_text" />
 
     <SwitchPreference
         android:key="toggle_high_text_contrast_preference"
         android:persistent="false"
-        android:title="@string/accessibility_toggle_high_text_contrast_preference_title"
-        settings:controller="com.android.settings.accessibility.HighTextContrastPreferenceController"/>
+        android:summary="@string/accessibility_toggle_high_text_contrast_preference_summary"
+        android:title="@string/accessibility_toggle_high_text_contrast_preference_title" />
+
+    <com.android.settingslib.widget.LayoutPreference
+        android:key="reset"
+        android:layout="@layout/accessibility_text_reading_reset_button"
+        android:persistent="false"
+        android:selectable="false" />
 </PreferenceScreen>
diff --git a/res/xml/app_locale_details.xml b/res/xml/app_locale_details.xml
index 8056cbf..40ca582 100644
--- a/res/xml/app_locale_details.xml
+++ b/res/xml/app_locale_details.xml
@@ -28,7 +28,14 @@
 
     <PreferenceCategory
         android:key="category_key_suggested_languages"
-        android:title="@string/suggested_app_locales_title" />
+        android:title="@string/suggested_app_locales_title" >
+
+        <com.android.settingslib.widget.RadioButtonPreference
+            android:key="system_default_locale"
+            android:title="@string/preference_of_system_locale_title"
+            android:order="-10000"/>
+
+    </PreferenceCategory>
 
     <PreferenceCategory
         android:key="category_key_all_languages"
diff --git a/res/xml/captioning_settings.xml b/res/xml/captioning_settings.xml
index f5059e5..f9e9948 100644
--- a/res/xml/captioning_settings.xml
+++ b/res/xml/captioning_settings.xml
@@ -21,6 +21,11 @@
     android:persistent="false"
     android:title="@string/accessibility_captioning_title">
 
+    <com.android.settingslib.widget.TopIntroPreference
+        android:key="captions_intro"
+        android:persistent="false"
+        android:title="@string/accessibility_caption_preference_intro"/>
+
     <com.android.settingslib.widget.IllustrationPreference
         android:key="captions_preview"
         android:persistent="false"
@@ -38,7 +43,8 @@
         android:fragment="com.android.settings.accessibility.CaptionAppearanceFragment"
         android:key="captioning_caption_appearance"
         android:persistent="false"
-        android:title="@string/captioning_caption_appearance_title" />
+        android:title="@string/captioning_caption_appearance_title"
+        settings:controller="com.android.settings.accessibility.CaptionAppearancePreferenceController" />
 
     <Preference
         android:fragment="com.android.settings.accessibility.CaptionMoreOptionsFragment"
diff --git a/res/xml/device_state_auto_rotate_settings.xml b/res/xml/device_state_auto_rotate_settings.xml
new file mode 100644
index 0000000..2ddb4c7
--- /dev/null
+++ b/res/xml/device_state_auto_rotate_settings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2022 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:title="@string/accelerometer_title" >
+
+    <!-- Device state based auto-rotation preferences will be added programmatically here.  -->
+
+</PreferenceScreen>
diff --git a/res/xml/display_settings.xml b/res/xml/display_settings.xml
index 328e15c..88f8bf1 100644
--- a/res/xml/display_settings.xml
+++ b/res/xml/display_settings.xml
@@ -103,12 +103,27 @@
     <PreferenceCategory
         android:title="@string/category_name_display_controls">
 
+        <!--
+            Standard auto-rotation preference that will be shown when device state based
+            auto-rotation settings are NOT available.
+          -->
         <SwitchPreference
             android:key="auto_rotate"
             android:title="@string/accelerometer_title"
             settings:keywords="@string/keywords_auto_rotate"
             settings:controller="com.android.settings.display.AutoRotatePreferenceController"/>
 
+        <!--
+            Auto-rotation preference that will be shown when device state based auto-rotation
+            settings are available.
+          -->
+        <Preference
+            android:key="device_state_auto_rotate"
+            android:title="@string/accelerometer_title"
+            android:fragment="com.android.settings.display.DeviceStateAutoRotateDetailsFragment"
+            settings:keywords="@string/keywords_auto_rotate"
+            settings:controller="com.android.settings.display.DeviceStateAutoRotateOverviewController"/>
+
         <SwitchPreference
             android:key="display_white_balance"
             android:title="@string/display_white_balance_title"
diff --git a/res/xml/language_and_input.xml b/res/xml/language_and_input.xml
index f2b6d8a..770a862 100644
--- a/res/xml/language_and_input.xml
+++ b/res/xml/language_and_input.xml
@@ -25,7 +25,6 @@
         <Preference
             android:key="phone_language"
             android:title="@string/phone_language"
-            android:icon="@drawable/ic_translate_24dp"
             android:fragment="com.android.settings.localepicker.LocaleListEditor" />
 
         <Preference
@@ -38,8 +37,6 @@
                 android:name="classname"
                 android:value="com.android.settings.applications.appinfo.AppLocaleDetails" />
         </Preference>
-
-
     </PreferenceCategory>
 
     <PreferenceCategory
@@ -50,6 +47,7 @@
             android:title="@string/virtual_keyboard_category"
             android:fragment="com.android.settings.inputmethod.AvailableVirtualKeyboardFragment"
             settings:keywords="@string/keywords_virtual_keyboard"/>
+
         <Preference
             android:key="physical_keyboard_pref"
             android:title="@string/physical_keyboard_title"
@@ -58,6 +56,21 @@
     </PreferenceCategory>
 
     <PreferenceCategory
+        android:key="speech_category"
+        android:title="@string/speech_category_title">
+        <com.android.settings.widget.GearPreference
+            android:key="voice_input_settings"
+            android:title="@string/voice_input_settings_title"
+            android:fragment="com.android.settings.language.DefaultVoiceInputPicker" />
+
+        <Preference
+            android:key="tts_settings_summary"
+            android:title="@string/tts_settings_title"
+            android:fragment="com.android.settings.tts.TextToSpeechSettings"
+            settings:searchable="false"/>
+    </PreferenceCategory>
+
+    <PreferenceCategory
         android:key="input_assistance_category"
         android:title="@string/input_assistance">
         <!-- Spell checker preference title, summary and fragment will be set programmatically. -->
@@ -79,20 +92,12 @@
     </PreferenceCategory>
 
     <PreferenceCategory
-        android:key="pointer_and_tts_category"
+        android:key="pointer_category"
         android:layout="@layout/preference_category_no_label">
-
         <com.android.settings.PointerSpeedPreference
             android:key="pointer_speed"
             android:title="@string/pointer_speed"
             android:dialogTitle="@string/pointer_speed" />
-
-        <Preference
-            android:key="tts_settings_summary"
-            android:title="@string/tts_settings_title"
-            android:fragment="com.android.settings.tts.TextToSpeechSettings"
-            settings:searchable="false"/>
-
     </PreferenceCategory>
 
     <SwitchPreference
diff --git a/res/xml/manage_assist.xml b/res/xml/manage_assist.xml
index 59ba2f5..c8dbe42 100644
--- a/res/xml/manage_assist.xml
+++ b/res/xml/manage_assist.xml
@@ -49,11 +49,6 @@
         android:title="@string/assist_flash_title"
         android:summary="@string/assist_flash_summary" />
 
-    <com.android.settings.widget.GearPreference
-        android:key="voice_input_settings"
-        android:title="@string/voice_input_settings_title"
-        android:fragment="com.android.settings.applications.assist.DefaultVoiceInputPicker" />
-
     <com.android.settingslib.widget.FooterPreference
         android:key="manage_assist_footer"
         android:title="@string/assist_footer"
diff --git a/src/com/android/settings/RestrictedListPreference.java b/src/com/android/settings/RestrictedListPreference.java
index bd3cd17..d75f1b8 100644
--- a/src/com/android/settings/RestrictedListPreference.java
+++ b/src/com/android/settings/RestrictedListPreference.java
@@ -30,7 +30,6 @@
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
 import android.widget.CheckedTextView;
-import android.widget.ImageView;
 import android.widget.ListAdapter;
 import android.widget.ListView;
 
@@ -53,7 +52,6 @@
 
     public RestrictedListPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
-        setWidgetLayoutResource(R.layout.restricted_icon);
         mHelper = new RestrictedPreferenceHelper(context, this, attrs);
     }
 
@@ -67,10 +65,6 @@
     public void onBindViewHolder(PreferenceViewHolder holder) {
         super.onBindViewHolder(holder);
         mHelper.onBindViewHolder(holder);
-        final View restrictedIcon = holder.findViewById(R.id.restricted_icon);
-        if (restrictedIcon != null) {
-            restrictedIcon.setVisibility(isDisabledByAdmin() ? View.VISIBLE : View.GONE);
-        }
     }
 
     @Override
@@ -187,11 +181,9 @@
             View root = super.getView(position, convertView, parent);
             CharSequence entry = getItem(position);
             CheckedTextView text = (CheckedTextView) root.findViewById(R.id.text1);
-            ImageView padlock = (ImageView) root.findViewById(R.id.restricted_lock_icon);
             if (isRestrictedForEntry(entry)) {
                 text.setEnabled(false);
                 text.setChecked(false);
-                padlock.setVisibility(View.VISIBLE);
             } else {
                 if (mSelectedIndex != -1) {
                     text.setChecked(position == mSelectedIndex);
@@ -199,7 +191,6 @@
                 if (!text.isEnabled()) {
                     text.setEnabled(true);
                 }
-                padlock.setVisibility(View.GONE);
             }
             return root;
         }
diff --git a/src/com/android/settings/accessibility/AccessibilityButtonFooterPreferenceController.java b/src/com/android/settings/accessibility/AccessibilityButtonFooterPreferenceController.java
index 55b8019..ca9c3d8 100644
--- a/src/com/android/settings/accessibility/AccessibilityButtonFooterPreferenceController.java
+++ b/src/com/android/settings/accessibility/AccessibilityButtonFooterPreferenceController.java
@@ -50,9 +50,10 @@
         final int titleResource = AccessibilityUtil.isGestureNavigateEnabled(mContext)
                 ? R.string.accessibility_button_gesture_description
                 : R.string.accessibility_button_description;
+        final CharSequence footerText = mContext.getText(titleResource);
         final AccessibilityFooterPreference footerPreference =
                 screen.findPreference(getPreferenceKey());
-        footerPreference.setTitle(titleResource);
+        footerPreference.setTitle(footerText);
         super.displayPreference(screen);
     }
 }
diff --git a/src/com/android/settings/accessibility/AccessibilityDetailsSettingsFragment.java b/src/com/android/settings/accessibility/AccessibilityDetailsSettingsFragment.java
index 5fc4cd2..2cdbb33 100644
--- a/src/com/android/settings/accessibility/AccessibilityDetailsSettingsFragment.java
+++ b/src/com/android/settings/accessibility/AccessibilityDetailsSettingsFragment.java
@@ -234,6 +234,9 @@
         final String htmlDescription = info.loadHtmlDescription(getActivity().getPackageManager());
         extras.putString(AccessibilitySettings.EXTRA_HTML_DESCRIPTION, htmlDescription);
 
+        final CharSequence intro = info.loadIntro(getActivity().getPackageManager());
+        extras.putCharSequence(AccessibilitySettings.EXTRA_INTRO, intro);
+
         // We will log nonA11yTool status from PolicyWarningUIController; others none.
         extras.putLong(AccessibilitySettings.EXTRA_TIME_FOR_LOGGING,
                 getActivity().getIntent().getLongExtra(
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index e834640..6539f32 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -94,6 +94,7 @@
     static final String EXTRA_TITLE_RES = "title_res";
     static final String EXTRA_RESOLVE_INFO = "resolve_info";
     static final String EXTRA_SUMMARY = "summary";
+    static final String EXTRA_INTRO = "intro";
     static final String EXTRA_SETTINGS_TITLE = "settings_title";
     static final String EXTRA_COMPONENT_NAME = "component_name";
     static final String EXTRA_SETTINGS_COMPONENT_NAME = "settings_component_name";
@@ -570,14 +571,15 @@
 
                 final String prefKey = preference.getKey();
                 final int imageRes = info.getAnimatedImageRes();
+                final CharSequence intro = info.loadIntro(mPm);
                 final CharSequence description = getServiceDescription(mContext, info,
                         serviceEnabled);
                 final String htmlDescription = info.loadHtmlDescription(mPm);
                 final String settingsClassName = info.getSettingsActivityName();
                 final String tileServiceClassName = info.getTileServiceClassName();
 
-                putBasicExtras(preference, prefKey, title, description, imageRes, htmlDescription,
-                        componentName);
+                putBasicExtras(preference, prefKey, title, intro, description, imageRes,
+                        htmlDescription, componentName);
                 putServiceExtras(preference, resolveInfo, serviceEnabled);
                 putSettingsExtras(preference, packageName, settingsClassName);
                 putTileServiceExtras(preference, packageName, tileServiceClassName);
@@ -630,14 +632,15 @@
                 setRestrictedPreferenceEnabled(preference, permittedServices, serviceEnabled);
 
                 final String prefKey = preference.getKey();
+                final CharSequence intro = info.loadIntro(mPm);
                 final String description = info.loadDescription(mPm);
                 final int imageRes = info.getAnimatedImageRes();
                 final String htmlDescription = info.loadHtmlDescription(mPm);
                 final String settingsClassName = info.getSettingsActivityName();
                 final String tileServiceClassName = info.getTileServiceClassName();
 
-                putBasicExtras(preference, prefKey, title, description, imageRes, htmlDescription,
-                        componentName);
+                putBasicExtras(preference, prefKey, title, intro, description, imageRes,
+                        htmlDescription, componentName);
                 putSettingsExtras(preference, componentName.getPackageName(), settingsClassName);
                 putTileServiceExtras(preference, componentName.getPackageName(),
                         tileServiceClassName);
@@ -722,11 +725,12 @@
 
         /** Puts the basic extras into {@link RestrictedPreference}'s getExtras(). */
         private void putBasicExtras(RestrictedPreference preference, String prefKey,
-                CharSequence title, CharSequence summary, int imageRes, String htmlDescription,
-                ComponentName componentName) {
+                CharSequence title, CharSequence intro, CharSequence summary, int imageRes,
+                String htmlDescription, ComponentName componentName) {
             final Bundle extras = preference.getExtras();
             extras.putString(EXTRA_PREFERENCE_KEY, prefKey);
             extras.putCharSequence(EXTRA_TITLE, title);
+            extras.putCharSequence(EXTRA_INTRO, intro);
             extras.putCharSequence(EXTRA_SUMMARY, summary);
             extras.putParcelable(EXTRA_COMPONENT_NAME, componentName);
             extras.putInt(EXTRA_ANIMATED_IMAGE_RES, imageRes);
diff --git a/src/com/android/settings/accessibility/AudioDescriptionPreferenceController.java b/src/com/android/settings/accessibility/AudioDescriptionPreferenceController.java
new file mode 100644
index 0000000..a05a0d0
--- /dev/null
+++ b/src/com/android/settings/accessibility/AudioDescriptionPreferenceController.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 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.accessibility;
+
+import static android.provider.Settings.Secure.ENABLED_ACCESSIBILITY_AUDIO_DESCRIPTION_BY_DEFAULT;
+
+import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
+import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
+
+import android.content.Context;
+import android.os.UserHandle;
+import android.provider.Settings;
+
+import com.android.settings.R;
+import com.android.settings.core.TogglePreferenceController;
+
+/**
+ * A toggle preference controller for audio description
+ */
+public class AudioDescriptionPreferenceController extends TogglePreferenceController {
+
+    static final String PREF_KEY = "toggle_audio_description";
+
+    public AudioDescriptionPreferenceController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+    }
+
+    @Override
+    public boolean isChecked() {
+        return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                ENABLED_ACCESSIBILITY_AUDIO_DESCRIPTION_BY_DEFAULT,
+                OFF /* default */,
+                UserHandle.USER_CURRENT) == ON;
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        return Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                ENABLED_ACCESSIBILITY_AUDIO_DESCRIPTION_BY_DEFAULT,
+                isChecked ? ON : OFF,
+                UserHandle.USER_CURRENT);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+
+    @Override
+    public int getSliceHighlightMenuRes() {
+        return R.string.menu_key_accessibility;
+    }
+}
diff --git a/src/com/android/settings/accessibility/CaptionAppearancePreferenceController.java b/src/com/android/settings/accessibility/CaptionAppearancePreferenceController.java
new file mode 100644
index 0000000..4bcdceb
--- /dev/null
+++ b/src/com/android/settings/accessibility/CaptionAppearancePreferenceController.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2022 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.accessibility;
+
+import android.content.Context;
+import android.view.accessibility.CaptioningManager;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+
+import com.google.common.primitives.Floats;
+import com.google.common.primitives.Ints;
+
+/** Controller that shows the caption scale and style summary. */
+public class CaptionAppearancePreferenceController extends BasePreferenceController {
+
+    private final CaptioningManager mCaptioningManager;
+
+    public CaptionAppearancePreferenceController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+        mCaptioningManager = context.getSystemService(CaptioningManager.class);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+
+    @Override
+    public CharSequence getSummary() {
+        return mContext.getString(R.string.preference_summary_default_combination,
+                geFontScaleSummary(), getPresetSummary());
+    }
+
+    private float[] getFontScaleValuesArray() {
+        final String[] fontScaleValuesStrArray = mContext.getResources().getStringArray(
+                R.array.captioning_font_size_selector_values);
+        final int length = fontScaleValuesStrArray.length;
+        final float[] fontScaleValuesArray = new float[length];
+        for (int i = 0; i < length; ++i) {
+            fontScaleValuesArray[i] = Float.parseFloat(fontScaleValuesStrArray[i]);
+        }
+        return fontScaleValuesArray;
+    }
+
+    private CharSequence geFontScaleSummary() {
+        final float[] fontScaleValuesArray = getFontScaleValuesArray();
+        final String[] fontScaleSummaries = mContext.getResources().getStringArray(
+                R.array.captioning_font_size_selector_titles);
+        final float fontScale = mCaptioningManager.getFontScale();
+        final int idx = Floats.indexOf(fontScaleValuesArray, fontScale);
+        return fontScaleSummaries[idx == /* not exist */ -1 ? 0 : idx];
+    }
+
+    private CharSequence getPresetSummary() {
+        final int[] presetValuesArray = mContext.getResources().getIntArray(
+                R.array.captioning_preset_selector_values);
+        final String[] presetSummaries = mContext.getResources().getStringArray(
+                R.array.captioning_preset_selector_titles);
+        final int preset = mCaptioningManager.getRawUserStyle();
+        final int idx = Ints.indexOf(presetValuesArray, preset);
+        return presetSummaries[idx];
+    }
+}
diff --git a/src/com/android/settings/accessibility/CaptionPropertiesFragment.java b/src/com/android/settings/accessibility/CaptionPropertiesFragment.java
index bcdba11..2d4bb11 100644
--- a/src/com/android/settings/accessibility/CaptionPropertiesFragment.java
+++ b/src/com/android/settings/accessibility/CaptionPropertiesFragment.java
@@ -34,8 +34,6 @@
 import com.android.settingslib.search.SearchIndexable;
 import com.android.settingslib.widget.OnMainSwitchChangeListener;
 
-import com.google.common.primitives.Floats;
-
 import java.util.ArrayList;
 import java.util.List;
 
@@ -56,7 +54,6 @@
     private Preference mMoreOptions;
 
     private final List<Preference> mPreferenceList = new ArrayList<>();
-    private float[] mFontSizeValuesArray;
 
     @Override
     public int getMetricsCategory() {
@@ -71,13 +68,12 @@
 
         initializeAllPreferences();
         installUpdateListeners();
-        initFontSizeValuesArray();
     }
 
     @Override
     public void onResume() {
         super.onResume();
-        updateAllPreferences();
+        mSwitch.setChecked(mCaptioningManager.isEnabled());
     }
 
     @Override
@@ -105,21 +101,6 @@
 
     }
 
-    private void initFontSizeValuesArray() {
-        final String[] fontSizeValuesStrArray = getPrefContext().getResources().getStringArray(
-                R.array.captioning_font_size_selector_values);
-        final int length = fontSizeValuesStrArray.length;
-        mFontSizeValuesArray = new float[length];
-        for (int i = 0; i < length; ++i) {
-            mFontSizeValuesArray[i] = Float.parseFloat(fontSizeValuesStrArray[i]);
-        }
-    }
-
-    private void updateAllPreferences() {
-        mSwitch.setChecked(mCaptioningManager.isEnabled());
-        mTextAppearance.setSummary(geTextAppearanceSummary(getPrefContext()));
-    }
-
     @Override
     public boolean onPreferenceChange(Preference preference, Object value) {
         final ContentResolver cr = getActivity().getContentResolver();
@@ -136,16 +117,6 @@
         return R.string.help_url_caption;
     }
 
-    private CharSequence geTextAppearanceSummary(Context context) {
-        final String[] fontSizeSummaries = context.getResources().getStringArray(
-                R.array.captioning_font_size_selector_summaries);
-
-        final float fontSize = mCaptioningManager.getFontScale();
-        final int idx = Floats.indexOf(mFontSizeValuesArray, fontSize);
-
-        return fontSizeSummaries[idx == /* not exist */ -1 ? 0 : idx];
-    }
-
     public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.captioning_settings);
 
diff --git a/src/com/android/settings/accessibility/TextAndDisplayFragment.java b/src/com/android/settings/accessibility/ColorAndMotionFragment.java
similarity index 91%
rename from src/com/android/settings/accessibility/TextAndDisplayFragment.java
rename to src/com/android/settings/accessibility/ColorAndMotionFragment.java
index e81dded..7f55053 100644
--- a/src/com/android/settings/accessibility/TextAndDisplayFragment.java
+++ b/src/com/android/settings/accessibility/ColorAndMotionFragment.java
@@ -30,11 +30,11 @@
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.search.SearchIndexable;
 
-/** Accessibility settings for text and display. */
+/** Accessibility settings for color and motion. */
 @SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
-public class TextAndDisplayFragment extends DashboardFragment {
+public class ColorAndMotionFragment extends DashboardFragment {
 
-    private static final String TAG = "TextAndDisplayFragment";
+    private static final String TAG = "ColorAndMotionFragment";
 
     private static final String CATEGORY_EXPERIMENTAL = "experimental_category";
 
@@ -49,7 +49,7 @@
 
     @Override
     public int getMetricsCategory() {
-        return SettingsEnums.ACCESSIBILITY_TEXT_AND_DISPLAY;
+        return SettingsEnums.ACCESSIBILITY_COLOR_AND_MOTION;
     }
 
 
@@ -62,7 +62,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.accessibility_text_and_display;
+        return R.xml.accessibility_color_and_motion;
     }
 
     @Override
@@ -104,5 +104,5 @@
     }
 
     public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider(R.xml.accessibility_text_and_display);
+            new BaseSearchIndexProvider(R.xml.accessibility_color_and_motion);
 }
diff --git a/src/com/android/settings/accessibility/DisplaySizeData.java b/src/com/android/settings/accessibility/DisplaySizeData.java
new file mode 100644
index 0000000..42a8c46
--- /dev/null
+++ b/src/com/android/settings/accessibility/DisplaySizeData.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 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.accessibility;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.view.Display;
+
+import com.android.settingslib.display.DisplayDensityConfiguration;
+import com.android.settingslib.display.DisplayDensityUtils;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.stream.Collectors;
+
+/**
+ * Data class for storing the configurations related to the display size.
+ */
+class DisplaySizeData extends PreviewSizeData<Integer> {
+    DisplaySizeData(Context context) {
+        super(context);
+
+        final DisplayDensityUtils density = new DisplayDensityUtils(getContext());
+        final int initialIndex = density.getCurrentIndex();
+        if (initialIndex < 0) {
+            // Failed to obtain default density, which means we failed to
+            // connect to the window manager service. Just use the current
+            // density and don't let the user change anything.
+            final Resources resources = getContext().getResources();
+            final int densityDpi = resources.getDisplayMetrics().densityDpi;
+            setDefaultValue(densityDpi);
+            setInitialIndex(0);
+            setValues(Collections.singletonList(densityDpi));
+        } else {
+            setDefaultValue(density.getDefaultDensity());
+            setInitialIndex(initialIndex);
+            setValues(Arrays.stream(density.getValues()).boxed().collect(Collectors.toList()));
+        }
+    }
+
+    @Override
+    void commit(int currentProgress) {
+        final int densityDpi = getValues().get(currentProgress);
+        if (densityDpi == getDefaultValue()) {
+            DisplayDensityConfiguration.clearForcedDisplayDensity(Display.DEFAULT_DISPLAY);
+        } else {
+            DisplayDensityConfiguration.setForcedDisplayDensity(Display.DEFAULT_DISPLAY,
+                    densityDpi);
+        }
+    }
+}
diff --git a/src/com/android/settings/accessibility/FontSizeData.java b/src/com/android/settings/accessibility/FontSizeData.java
new file mode 100644
index 0000000..1d4f6bd
--- /dev/null
+++ b/src/com/android/settings/accessibility/FontSizeData.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 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.accessibility;
+
+import static com.android.settings.display.ToggleFontSizePreferenceFragment.fontSizeValueToIndex;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.Resources;
+import android.provider.Settings;
+
+import com.android.settings.R;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Data class for storing the configurations related to the font size.
+ */
+final class FontSizeData extends PreviewSizeData<Float> {
+    private static final float FONT_SCALE_DEF_VALUE = 1.0f;
+
+    FontSizeData(Context context) {
+        super(context);
+
+        final Resources resources = getContext().getResources();
+        final ContentResolver resolver = getContext().getContentResolver();
+        final List<String> strEntryValues =
+                Arrays.asList(resources.getStringArray(R.array.entryvalues_font_size));
+        setDefaultValue(FONT_SCALE_DEF_VALUE);
+        final float currentScale =
+                Settings.System.getFloat(resolver, Settings.System.FONT_SCALE, getDefaultValue());
+        setInitialIndex(fontSizeValueToIndex(currentScale, strEntryValues.toArray(new String[0])));
+        setValues(strEntryValues.stream().map(Float::valueOf).collect(Collectors.toList()));
+    }
+
+    @Override
+    void commit(int currentProgress) {
+        final ContentResolver resolver = getContext().getContentResolver();
+        Settings.System.putFloat(resolver, Settings.System.FONT_SCALE,
+                getValues().get(currentProgress));
+    }
+}
diff --git a/src/com/android/settings/accessibility/FontWeightAdjustmentPreferenceController.java b/src/com/android/settings/accessibility/FontWeightAdjustmentPreferenceController.java
index b59b3b2..e3c1b9e 100644
--- a/src/com/android/settings/accessibility/FontWeightAdjustmentPreferenceController.java
+++ b/src/com/android/settings/accessibility/FontWeightAdjustmentPreferenceController.java
@@ -24,7 +24,8 @@
 import com.android.settings.core.TogglePreferenceController;
 
 /** PreferenceController for displaying all text in bold. */
-public class FontWeightAdjustmentPreferenceController extends TogglePreferenceController {
+public class FontWeightAdjustmentPreferenceController extends TogglePreferenceController implements
+        TextReadingResetController.ResetStateListener {
     static final int BOLD_TEXT_ADJUSTMENT =
             FontStyle.FONT_WEIGHT_BOLD - FontStyle.FONT_WEIGHT_NORMAL;
 
@@ -53,4 +54,9 @@
     public int getSliceHighlightMenuRes() {
         return R.string.menu_key_accessibility;
     }
+
+    @Override
+    public void resetState() {
+        setChecked(false);
+    }
 }
diff --git a/src/com/android/settings/accessibility/HighTextContrastPreferenceController.java b/src/com/android/settings/accessibility/HighTextContrastPreferenceController.java
index e98a28c..aad69b9 100644
--- a/src/com/android/settings/accessibility/HighTextContrastPreferenceController.java
+++ b/src/com/android/settings/accessibility/HighTextContrastPreferenceController.java
@@ -22,7 +22,11 @@
 import com.android.settings.R;
 import com.android.settings.core.TogglePreferenceController;
 
-public class HighTextContrastPreferenceController extends TogglePreferenceController {
+/**
+ * PreferenceController for displaying all text in high contrast style.
+ */
+public class HighTextContrastPreferenceController extends TogglePreferenceController implements
+        TextReadingResetController.ResetStateListener {
 
     public HighTextContrastPreferenceController(Context context, String preferenceKey) {
         super(context, preferenceKey);
@@ -49,4 +53,9 @@
     public int getSliceHighlightMenuRes() {
         return R.string.menu_key_accessibility;
     }
+
+    @Override
+    public void resetState() {
+        setChecked(false);
+    }
 }
diff --git a/src/com/android/settings/accessibility/LockScreenRotationPreferenceController.java b/src/com/android/settings/accessibility/LockScreenRotationPreferenceController.java
index 5ed4b5c..a1c292a 100644
--- a/src/com/android/settings/accessibility/LockScreenRotationPreferenceController.java
+++ b/src/com/android/settings/accessibility/LockScreenRotationPreferenceController.java
@@ -25,6 +25,7 @@
 import com.android.internal.view.RotationPolicy.RotationPolicyListener;
 import com.android.settings.R;
 import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.display.DeviceStateAutoRotationHelper;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnStart;
 import com.android.settingslib.core.lifecycle.events.OnStop;
@@ -59,7 +60,9 @@
 
     @Override
     public int getAvailabilityStatus() {
-        return RotationPolicy.isRotationSupported(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+        return RotationPolicy.isRotationSupported(mContext)
+                && !DeviceStateAutoRotationHelper.isDeviceStateRotationEnabledForA11y(mContext)
+                ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
     }
 
     @Override
diff --git a/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java b/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java
index 37d09a7..01ee249 100644
--- a/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java
+++ b/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java
@@ -100,7 +100,10 @@
         extras.putInt(AccessibilitySettings.EXTRA_TITLE_RES,
                 R.string.accessibility_screen_magnification_gestures_title);
 
-        String summary =  context.getString(R.string.accessibility_screen_magnification_summary);
+        String intro = context.getString(R.string.accessibility_screen_magnification_intro_text);
+        extras.putCharSequence(AccessibilitySettings.EXTRA_INTRO, intro);
+
+        String summary = context.getString(R.string.accessibility_screen_magnification_summary);
         final Object[] numberArguments = {1, 2, 3, 4, 5};
         summary = MessageFormat.format(summary, numberArguments);
         extras.putCharSequence(AccessibilitySettings.EXTRA_HTML_DESCRIPTION, summary);
diff --git a/src/com/android/settings/accessibility/PreviewSizeData.java b/src/com/android/settings/accessibility/PreviewSizeData.java
new file mode 100644
index 0000000..5d4204e
--- /dev/null
+++ b/src/com/android/settings/accessibility/PreviewSizeData.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2022 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.accessibility;
+
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+
+import java.util.List;
+
+/**
+ * Abstract data class for storing and fetching the configurations related to the preview of the
+ * text and reading options.
+ */
+abstract class PreviewSizeData<T extends Number> {
+    private final Context mContext;
+    private int mInitialIndex;
+    private T mDefaultValue;
+    private List<T> mValues;
+
+    PreviewSizeData(@NonNull Context context) {
+        mContext = context;
+    }
+
+    Context getContext() {
+        return mContext;
+    }
+
+    List<T> getValues() {
+        return mValues;
+    }
+
+    void setValues(List<T> values) {
+        mValues = values;
+    }
+
+    T getDefaultValue() {
+        return mDefaultValue;
+    }
+
+    void setDefaultValue(T defaultValue) {
+        mDefaultValue = defaultValue;
+    }
+
+    int getInitialIndex() {
+        return mInitialIndex;
+    }
+
+    void setInitialIndex(int initialIndex) {
+        mInitialIndex = initialIndex;
+    }
+
+    /**
+     * Persists the selected size.
+     */
+    abstract void commit(int currentProgress);
+}
diff --git a/src/com/android/settings/accessibility/PreviewSizeSeekBarController.java b/src/com/android/settings/accessibility/PreviewSizeSeekBarController.java
new file mode 100644
index 0000000..c7dfd61
--- /dev/null
+++ b/src/com/android/settings/accessibility/PreviewSizeSeekBarController.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2022 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.accessibility;
+
+import android.content.Context;
+import android.widget.SeekBar;
+
+import androidx.annotation.NonNull;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.widget.LabeledSeekBarPreference;
+
+/**
+ * The controller of {@link LabeledSeekBarPreference} that listens to display size and font size
+ * settings changes and updates preview size threshold smoothly.
+ */
+class PreviewSizeSeekBarController extends BasePreferenceController implements
+        TextReadingResetController.ResetStateListener {
+    private final PreviewSizeData<? extends Number> mSizeData;
+    private boolean mSeekByTouch;
+    private ProgressInteractionListener mInteractionListener;
+    private LabeledSeekBarPreference mSeekBarPreference;
+
+    private final SeekBar.OnSeekBarChangeListener mSeekBarChangeListener =
+            new SeekBar.OnSeekBarChangeListener() {
+                @Override
+                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+                    mInteractionListener.notifyPreferenceChanged();
+
+                    if (!mSeekByTouch && mInteractionListener != null) {
+                        mInteractionListener.onProgressChanged();
+                    }
+                }
+
+                @Override
+                public void onStartTrackingTouch(SeekBar seekBar) {
+                    mSeekByTouch = true;
+                }
+
+                @Override
+                public void onStopTrackingTouch(SeekBar seekBar) {
+                    mSeekByTouch = false;
+
+                    if (mInteractionListener != null) {
+                        mInteractionListener.onEndTrackingTouch();
+                    }
+                }
+            };
+
+    PreviewSizeSeekBarController(Context context, String preferenceKey,
+            @NonNull PreviewSizeData<? extends Number> sizeData) {
+        super(context, preferenceKey);
+        mSizeData = sizeData;
+    }
+
+    void setInteractionListener(ProgressInteractionListener interactionListener) {
+        mInteractionListener = interactionListener;
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+
+        final int dataSize = mSizeData.getValues().size();
+        final int initialIndex = mSizeData.getInitialIndex();
+        mSeekBarPreference = screen.findPreference(getPreferenceKey());
+        mSeekBarPreference.setMax(dataSize - 1);
+        mSeekBarPreference.setProgress(initialIndex);
+        mSeekBarPreference.setContinuousUpdates(true);
+        mSeekBarPreference.setOnSeekBarChangeListener(mSeekBarChangeListener);
+    }
+
+    @Override
+    public void resetState() {
+        final int defaultProgress = mSizeData.getValues().indexOf(mSizeData.getDefaultValue());
+        mSeekBarPreference.setProgress(defaultProgress);
+    }
+
+    /**
+     * Interface for callbacks when users interact with the seek bar.
+     */
+    interface ProgressInteractionListener {
+
+        /**
+         * Called when the progress is changed.
+         */
+        void notifyPreferenceChanged();
+
+        /**
+         * Called when the progress is changed without tracking touch.
+         */
+        void onProgressChanged();
+
+        /**
+         * Called when the seek bar is end tracking.
+         */
+        void onEndTrackingTouch();
+    }
+}
diff --git a/src/com/android/settings/accessibility/TextReadingPreferenceFragment.java b/src/com/android/settings/accessibility/TextReadingPreferenceFragment.java
index 0e8457b..7dd70af 100644
--- a/src/com/android/settings/accessibility/TextReadingPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/TextReadingPreferenceFragment.java
@@ -16,13 +16,21 @@
 
 package com.android.settings.accessibility;
 
+import static com.android.settings.accessibility.TextReadingResetController.ResetStateListener;
+
 import android.app.settings.SettingsEnums;
+import android.content.Context;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.search.SearchIndexable;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
 /**
  * Accessibility settings for adjusting the system features which are related to the reading. For
  * example, bold text, high contrast text, display size, font size and so on.
@@ -30,6 +38,12 @@
 @SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
 public class TextReadingPreferenceFragment extends DashboardFragment {
     private static final String TAG = "TextReadingPreferenceFragment";
+    private static final String FONT_SIZE_KEY = "font_size";
+    private static final String DISPLAY_SIZE_KEY = "display_size";
+    private static final String PREVIEW_KEY = "preview";
+    private static final String RESET_KEY = "reset";
+    private static final String BOLD_TEXT_KEY = "toggle_force_bold_text";
+    private static final String HIGHT_TEXT_CONTRAST_KEY = "toggle_high_text_contrast_preference";
 
     @Override
     protected int getPreferenceScreenResId() {
@@ -46,6 +60,44 @@
         return SettingsEnums.ACCESSIBILITY_TEXT_READING_OPTIONS;
     }
 
+    @Override
+    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+        final List<AbstractPreferenceController> controllers = new ArrayList<>();
+        final FontSizeData fontSizeData = new FontSizeData(context);
+        final DisplaySizeData displaySizeData = new DisplaySizeData(context);
+
+        final TextReadingPreviewController previewController = new TextReadingPreviewController(
+                context, PREVIEW_KEY, fontSizeData, displaySizeData);
+        controllers.add(previewController);
+
+        final PreviewSizeSeekBarController fontSizeController = new PreviewSizeSeekBarController(
+                context, FONT_SIZE_KEY, fontSizeData);
+        fontSizeController.setInteractionListener(previewController);
+        controllers.add(fontSizeController);
+
+        final PreviewSizeSeekBarController displaySizeController = new PreviewSizeSeekBarController(
+                context, DISPLAY_SIZE_KEY, displaySizeData);
+        displaySizeController.setInteractionListener(previewController);
+        controllers.add(displaySizeController);
+
+        final FontWeightAdjustmentPreferenceController fontWeightController =
+                new FontWeightAdjustmentPreferenceController(context, BOLD_TEXT_KEY);
+        controllers.add(fontWeightController);
+
+        final HighTextContrastPreferenceController highTextContrastController =
+                new HighTextContrastPreferenceController(context, HIGHT_TEXT_CONTRAST_KEY);
+        controllers.add(highTextContrastController);
+
+        final List<ResetStateListener> resetStateListeners =
+                controllers.stream().filter(c -> c instanceof ResetStateListener).map(
+                        c -> (ResetStateListener) c).collect(Collectors.toList());
+        final TextReadingResetController resetController =
+                new TextReadingResetController(context, RESET_KEY, resetStateListeners);
+        controllers.add(resetController);
+
+        return controllers;
+    }
+
     public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.accessibility_text_reading_options);
 }
diff --git a/src/com/android/settings/accessibility/TextReadingPreviewController.java b/src/com/android/settings/accessibility/TextReadingPreviewController.java
new file mode 100644
index 0000000..cef20aa
--- /dev/null
+++ b/src/com/android/settings/accessibility/TextReadingPreviewController.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2022 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.accessibility;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.os.SystemClock;
+import android.view.Choreographer;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.display.PreviewPagerAdapter;
+import com.android.settings.widget.LabeledSeekBarPreference;
+
+import java.util.Objects;
+
+/**
+ * A {@link BasePreferenceController} for controlling the preview pager of the text and reading
+ * options.
+ */
+class TextReadingPreviewController extends BasePreferenceController implements
+        PreviewSizeSeekBarController.ProgressInteractionListener {
+    static final int[] PREVIEW_SAMPLE_RES_IDS = new int[]{
+            R.layout.accessibility_text_reading_preview_app_grid,
+            R.layout.screen_zoom_preview_1,
+            R.layout.accessibility_text_reading_preview_mail_content};
+
+    private static final String PREVIEW_KEY = "preview";
+    private static final String FONT_SIZE_KEY = "font_size";
+    private static final String DISPLAY_SIZE_KEY = "display_size";
+    private static final long MIN_COMMIT_INTERVAL_MS = 800;
+    private static final long CHANGE_BY_SEEKBAR_DELAY_MS = 100;
+    private static final long CHANGE_BY_BUTTON_DELAY_MS = 300;
+    private final FontSizeData mFontSizeData;
+    private final DisplaySizeData mDisplaySizeData;
+    private int mLastFontProgress;
+    private int mLastDisplayProgress;
+    private long mLastCommitTime;
+    private TextReadingPreviewPreference mPreviewPreference;
+    private LabeledSeekBarPreference mFontSizePreference;
+    private LabeledSeekBarPreference mDisplaySizePreference;
+
+    private final Choreographer.FrameCallback mCommit = f -> {
+        tryCommitFontSizeConfig();
+        tryCommitDisplaySizeConfig();
+
+        mLastCommitTime = SystemClock.elapsedRealtime();
+    };
+
+    TextReadingPreviewController(Context context, String preferenceKey,
+            @NonNull FontSizeData fontSizeData, @NonNull DisplaySizeData displaySizeData) {
+        super(context, preferenceKey);
+        mFontSizeData = fontSizeData;
+        mDisplaySizeData = displaySizeData;
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+
+        mPreviewPreference = screen.findPreference(PREVIEW_KEY);
+
+        mFontSizePreference = screen.findPreference(FONT_SIZE_KEY);
+        mDisplaySizePreference = screen.findPreference(DISPLAY_SIZE_KEY);
+        Objects.requireNonNull(mFontSizePreference,
+                /* message= */ "Font size preference is null, the preview controller "
+                        + "couldn't get the info");
+        Objects.requireNonNull(mDisplaySizePreference,
+                /* message= */ "Display size preference is null, the preview controller"
+                        + " couldn't get the info");
+
+        mLastFontProgress = mFontSizePreference.getProgress();
+        mLastDisplayProgress = mDisplaySizePreference.getProgress();
+
+        final Configuration origConfig = mContext.getResources().getConfiguration();
+        final boolean isLayoutRtl =
+                origConfig.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+        final PreviewPagerAdapter pagerAdapter = new PreviewPagerAdapter(mContext, isLayoutRtl,
+                PREVIEW_SAMPLE_RES_IDS, createConfig(origConfig));
+        mPreviewPreference.setPreviewAdapter(pagerAdapter);
+        pagerAdapter.setPreviewLayer(/* newLayerIndex= */ 0,
+                /* currentLayerIndex= */ 0,
+                /* currentFrameIndex= */ 0, /* animate= */ false);
+    }
+
+    @Override
+    public void notifyPreferenceChanged() {
+        final int displayDataSize = mDisplaySizeData.getValues().size();
+        final int fontSizeProgress = mFontSizePreference.getProgress();
+        final int displaySizeProgress = mDisplaySizePreference.getProgress();
+
+        // To be consistent with the
+        // {@link PreviewPagerAdapter#setPreviewLayer(int, int, int, boolean)} behavior,
+        // here also needs the same design. In addition, please also refer to
+        // the {@link #createConfig(Configuration)}.
+        final int pagerIndex = fontSizeProgress * displayDataSize + displaySizeProgress;
+
+        mPreviewPreference.notifyPreviewPagerChanged(pagerIndex);
+    }
+
+    @Override
+    public void onProgressChanged() {
+        postCommitDelayed(CHANGE_BY_BUTTON_DELAY_MS);
+    }
+
+    @Override
+    public void onEndTrackingTouch() {
+        postCommitDelayed(CHANGE_BY_SEEKBAR_DELAY_MS);
+    }
+
+    /**
+     * Avoids the flicker when switching to the previous or next level.
+     *
+     * <p><br>[Flickering problem steps] commit()-> snapshot in framework(old screenshot) ->
+     * app update the preview -> snapshot(old screen) fade out</p>
+     *
+     * <p><br>To prevent flickering problem, we make sure that we update the local preview
+     * first and then we do the commit later. </p>
+     *
+     * <p><br><b>Note:</b> It doesn't matter that we use
+     * Choreographer or main thread handler since the delay time is longer
+     * than 1 frame. Use Choreographer to let developer understand it's a
+     * window update.</p>
+     *
+     * @param commitDelayMs the interval time after a action.
+     */
+    void postCommitDelayed(long commitDelayMs) {
+        if (SystemClock.elapsedRealtime() - mLastCommitTime < MIN_COMMIT_INTERVAL_MS) {
+            commitDelayMs += MIN_COMMIT_INTERVAL_MS;
+        }
+
+        final Choreographer choreographer = Choreographer.getInstance();
+        choreographer.removeFrameCallback(mCommit);
+        choreographer.postFrameCallbackDelayed(mCommit, commitDelayMs);
+    }
+
+    private void tryCommitFontSizeConfig() {
+        final int fontProgress = mFontSizePreference.getProgress();
+        if (fontProgress != mLastFontProgress) {
+            mFontSizeData.commit(fontProgress);
+            mLastFontProgress = fontProgress;
+        }
+    }
+
+    private void tryCommitDisplaySizeConfig() {
+        final int displayProgress = mDisplaySizePreference.getProgress();
+        if (displayProgress != mLastDisplayProgress) {
+            mDisplaySizeData.commit(displayProgress);
+            mLastDisplayProgress = displayProgress;
+        }
+    }
+
+    private Configuration[] createConfig(Configuration origConfig) {
+        final int fontDataSize = mFontSizeData.getValues().size();
+        final int displayDataSize = mDisplaySizeData.getValues().size();
+        final int totalNum = fontDataSize * displayDataSize;
+        final Configuration[] configurations = new Configuration[totalNum];
+
+        for (int i = 0; i < fontDataSize; ++i) {
+            for (int j = 0; j < displayDataSize; ++j) {
+                final Configuration config = new Configuration(origConfig);
+                config.fontScale = mFontSizeData.getValues().get(i);
+                config.densityDpi = mDisplaySizeData.getValues().get(j);
+
+                configurations[i * displayDataSize + j] = config;
+            }
+        }
+
+        return configurations;
+    }
+}
diff --git a/src/com/android/settings/accessibility/TextReadingPreviewPreference.java b/src/com/android/settings/accessibility/TextReadingPreviewPreference.java
index 1b9cc4b..4b8ca39 100644
--- a/src/com/android/settings/accessibility/TextReadingPreviewPreference.java
+++ b/src/com/android/settings/accessibility/TextReadingPreviewPreference.java
@@ -32,8 +32,9 @@
 /**
  * A {@link Preference} that could show the preview related to the text and reading options.
  */
-final class TextReadingPreviewPreference extends Preference {
+public class TextReadingPreviewPreference extends Preference {
     private int mCurrentItem;
+    private int mLastLayerIndex;
     private PreviewPagerAdapter mPreviewAdapter;
 
     TextReadingPreviewPreference(Context context) {
@@ -41,7 +42,7 @@
         init();
     }
 
-    TextReadingPreviewPreference(Context context, AttributeSet attrs) {
+    public TextReadingPreviewPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
         init();
     }
@@ -120,4 +121,16 @@
     private void init() {
         setLayoutResource(R.layout.accessibility_text_reading_preview);
     }
+
+    void notifyPreviewPagerChanged(int pagerIndex) {
+        Preconditions.checkNotNull(mPreviewAdapter,
+                "Preview adapter is null, you should init the preview adapter first");
+
+        if (pagerIndex != mLastLayerIndex) {
+            mPreviewAdapter.setPreviewLayer(pagerIndex, mLastLayerIndex, getCurrentItem(),
+                    /* animate= */ false);
+        }
+
+        mLastLayerIndex = pagerIndex;
+    }
 }
diff --git a/src/com/android/settings/accessibility/TextReadingResetController.java b/src/com/android/settings/accessibility/TextReadingResetController.java
new file mode 100644
index 0000000..f4752cb
--- /dev/null
+++ b/src/com/android/settings/accessibility/TextReadingResetController.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 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.accessibility;
+
+import android.content.Context;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+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;
+
+/**
+ * The controller of the reset button in the text and reading options page.
+ */
+class TextReadingResetController extends BasePreferenceController {
+    private final List<ResetStateListener> mListeners;
+
+    TextReadingResetController(Context context, String preferenceKey,
+            @NonNull List<ResetStateListener> listeners) {
+        super(context, preferenceKey);
+        mListeners = listeners;
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+
+        final LayoutPreference layoutPreference = screen.findPreference(getPreferenceKey());
+        final View view = layoutPreference.findViewById(R.id.reset_button);
+        view.setOnClickListener(v -> mListeners.forEach(ResetStateListener::resetState));
+    }
+
+    /**
+     * Interface for resetting to default state.
+     */
+    interface ResetStateListener {
+        /**
+         * Called when the reset button was clicked.
+         */
+        void resetState();
+    }
+}
diff --git a/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java
index 679e284..e421626 100644
--- a/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java
@@ -82,6 +82,7 @@
         mComponentName = COLOR_INVERSION_COMPONENT_NAME;
         mPackageName = getText(R.string.accessibility_display_inversion_preference_title);
         mHtmlDescription = getText(R.string.accessibility_display_inversion_preference_subtitle);
+        mTopIntroTitle = getText(R.string.accessibility_display_inversion_preference_intro_text);
         mImageUri = new Uri.Builder().scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
                 .authority(getPrefContext().getPackageName())
                 .appendPath(String.valueOf(R.raw.accessibility_color_inversion_banner))
diff --git a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
index 5d9cbe5..b1b9f81 100644
--- a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
@@ -51,7 +51,10 @@
 
     private static final String ENABLED = Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED;
     private static final String KEY_PREVIEW = "daltonizer_preview";
-    private static final String KEY_CATEGORY_MODE = "daltonizer_mode_category";
+    private static final String KEY_DEUTERANOMALY = "daltonizer_mode_deuteranomaly";
+    private static final String KEY_PROTANOMALY = "daltonizer_mode_protanomaly";
+    private static final String KEY_TRITANOMEALY = "daltonizer_mode_tritanomaly";
+    private static final String KEY_GRAYSCALE = "daltonizer_mode_grayscale";
     private static final List<AbstractPreferenceController> sControllers = new ArrayList<>();
 
     private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
@@ -82,6 +85,7 @@
         mComponentName = DALTONIZER_COMPONENT_NAME;
         mPackageName = getText(R.string.accessibility_display_daltonizer_preference_title);
         mHtmlDescription = getText(R.string.accessibility_display_daltonizer_preference_subtitle);
+        mTopIntroTitle = getText(R.string.accessibility_daltonizer_about_intro_text);
         final View view = super.onCreateView(inflater, container, savedInstanceState);
         updateFooterPreference();
         return view;
@@ -111,9 +115,13 @@
     /** Customizes the order by preference key. */
     protected List<String> getPreferenceOrderList() {
         final List<String> lists = new ArrayList<>();
+        lists.add(KEY_TOP_INTRO_PREFERENCE);
         lists.add(KEY_PREVIEW);
         lists.add(KEY_USE_SERVICE_PREFERENCE);
-        lists.add(KEY_CATEGORY_MODE);
+        lists.add(KEY_DEUTERANOMALY);
+        lists.add(KEY_PROTANOMALY);
+        lists.add(KEY_TRITANOMEALY);
+        lists.add(KEY_GRAYSCALE);
         lists.add(KEY_GENERAL_CATEGORY);
         lists.add(KEY_HTML_DESCRIPTION_PREFERENCE);
         return lists;
diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
index 08e9b88..5747d0a 100644
--- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
@@ -63,6 +63,7 @@
 import com.android.settingslib.accessibility.AccessibilityUtils;
 import com.android.settingslib.widget.IllustrationPreference;
 import com.android.settingslib.widget.OnMainSwitchChangeListener;
+import com.android.settingslib.widget.TopIntroPreference;
 
 import com.google.android.setupcompat.util.WizardManagerHelper;
 
@@ -92,8 +93,10 @@
     protected Uri mImageUri;
     private CharSequence mDescription;
     protected CharSequence mHtmlDescription;
+    protected CharSequence mTopIntroTitle;
 
     private static final String DRAWABLE_FOLDER = "drawable";
+    protected static final String KEY_TOP_INTRO_PREFERENCE = "top_intro";
     protected static final String KEY_USE_SERVICE_PREFERENCE = "use_service";
     public static final String KEY_GENERAL_CATEGORY = "general_categories";
     protected static final String KEY_HTML_DESCRIPTION_PREFERENCE = "html_description";
@@ -182,6 +185,7 @@
         // Need to be called as early as possible. Protected variables will be assigned here.
         onProcessArguments(getArguments());
 
+        initTopIntroPreference();
         initAnimatedImagePreference();
         initToggleServiceSwitchPreference();
         initGeneralCategory();
@@ -388,11 +392,17 @@
             mHtmlDescription = arguments.getCharSequence(
                     AccessibilitySettings.EXTRA_HTML_DESCRIPTION);
         }
+
+        // Intro.
+        if (arguments.containsKey(AccessibilitySettings.EXTRA_INTRO)) {
+            mTopIntroTitle = arguments.getCharSequence(AccessibilitySettings.EXTRA_INTRO);
+        }
     }
 
     /** Customizes the order by preference key. */
     protected List<String> getPreferenceOrderList() {
         final List<String> lists = new ArrayList<>();
+        lists.add(KEY_TOP_INTRO_PREFERENCE);
         lists.add(KEY_ANIMATED_IMAGE);
         lists.add(KEY_USE_SERVICE_PREFERENCE);
         lists.add(KEY_GENERAL_CATEGORY);
@@ -461,6 +471,17 @@
         getPreferenceScreen().addPreference(illustrationPreference);
     }
 
+    @VisibleForTesting
+    void initTopIntroPreference() {
+        if (TextUtils.isEmpty(mTopIntroTitle)) {
+            return;
+        }
+        final TopIntroPreference topIntroPreference = new TopIntroPreference(getPrefContext());
+        topIntroPreference.setKey(KEY_TOP_INTRO_PREFERENCE);
+        topIntroPreference.setTitle(mTopIntroTitle);
+        getPreferenceScreen().addPreference(topIntroPreference);
+    }
+
     private void initToggleServiceSwitchPreference() {
         mToggleServiceSwitchPreference = new SettingsMainSwitchPreference(getPrefContext());
         mToggleServiceSwitchPreference.setKey(KEY_USE_SERVICE_PREFERENCE);
diff --git a/src/com/android/settings/accessibility/ToggleReduceBrightColorsPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleReduceBrightColorsPreferenceFragment.java
index 973e27c..1e2e9e5 100644
--- a/src/com/android/settings/accessibility/ToggleReduceBrightColorsPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleReduceBrightColorsPreferenceFragment.java
@@ -68,6 +68,7 @@
         mComponentName = REDUCE_BRIGHT_COLORS_COMPONENT_NAME;
         mPackageName = getText(R.string.reduce_bright_colors_preference_title);
         mHtmlDescription = getText(R.string.reduce_bright_colors_preference_subtitle);
+        mTopIntroTitle = getText(R.string.reduce_bright_colors_preference_intro_text);
         mRbcIntensityPreferenceController =
                 new ReduceBrightColorsIntensityPreferenceController(getContext(), KEY_INTENSITY);
         mRbcPersistencePreferenceController =
diff --git a/src/com/android/settings/applications/appinfo/AppLocaleDetails.java b/src/com/android/settings/applications/appinfo/AppLocaleDetails.java
index 164cfd9..8f1c212 100644
--- a/src/com/android/settings/applications/appinfo/AppLocaleDetails.java
+++ b/src/com/android/settings/applications/appinfo/AppLocaleDetails.java
@@ -38,8 +38,6 @@
 import androidx.preference.Preference;
 import androidx.preference.PreferenceGroup;
 
-import com.android.internal.app.LocalePicker;
-import com.android.internal.app.LocalePicker.LocaleInfo;
 import com.android.settings.R;
 import com.android.settings.Utils;
 import com.android.settings.applications.AppInfoBase;
@@ -48,11 +46,8 @@
 import com.android.settingslib.widget.LayoutPreference;
 import com.android.settingslib.widget.RadioButtonPreference;
 
-import com.google.common.collect.Iterables;
-
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.List;
 import java.util.Locale;
 
 /**
@@ -66,13 +61,17 @@
     private static final String CATEGORY_KEY_ALL_LANGUAGES =
             "category_key_all_languages";
     private static final String KEY_APP_DESCRIPTION = "app_locale_description";
+    @VisibleForTesting
+    static final String KEY_SYSTEM_DEFAULT_LOCALE = "system_default_locale";
 
     private boolean mCreated = false;
-    private AppLocaleDetailsHelper mAppLocaleDetailsHelper;
+    @VisibleForTesting
+    AppLocaleDetailsHelper mAppLocaleDetailsHelper;
 
     private PreferenceGroup mGroupOfSuggestedLocales;
     private PreferenceGroup mGroupOfSupportedLocales;
     private LayoutPreference mPrefOfDescription;
+    private RadioButtonPreference mDefaultPreference;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -85,6 +84,10 @@
         mGroupOfSupportedLocales =
                 getPreferenceScreen().findPreference(CATEGORY_KEY_ALL_LANGUAGES);
         mPrefOfDescription = getPreferenceScreen().findPreference(KEY_APP_DESCRIPTION);
+
+        mDefaultPreference = (RadioButtonPreference) getPreferenceScreen()
+                .findPreference(KEY_SYSTEM_DEFAULT_LOCALE);
+        mDefaultPreference.setOnClickListener(this);
     }
 
     // Override here so we don't have an empty screen
@@ -104,30 +107,43 @@
         // Update Locales first, before refresh ui.
         mAppLocaleDetailsHelper.handleAllLocalesData();
         super.onResume();
+        mDefaultPreference.setSummary(Locale.getDefault().getDisplayName(Locale.getDefault()));
     }
 
     @Override
     protected boolean refreshUi() {
+        refreshUiInternal();
+        return true;
+    }
+
+    @VisibleForTesting
+    void refreshUiInternal() {
         if (mAppLocaleDetailsHelper.getSupportedLocales().isEmpty()) {
             Log.d(TAG, "No supported language.");
             mGroupOfSuggestedLocales.setVisible(false);
             mGroupOfSupportedLocales.setVisible(false);
             mPrefOfDescription.setVisible(true);
             TextView description = (TextView) mPrefOfDescription.findViewById(R.id.description);
-            Locale locale = mAppLocaleDetailsHelper.getCurrentSystemLocales().get(0);
             description.setText(getContext().getString(R.string.no_multiple_language_supported,
-                    locale.getDisplayName(locale)));
-            return true;
+                    Locale.getDefault().getDisplayName(Locale.getDefault())));
+            return;
         }
-
-        mGroupOfSuggestedLocales.removeAll();
-        mGroupOfSupportedLocales.removeAll();
+        resetLocalePreferences();
         Locale appLocale = AppLocaleDetailsHelper.getAppDefaultLocale(getContext(), mPackageName);
+        // Sets up default locale preference.
+        mGroupOfSuggestedLocales.addPreference(mDefaultPreference);
+        mDefaultPreference.setChecked(appLocale == null);
+        // Sets up suggested locales of per app.
         setLanguagesPreference(mGroupOfSuggestedLocales,
                 mAppLocaleDetailsHelper.getSuggestedLocales(), appLocale);
+        // Sets up supported locales of per app.
         setLanguagesPreference(mGroupOfSupportedLocales,
                 mAppLocaleDetailsHelper.getSupportedLocales(), appLocale);
-        return true;
+    }
+
+    private void resetLocalePreferences() {
+        mGroupOfSuggestedLocales.removeAll();
+        mGroupOfSupportedLocales.removeAll();
     }
 
     @Override
@@ -142,7 +158,12 @@
 
     @Override
     public void onRadioButtonClicked(RadioButtonPreference pref) {
-        mAppLocaleDetailsHelper.setAppDefaultLocale(pref.getKey());
+        String key = pref.getKey();
+        if (KEY_SYSTEM_DEFAULT_LOCALE.equals(key)) {
+            mAppLocaleDetailsHelper.setAppDefaultLocale(LocaleList.forLanguageTags(""));
+        } else {
+            mAppLocaleDetailsHelper.setAppDefaultLocale(key);
+        }
         refreshUi();
     }
 
@@ -180,7 +201,13 @@
     public static CharSequence getSummary(Context context, String packageName) {
         Locale appLocale =
                 AppLocaleDetailsHelper.getAppDefaultLocale(context, packageName);
-        return appLocale == null ? "" : appLocale.getDisplayName(appLocale);
+        if (appLocale == null) {
+            Locale systemLocale = Locale.getDefault();
+            return context.getString(R.string.preference_of_system_locale_summary,
+                    systemLocale.getDisplayName(systemLocale));
+        } else {
+            return appLocale.getDisplayName(appLocale);
+        }
     }
 
     private void setLanguagesPreference(PreferenceGroup group,
@@ -190,9 +217,15 @@
         }
 
         for (Locale locale : locales) {
+            if (locale == null) {
+                continue;
+            }
+
             RadioButtonPreference pref = new RadioButtonPreference(getContext());
             pref.setTitle(locale.getDisplayName(locale));
             pref.setKey(locale.toLanguageTag());
+            // Will never be checked if appLocale is null
+            // aka if there is no per-app locale
             pref.setChecked(locale.equals(appLocale));
             pref.setOnClickListener(this);
             group.addPreference(pref);
@@ -206,14 +239,17 @@
         private TelephonyManager mTelephonyManager;
         private LocaleManager mLocaleManager;
 
-        private Collection<Locale> mSuggestedLocales = new ArrayList<>();
-        private Collection<Locale> mSupportedLocales = new ArrayList<>();
+        private Collection<Locale> mProcessedSuggestedLocales = new ArrayList<>();
+        private Collection<Locale> mProcessedSupportedLocales = new ArrayList<>();
+
+        private Collection<Locale> mAppSupportedLocales = new ArrayList<>();
 
         AppLocaleDetailsHelper(Context context, String packageName) {
             mContext = context;
             mPackageName = packageName;
             mTelephonyManager = context.getSystemService(TelephonyManager.class);
             mLocaleManager = context.getSystemService(LocaleManager.class);
+            mAppSupportedLocales = getAppSupportedLocales();
         }
 
         /** Handle suggested and supported locales for UI display. */
@@ -225,49 +261,47 @@
 
         /** Gets suggested locales in the app. */
         public Collection<Locale> getSuggestedLocales() {
-            return mSuggestedLocales;
+            return mProcessedSuggestedLocales;
         }
 
         /** Gets supported locales in the app. */
         public Collection<Locale> getSupportedLocales() {
-            return mSupportedLocales;
+            return mProcessedSupportedLocales;
         }
 
         @VisibleForTesting
         void handleSuggestedLocales() {
-            LocaleList currentSystemLocales = getCurrentSystemLocales();
             Locale appLocale = getAppDefaultLocale(mContext, mPackageName);
+            // 1st locale in suggested languages group.
+            for (Locale supportedlocale : mAppSupportedLocales) {
+                if (compareLocale(supportedlocale, appLocale)) {
+                    mProcessedSuggestedLocales.add(appLocale);
+                    break;
+                }
+            }
+
+            // 2nd and 3rd locale in suggested languages group.
             String simCountry = mTelephonyManager.getSimCountryIso().toUpperCase(Locale.US);
             String networkCountry = mTelephonyManager.getNetworkCountryIso().toUpperCase(Locale.US);
-            // 1st locale in suggested languages group.
-            if (appLocale != null) {
-                mSuggestedLocales.add(appLocale);
-            }
-            // 2nd locale in suggested languages group.
-            final List<LocaleInfo> localeInfos = LocalePicker.getAllAssetLocales(mContext, false);
-            for (LocaleInfo localeInfo : localeInfos) {
-                Locale locale = localeInfo.getLocale();
-                String localeCountry = locale.getCountry().toUpperCase(Locale.US);
-                if (!compareLocale(locale, appLocale)
+            mAppSupportedLocales.forEach(supportedlocale -> {
+                String localeCountry = supportedlocale.getCountry().toUpperCase(Locale.US);
+                if (!compareLocale(supportedlocale, appLocale)
                         && isCountrySuggestedLocale(localeCountry, simCountry, networkCountry)) {
-                    mSuggestedLocales.add(locale);
+                    mProcessedSuggestedLocales.add(supportedlocale);
                 }
-            }
+            });
+
             // Other locales in suggested languages group.
-            for (int i = 0; i < currentSystemLocales.size(); i++) {
-                Locale locale = currentSystemLocales.get(i);
-                boolean isInSuggestedLocales = false;
-                for (int j = 0; j < mSuggestedLocales.size(); j++) {
-                    Locale suggestedLocale = Iterables.get(mSuggestedLocales, j);
-                    if (compareLocale(locale, suggestedLocale)) {
-                        isInSuggestedLocales = true;
-                        break;
+            Collection<Locale> supportedSystemLocales = new ArrayList<>();
+            getCurrentSystemLocales().forEach(systemLocale -> {
+                mAppSupportedLocales.forEach(supportedLocale -> {
+                    if (compareLocale(systemLocale, supportedLocale)) {
+                        supportedSystemLocales.add(supportedLocale);
                     }
-                }
-                if (!isInSuggestedLocales) {
-                    mSuggestedLocales.add(locale);
-                }
-            }
+                });
+            });
+            supportedSystemLocales.removeAll(mProcessedSuggestedLocales);
+            mProcessedSuggestedLocales.addAll(supportedSystemLocales);
         }
 
         @VisibleForTesting
@@ -290,26 +324,34 @@
 
         @VisibleForTesting
         void handleSupportedLocales() {
-            LocaleList localeList = getPackageLocales();
-            if (localeList == null) {
-                String[] languages = getAssetSystemLocales();
-                for (String language : languages) {
-                    mSupportedLocales.add(Locale.forLanguageTag(language));
-                }
-            } else {
-                for (int i = 0; i < localeList.size(); i++) {
-                    mSupportedLocales.add(localeList.get(i));
-                }
-            }
+            mProcessedSupportedLocales.addAll(mAppSupportedLocales);
 
-            if (mSuggestedLocales != null || !mSuggestedLocales.isEmpty()) {
-                mSupportedLocales.removeAll(mSuggestedLocales);
+            if (mProcessedSuggestedLocales != null || !mProcessedSuggestedLocales.isEmpty()) {
+                mProcessedSuggestedLocales.retainAll(mProcessedSupportedLocales);
+                mProcessedSupportedLocales.removeAll(mProcessedSuggestedLocales);
             }
         }
 
         private void clearLocalesData() {
-            mSuggestedLocales.clear();
-            mSupportedLocales.clear();
+            mProcessedSuggestedLocales.clear();
+            mProcessedSupportedLocales.clear();
+        }
+
+        private Collection<Locale> getAppSupportedLocales() {
+            Collection<Locale> appSupportedLocales = new ArrayList<>();
+            LocaleList localeList = getPackageLocales();
+
+            if (localeList != null && localeList.size() > 0) {
+                for (int i = 0; i < localeList.size(); i++) {
+                    appSupportedLocales.add(localeList.get(i));
+                }
+            } else {
+                String[] languages = getAssetLocales();
+                for (String language : languages) {
+                    appSupportedLocales.add(Locale.forLanguageTag(language));
+                }
+            }
+            return appSupportedLocales;
         }
 
         /** Gets per app's default locale */
@@ -317,8 +359,8 @@
             LocaleManager localeManager = context.getSystemService(LocaleManager.class);
             try {
                 LocaleList localeList = (localeManager == null)
-                        ? new LocaleList() : localeManager.getApplicationLocales(packageName);
-                return localeList.isEmpty() ? null : localeList.get(0);
+                        ? null : localeManager.getApplicationLocales(packageName);
+                return localeList == null ? null : localeList.get(0);
             } catch (IllegalArgumentException e) {
                 Log.w(TAG, "package name : " + packageName + " is not correct. " + e);
             }
@@ -344,12 +386,17 @@
         }
 
         @VisibleForTesting
-        LocaleList getCurrentSystemLocales() {
-            return Resources.getSystem().getConfiguration().getLocales();
+        Collection<Locale> getCurrentSystemLocales() {
+            LocaleList localeList = Resources.getSystem().getConfiguration().getLocales();
+            Collection<Locale> systemLocales = new ArrayList<>();
+            for (int i = 0; i < localeList.size(); i++) {
+                systemLocales.add(localeList.get(i));
+            }
+            return systemLocales;
         }
 
         @VisibleForTesting
-        String[] getAssetSystemLocales() {
+        String[] getAssetLocales() {
             try {
                 PackageManager packageManager = mContext.getPackageManager();
                 return packageManager.getResourcesForApplication(
diff --git a/src/com/android/settings/applications/appinfo/OWNERS b/src/com/android/settings/applications/appinfo/OWNERS
new file mode 100644
index 0000000..cd6abb8
--- /dev/null
+++ b/src/com/android/settings/applications/appinfo/OWNERS
@@ -0,0 +1,5 @@
+# just for per-app locale settings review
+allenwtsu@google.com
+danielwbhuang@google.com
+goldmanj@google.com
+tomhsu@google.com
diff --git a/src/com/android/settings/applications/assist/ManageAssist.java b/src/com/android/settings/applications/assist/ManageAssist.java
index c96f43f..ad6c71e 100644
--- a/src/com/android/settings/applications/assist/ManageAssist.java
+++ b/src/com/android/settings/applications/assist/ManageAssist.java
@@ -73,7 +73,6 @@
         controllers.add(new AssistContextPreferenceController(context, lifecycle));
         controllers.add(new AssistScreenshotPreferenceController(context, lifecycle));
         controllers.add(new AssistFlashScreenPreferenceController(context, lifecycle));
-        controllers.add(new DefaultVoiceInputPreferenceController(context, lifecycle));
         return controllers;
     }
 
diff --git a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java
index b6a2970..de79739 100644
--- a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java
+++ b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java
@@ -311,11 +311,13 @@
                 return;
             }
 
-            // othewise, only the defined default supervision profile owner can be set after user
-            // setup.
+            // otherwise, only the defined default supervision profile owner or holder of
+            // supersvision role can be set after user setup.
             final String supervisor = getString(
                     com.android.internal.R.string.config_defaultSupervisionProfileOwnerComponent);
-            if (TextUtils.isEmpty(supervisor)) {
+            final String supervisionRolePackage = getString(
+                    com.android.internal.R.string.config_systemSupervision);
+            if (TextUtils.isEmpty(supervisor) && TextUtils.isEmpty(supervisionRolePackage)) {
                 Log.w(TAG, "Unable to set profile owner post-setup, no default supervisor"
                         + "profile owner defined");
                 finish();
@@ -324,7 +326,8 @@
 
             final ComponentName supervisorComponent = ComponentName.unflattenFromString(
                     supervisor);
-            if (supervisorComponent == null || who.compareTo(supervisorComponent) != 0) {
+            if (!who.equals(supervisorComponent)
+                    && !who.getPackageName().equals(supervisionRolePackage)) {
                 Log.w(TAG, "Unable to set non-default profile owner post-setup " + who);
                 finish();
                 return;
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressController.java b/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressController.java
index ec3e11f..d80512e 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressController.java
@@ -46,21 +46,22 @@
     protected void init(PreferenceScreen screen) {
         mFooterPreference = screen.findPreference(KEY_DEVICE_DETAILS_FOOTER);
         mFooterPreference.setTitle(mContext.getString(
-                R.string.bluetooth_device_mac_address, mCachedDevice.getAddress()));
+                R.string.bluetooth_device_mac_address, mCachedDevice.getIdentityAddress()));
     }
 
     @Override
     protected void refresh() {
         if (mCachedDevice.getGroupId() != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
             StringBuilder title = new StringBuilder(mContext.getString(
-                R.string.bluetooth_multuple_devices_mac_address, mCachedDevice.getAddress()));
+                    R.string.bluetooth_multuple_devices_mac_address,
+                            mCachedDevice.getIdentityAddress()));
             for (CachedBluetoothDevice member: mCachedDevice.getMemberDevice()) {
-                title.append("\n").append(member.getAddress());
+                title.append("\n").append(member.getIdentityAddress());
             }
             mFooterPreference.setTitle(title);
         } else {
             mFooterPreference.setTitle(mContext.getString(
-                R.string.bluetooth_device_mac_address, mCachedDevice.getAddress()));
+                    R.string.bluetooth_device_mac_address, mCachedDevice.getIdentityAddress()));
         }
     }
 
diff --git a/src/com/android/settings/bluetooth/BluetoothPairingController.java b/src/com/android/settings/bluetooth/BluetoothPairingController.java
index b75e02a..c70a56a 100644
--- a/src/com/android/settings/bluetooth/BluetoothPairingController.java
+++ b/src/com/android/settings/bluetooth/BluetoothPairingController.java
@@ -435,7 +435,7 @@
      */
     public void onCancel() {
         Log.d(TAG, "Pairing dialog canceled");
-        mDevice.cancelPairing();
+        mDevice.cancelBondProcess();
     }
 
     /**
diff --git a/src/com/android/settings/bluetooth/BluetoothPairingService.java b/src/com/android/settings/bluetooth/BluetoothPairingService.java
index bc5dc66..9883e61 100644
--- a/src/com/android/settings/bluetooth/BluetoothPairingService.java
+++ b/src/com/android/settings/bluetooth/BluetoothPairingService.java
@@ -98,7 +98,7 @@
             } else if (action.equals(ACTION_DISMISS_PAIRING)) {
                 Log.d(TAG, "Notification cancel " + " (" +
                         mDevice.getName() + ")");
-                mDevice.cancelPairing();
+                mDevice.cancelBondProcess();
             } else {
                 int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
                         BluetoothDevice.ERROR);
@@ -144,7 +144,7 @@
             createPairingNotification(intent);
         } else if (TextUtils.equals(action, ACTION_DISMISS_PAIRING)) {
             Log.d(TAG, "Notification cancel " + " (" + mDevice.getName() + ")");
-            mDevice.cancelPairing();
+            mDevice.cancelBondProcess();
             mNm.cancel(NOTIFICATION_ID);
             stopSelf();
         } else if (TextUtils.equals(action, ACTION_PAIRING_DIALOG)) {
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 2f0e8b3..ce3cab9 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -29,6 +29,7 @@
 import com.android.settings.accessibility.AccessibilitySettings;
 import com.android.settings.accessibility.AccessibilitySettingsForSetupWizard;
 import com.android.settings.accessibility.CaptionPropertiesFragment;
+import com.android.settings.accessibility.TextReadingPreferenceFragmentForSetupWizard;
 import com.android.settings.accessibility.ToggleColorInversionPreferenceFragment;
 import com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment;
 import com.android.settings.accessibility.ToggleReduceBrightColorsPreferenceFragment;
@@ -222,6 +223,7 @@
             AccessibilityDetailsSettingsFragment.class.getName(),
             AccessibilitySettings.class.getName(),
             AccessibilitySettingsForSetupWizard.class.getName(),
+            TextReadingPreferenceFragmentForSetupWizard.class.getName(),
             CaptionPropertiesFragment.class.getName(),
             ToggleDaltonizerPreferenceFragment.class.getName(),
             ToggleColorInversionPreferenceFragment.class.getName(),
diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
index cdac3b9..8ad66d2 100644
--- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
@@ -171,11 +171,13 @@
                     intent.setAction(action);
                 }
                 // Register the rule for injected apps.
-                ActivityEmbeddingRulesController.registerTwoPanePairRuleForSettingsHome(
-                        mContext,
-                        new ComponentName(tile.getPackageName(), tile.getComponentName()),
-                        action,
-                        true /* clearTop */);
+                if (fragment instanceof TopLevelSettings) {
+                    ActivityEmbeddingRulesController.registerTwoPanePairRuleForSettingsHome(
+                            mContext,
+                            new ComponentName(tile.getPackageName(), tile.getComponentName()),
+                            action,
+                            true /* clearTop */);
+                }
                 pref.setOnPreferenceClickListener(preference -> {
                     TopLevelHighlightMixin highlightMixin = null;
                     if (fragment instanceof TopLevelSettings
@@ -442,11 +444,6 @@
         ProfileSelectDialog.updateUserHandlesIfNeeded(mContext, tile);
         mMetricsFeatureProvider.logStartedIntent(intent, sourceMetricCategory);
 
-        //TODO(b/201970810): Add test cases.
-        if (tile.isNewTask(mContext)) {
-            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        }
-
         if (tile.userHandle == null || tile.isPrimaryProfileOnly()) {
             activity.startActivity(intent);
         } else if (tile.userHandle.size() == 1) {
diff --git a/src/com/android/settings/dashboard/DashboardFragment.java b/src/com/android/settings/dashboard/DashboardFragment.java
index cfdfdaa..8b1d633 100644
--- a/src/com/android/settings/dashboard/DashboardFragment.java
+++ b/src/com/android/settings/dashboard/DashboardFragment.java
@@ -53,6 +53,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -280,6 +281,11 @@
         return null;
     }
 
+    /** Returns all controllers of type T. */
+    protected <T extends AbstractPreferenceController> List<T> useAll(Class<T> clazz) {
+        return (List<T>) mPreferenceControllers.getOrDefault(clazz, Collections.emptyList());
+    }
+
     protected void addPreferenceController(AbstractPreferenceController controller) {
         if (mPreferenceControllers.get(controller.getClass()) == null) {
             mPreferenceControllers.put(controller.getClass(), new ArrayList<>());
diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java
index e0ba378..d3234dd 100644
--- a/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java
+++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java
@@ -97,7 +97,7 @@
     public void onClick(DialogInterface dialog, int which) {
         final UserHandle user = mSelectedTile.userHandle.get(which);
         // Show menu on top level items.
-        final Intent intent = mSelectedTile.getIntent();
+        final Intent intent = new Intent(mSelectedTile.getIntent());
         FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider()
                 .logStartedIntentWithProfile(intent, mSourceMetricCategory,
                         which == 1 /* isWorkProfile */);
diff --git a/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java b/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java
index 1b3b47a..fe20a01 100644
--- a/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java
+++ b/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java
@@ -123,13 +123,13 @@
         mDataUsageController = null;
     }
 
-    private void updateConfiguration(Context context,
+    protected void updateConfiguration(Context context,
             int subscriptionId, SubscriptionInfo subInfo) {
         final NetworkPolicyManager policyManager =
                 context.getSystemService(NetworkPolicyManager.class);
         mPolicyEditor = new NetworkPolicyEditor(policyManager);
 
-        mDataUsageController = new DataUsageController(context);
+        mDataUsageController = createDataUsageController(context);
         mDataUsageController.setSubscriptionId(subscriptionId);
         mDataInfoController = new DataUsageInfoController();
 
@@ -146,6 +146,11 @@
     }
 
     @VisibleForTesting
+    DataUsageController createDataUsageController(Context context) {
+        return new DataUsageController(context);
+    }
+
+    @VisibleForTesting
     DataUsageSummaryPreferenceController(
             DataUsageController dataUsageController,
             DataUsageInfoController dataInfoController,
@@ -186,8 +191,7 @@
                 .getSubscriptionPlans(subscriptionId);
     }
 
-    @VisibleForTesting
-    SubscriptionInfo getSubscriptionInfo(int subscriptionId) {
+    protected SubscriptionInfo getSubscriptionInfo(int subscriptionId) {
         if (!mHasMobileData) {
             return null;
         }
diff --git a/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java b/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java
index cd26ed1..08e523c 100644
--- a/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java
+++ b/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java
@@ -48,7 +48,6 @@
             ApplicationsState applicationsState, DataSaverBackend dataSaverBackend,
             DashboardFragment parentFragment) {
         super(context);
-        setWidgetLayoutResource(R.layout.restricted_switch_widget);
         mHelper = new RestrictedPreferenceHelper(context, this, null);
         mEntry = entry;
         mDataUsageState = (AppStateDataUsageBridge.DataUsageState) mEntry.extraInfo;
@@ -88,7 +87,7 @@
 
     @Override
     protected void onClick() {
-        if (mDataUsageState.isDataSaverDenylisted) {
+        if (mDataUsageState != null && mDataUsageState.isDataSaverDenylisted) {
             // app is denylisted, launch App Data Usage screen
             AppInfoDashboardFragment.startAppInfoFragment(AppDataUsage.class,
                     R.string.data_usage_app_summary_title,
@@ -131,10 +130,6 @@
         super.onBindViewHolder(holder);
 
         mHelper.onBindViewHolder(holder);
-        holder.findViewById(R.id.restricted_icon).setVisibility(
-                disabledByAdmin ? View.VISIBLE : View.GONE);
-        holder.findViewById(android.R.id.switch_widget).setVisibility(
-                disabledByAdmin ? View.GONE : View.VISIBLE);
     }
 
     @Override
diff --git a/src/com/android/settings/datausage/WifiDataUsageSummaryPreferenceController.java b/src/com/android/settings/datausage/WifiDataUsageSummaryPreferenceController.java
index 9d3054e..4d2dd00 100644
--- a/src/com/android/settings/datausage/WifiDataUsageSummaryPreferenceController.java
+++ b/src/com/android/settings/datausage/WifiDataUsageSummaryPreferenceController.java
@@ -26,23 +26,19 @@
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.net.DataUsageController;
 
+import java.util.HashSet;
 import java.util.Set;
 
 /**
  * The controller displays a data usage chart for the specified Wi-Fi network.
  */
 public class WifiDataUsageSummaryPreferenceController extends DataUsageSummaryPreferenceController {
-    final String mNetworkId;
+    final Set<String> mAllNetworkKeys;
 
-    public WifiDataUsageSummaryPreferenceController(Activity activity,
-            Lifecycle lifecycle, PreferenceFragmentCompat fragment, CharSequence networkId) {
+    public WifiDataUsageSummaryPreferenceController(Activity activity, Lifecycle lifecycle,
+            PreferenceFragmentCompat fragment, Set<String> allNetworkKeys) {
         super(activity, lifecycle, fragment, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-
-        if (networkId == null) {
-            mNetworkId = null;
-        } else {
-            mNetworkId = String.valueOf(networkId);
-        }
+        mAllNetworkKeys = new HashSet<>(allNetworkKeys);
     }
 
     @Override
@@ -52,10 +48,11 @@
         }
 
         final DataUsageSummaryPreference mPreference = (DataUsageSummaryPreference) preference;
-        // TODO(b/126299427): Currently gets data usage of whole Wi-Fi networks, but should get
-        //  specified one.
         final NetworkTemplate template = new NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI)
-                .setWifiNetworkKeys(Set.of(mNetworkId)).build();
+                .setWifiNetworkKeys(mAllNetworkKeys).build();
+        if (mDataUsageController == null) {
+            updateConfiguration(mContext, mSubId, getSubscriptionInfo(mSubId));
+        }
         final DataUsageController.DataUsageInfo info = mDataUsageController.getDataUsageInfo(
                 template);
         mDataInfoController.updateDataLimit(info, mPolicyEditor.getPolicy(template));
diff --git a/src/com/android/settings/display/AutoRotatePreferenceController.java b/src/com/android/settings/display/AutoRotatePreferenceController.java
index 5dc2286..90423fb 100644
--- a/src/com/android/settings/display/AutoRotatePreferenceController.java
+++ b/src/com/android/settings/display/AutoRotatePreferenceController.java
@@ -74,6 +74,7 @@
     @Override
     public int getAvailabilityStatus() {
         return RotationPolicy.isRotationLockToggleVisible(mContext)
+                && !DeviceStateAutoRotationHelper.isDeviceStateRotationEnabled(mContext)
                 ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
     }
 
diff --git a/src/com/android/settings/display/DeviceStateAutoRotateDetailsFragment.java b/src/com/android/settings/display/DeviceStateAutoRotateDetailsFragment.java
new file mode 100644
index 0000000..fb6d9f4
--- /dev/null
+++ b/src/com/android/settings/display/DeviceStateAutoRotateDetailsFragment.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.display;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.search.Indexable;
+import com.android.settingslib.search.SearchIndexable;
+import com.android.settingslib.search.SearchIndexableRaw;
+
+import java.util.List;
+
+/** Fragment that shows all the available device state based auto-rotation preferences. */
+@SearchIndexable
+public class DeviceStateAutoRotateDetailsFragment extends DashboardFragment {
+
+    private static final String TAG = "DeviceStateAutoRotateDetailsFragment";
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.DISPLAY_AUTO_ROTATE_SETTINGS;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.device_state_auto_rotate_settings;
+    }
+
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        DeviceStateAutoRotationHelper.initControllers(
+                getLifecycle(),
+                useAll(DeviceStateAutoRotateSettingController.class)
+        );
+    }
+
+    @Override
+    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+        return DeviceStateAutoRotationHelper.createPreferenceControllers(context);
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.device_state_auto_rotate_settings) {
+
+                @Override
+                public List<SearchIndexableRaw> getRawDataToIndex(Context context,
+                        boolean enabled) {
+                    return DeviceStateAutoRotationHelper.getRawDataToIndex(context, enabled);
+                }
+            };
+}
diff --git a/src/com/android/settings/display/DeviceStateAutoRotateOverviewController.java b/src/com/android/settings/display/DeviceStateAutoRotateOverviewController.java
new file mode 100644
index 0000000..5e49bf3
--- /dev/null
+++ b/src/com/android/settings/display/DeviceStateAutoRotateOverviewController.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.display;
+
+import android.content.Context;
+import android.text.TextUtils;
+
+import com.android.settings.core.BasePreferenceController;
+
+/**
+ * The top-level preference controller for device state based auto-rotation settings.
+ *
+ * It doesn't do anything on its own besides showing/hiding. The toggling of the settings will
+ * always be done in the details screen when device state based auto-rotation is enabled.
+ */
+public class DeviceStateAutoRotateOverviewController extends BasePreferenceController {
+
+    /** Preference key for when it is used in "accessibility_system_controls.xml". */
+    private static final String ACCESSIBILITY_PREF_KEY = "device_state_auto_rotate_accessibility";
+
+    public DeviceStateAutoRotateOverviewController(Context context, String key) {
+        super(context, key);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return isAvailableInternal() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+    }
+
+    private boolean isAvailableInternal() {
+        return isA11yPage()
+                ? DeviceStateAutoRotationHelper.isDeviceStateRotationEnabledForA11y(mContext)
+                : DeviceStateAutoRotationHelper.isDeviceStateRotationEnabled(mContext);
+    }
+
+    private boolean isA11yPage() {
+        return TextUtils.equals(getPreferenceKey(), ACCESSIBILITY_PREF_KEY);
+    }
+}
diff --git a/src/com/android/settings/display/DeviceStateAutoRotateSettingController.java b/src/com/android/settings/display/DeviceStateAutoRotateSettingController.java
new file mode 100644
index 0000000..c8f6280
--- /dev/null
+++ b/src/com/android/settings/display/DeviceStateAutoRotateSettingController.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.display;
+
+import static androidx.lifecycle.Lifecycle.Event.ON_START;
+import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+
+import com.android.settings.R;
+import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
+import com.android.settingslib.search.SearchIndexableRaw;
+
+import java.util.List;
+
+/** Controller for device state based auto rotation preferences. */
+public class DeviceStateAutoRotateSettingController extends TogglePreferenceController implements
+        LifecycleObserver {
+
+    private SwitchPreference mPreference;
+
+    private final DeviceStateRotationLockSettingsManager mAutoRotateSettingsManager;
+    private final int mOrder;
+    private final DeviceStateRotationLockSettingsManager.DeviceStateRotationLockSettingsListener
+            mDeviceStateRotationLockSettingsListener = () -> updateState(mPreference);
+    private final int mDeviceState;
+    private final String mDeviceStateDescription;
+    private final MetricsFeatureProvider mMetricsFeatureProvider;
+
+    public DeviceStateAutoRotateSettingController(Context context, int deviceState,
+            String deviceStateDescription, int order) {
+        super(context, getPreferenceKeyForDeviceState(deviceState));
+        mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
+        mDeviceState = deviceState;
+        mDeviceStateDescription = deviceStateDescription;
+        mAutoRotateSettingsManager = DeviceStateRotationLockSettingsManager.getInstance(context);
+        mOrder = order;
+    }
+
+    void init(Lifecycle lifecycle) {
+        lifecycle.addObserver(this);
+    }
+
+    @OnLifecycleEvent(ON_START)
+    void onStart() {
+        mAutoRotateSettingsManager.registerListener(mDeviceStateRotationLockSettingsListener);
+    }
+
+    @OnLifecycleEvent(ON_STOP)
+    void onStop() {
+        mAutoRotateSettingsManager.unregisterListener(mDeviceStateRotationLockSettingsListener);
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        mPreference = new SwitchPreference(mContext);
+        mPreference.setTitle(mDeviceStateDescription);
+        mPreference.setKey(getPreferenceKey());
+        mPreference.setOrder(mOrder);
+        screen.addPreference(mPreference);
+        super.displayPreference(screen);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return DeviceStateAutoRotationHelper.isDeviceStateRotationEnabled(mContext)
+                ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return getPreferenceKeyForDeviceState(mDeviceState);
+    }
+
+    private static String getPreferenceKeyForDeviceState(int deviceState) {
+        return "auto_rotate_device_state_" + deviceState;
+    }
+
+    @Override
+    public boolean isChecked() {
+        return !mAutoRotateSettingsManager.isRotationLocked(mDeviceState);
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        boolean isRotationLocked = !isChecked;
+        mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_ROTATION_LOCK,
+                isRotationLocked);
+        mAutoRotateSettingsManager.updateSetting(mDeviceState, isRotationLocked);
+        return true;
+    }
+
+    @Override
+    public void updateRawDataToIndex(List<SearchIndexableRaw> rawData) {
+        SearchIndexableRaw indexable = new SearchIndexableRaw(mContext);
+        indexable.key = getPreferenceKey();
+        indexable.title = mDeviceStateDescription;
+        // Maybe pass screen title as param?
+        indexable.screenTitle = mContext.getString(R.string.accelerometer_title);
+        rawData.add(indexable);
+    }
+
+    @Override
+    public int getSliceHighlightMenuRes() {
+        return R.string.menu_key_display;
+    }
+
+    @Override
+    public boolean isSliceable() {
+        return true; // Maybe set to false if in accessibility settings screen
+    }
+
+    @Override
+    public boolean isPublicSlice() {
+        return true;
+    }
+}
diff --git a/src/com/android/settings/display/DeviceStateAutoRotationHelper.java b/src/com/android/settings/display/DeviceStateAutoRotationHelper.java
new file mode 100644
index 0000000..223ef1a
--- /dev/null
+++ b/src/com/android/settings/display/DeviceStateAutoRotationHelper.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.display;
+
+import android.content.Context;
+import android.util.Log;
+
+import androidx.lifecycle.Lifecycle;
+
+import com.android.internal.view.RotationPolicy;
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
+import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager.SettableDeviceState;
+import com.android.settingslib.search.SearchIndexableRaw;
+
+import com.google.common.collect.ImmutableList;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Helper class with utility methods related to device state auto-rotation that can be used in
+ * auto-rotation settings fragments and controllers.
+ */
+public class DeviceStateAutoRotationHelper {
+
+    private static final String TAG = "DeviceStateAutoRotHelpr";
+
+    static void initControllers(Lifecycle lifecycle,
+            List<DeviceStateAutoRotateSettingController> controllers) {
+        for (DeviceStateAutoRotateSettingController controller : controllers) {
+            controller.init(lifecycle);
+        }
+    }
+
+    static ImmutableList<AbstractPreferenceController> createPreferenceControllers(
+            Context context) {
+        List<SettableDeviceState> settableDeviceStates = DeviceStateRotationLockSettingsManager
+                .getInstance(context).getSettableDeviceStates();
+        int numDeviceStates = settableDeviceStates.size();
+        if (numDeviceStates == 0) {
+            return ImmutableList.of();
+        }
+        String[] deviceStateSettingDescriptions = context.getResources().getStringArray(
+                R.array.config_settableAutoRotationDeviceStatesDescriptions);
+        if (numDeviceStates != deviceStateSettingDescriptions.length) {
+            Log.wtf(TAG,
+                    "Mismatch between number of device states and device states descriptions.");
+            return ImmutableList.of();
+        }
+
+        ImmutableList.Builder<AbstractPreferenceController> controllers =
+                ImmutableList.builderWithExpectedSize(numDeviceStates);
+        for (int i = 0; i < numDeviceStates; i++) {
+            SettableDeviceState settableDeviceState = settableDeviceStates.get(i);
+            if (!settableDeviceState.isSettable()) {
+                continue;
+            }
+            // Preferences with a lower order will be showed first. Here we go below 0 to make sure
+            // we are shown before statically declared preferences in XML.
+            int order = -numDeviceStates + i;
+            controllers.add(new DeviceStateAutoRotateSettingController(
+                    context,
+                    settableDeviceState.getDeviceState(),
+                    deviceStateSettingDescriptions[i],
+                    order
+            ));
+        }
+        return controllers.build();
+    }
+
+    static List<SearchIndexableRaw> getRawDataToIndex(
+            Context context, boolean enabled) {
+        // Check what the "enabled" param is for
+        List<AbstractPreferenceController> controllers = createPreferenceControllers(context);
+        List<SearchIndexableRaw> rawData = new ArrayList<>();
+        for (AbstractPreferenceController controller : controllers) {
+            ((BasePreferenceController) controller).updateRawDataToIndex(rawData);
+        }
+        return rawData;
+    }
+
+    /** Returns whether the device state based auto-rotation settings are enabled. */
+    public static boolean isDeviceStateRotationEnabled(Context context) {
+        return RotationPolicy.isRotationLockToggleVisible(context)
+                && DeviceStateRotationLockSettingsManager.isDeviceStateRotationLockEnabled(context);
+    }
+
+    /**
+     * Returns whether the device state based auto-rotation settings are enabled for the
+     * accessibility settings page.
+     */
+    public static boolean isDeviceStateRotationEnabledForA11y(Context context) {
+        return RotationPolicy.isRotationSupported(context)
+                && DeviceStateRotationLockSettingsManager.isDeviceStateRotationLockEnabled(context);
+    }
+}
diff --git a/src/com/android/settings/display/PreviewPagerAdapter.java b/src/com/android/settings/display/PreviewPagerAdapter.java
index 018be32..693d574 100644
--- a/src/com/android/settings/display/PreviewPagerAdapter.java
+++ b/src/com/android/settings/display/PreviewPagerAdapter.java
@@ -117,7 +117,15 @@
         mAnimationEndAction = action;
     }
 
-    void setPreviewLayer(int newLayerIndex, int currentLayerIndex, int currentFrameIndex,
+    /**
+     * Switches the sample layouts for the preview pager.
+     *
+     * @param newLayerIndex the new layer index
+     * @param currentLayerIndex the current layer index
+     * @param currentFrameIndex the current frame index
+     * @param animate whether to enable the animation
+     */
+    public void setPreviewLayer(int newLayerIndex, int currentLayerIndex, int currentFrameIndex,
             final boolean animate) {
         for (FrameLayout previewFrame : mPreviewFrames) {
             if (currentLayerIndex >= 0) {
diff --git a/src/com/android/settings/display/SmartAutoRotateController.java b/src/com/android/settings/display/SmartAutoRotateController.java
index 76a222a..d29a64e 100644
--- a/src/com/android/settings/display/SmartAutoRotateController.java
+++ b/src/com/android/settings/display/SmartAutoRotateController.java
@@ -47,6 +47,7 @@
 import com.android.settings.core.TogglePreferenceController;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
 
 /**
  * SmartAutoRotateController controls whether auto rotation is enabled
@@ -54,6 +55,8 @@
 public class SmartAutoRotateController extends TogglePreferenceController implements
         Preference.OnPreferenceChangeListener, LifecycleObserver {
 
+    protected Preference mPreference;
+
     private final MetricsFeatureProvider mMetricsFeatureProvider;
     private final SensorPrivacyManager mPrivacyManager;
     private final PowerManager mPowerManager;
@@ -63,7 +66,9 @@
             updateState(mPreference);
         }
     };
-    protected Preference mPreference;
+    private final DeviceStateRotationLockSettingsManager mDeviceStateAutoRotateSettingsManager;
+    private final DeviceStateRotationLockSettingsManager.DeviceStateRotationLockSettingsListener
+            mDeviceStateRotationLockSettingsListener = () -> updateState(mPreference);
     private RotationPolicy.RotationPolicyListener mRotationPolicyListener;
 
     public SmartAutoRotateController(Context context, String preferenceKey) {
@@ -73,6 +78,8 @@
         mPrivacyManager
                 .addSensorPrivacyListener(CAMERA, (sensor, enabled) -> updateState(mPreference));
         mPowerManager = context.getSystemService(PowerManager.class);
+        mDeviceStateAutoRotateSettingsManager = DeviceStateRotationLockSettingsManager.getInstance(
+                context);
     }
 
     public void init(Lifecycle lifecycle) {
@@ -89,6 +96,9 @@
     }
 
     protected boolean isRotationLocked() {
+        if (DeviceStateAutoRotationHelper.isDeviceStateRotationEnabled(mContext)) {
+            return mDeviceStateAutoRotateSettingsManager.isRotationLockedForAllStates();
+        }
         return RotationPolicy.isRotationLocked(mContext);
     }
 
@@ -127,6 +137,8 @@
             };
         }
         RotationPolicy.registerRotationPolicyListener(mContext, mRotationPolicyListener);
+        mDeviceStateAutoRotateSettingsManager.registerListener(
+                mDeviceStateRotationLockSettingsListener);
     }
 
     @OnLifecycleEvent(ON_STOP)
@@ -136,6 +148,8 @@
             RotationPolicy.unregisterRotationPolicyListener(mContext, mRotationPolicyListener);
             mRotationPolicyListener = null;
         }
+        mDeviceStateAutoRotateSettingsManager.unregisterListener(
+                mDeviceStateRotationLockSettingsListener);
     }
 
     @Override
diff --git a/src/com/android/settings/display/SmartAutoRotatePreferenceController.java b/src/com/android/settings/display/SmartAutoRotatePreferenceController.java
index bd8ee84..d02e336 100644
--- a/src/com/android/settings/display/SmartAutoRotatePreferenceController.java
+++ b/src/com/android/settings/display/SmartAutoRotatePreferenceController.java
@@ -77,6 +77,7 @@
     @Override
     public int getAvailabilityStatus() {
         return RotationPolicy.isRotationLockToggleVisible(mContext)
+                && !DeviceStateAutoRotationHelper.isDeviceStateRotationEnabled(mContext)
                 ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
     }
 
diff --git a/src/com/android/settings/display/SmartAutoRotatePreferenceFragment.java b/src/com/android/settings/display/SmartAutoRotatePreferenceFragment.java
index 4737336..9fda03c 100644
--- a/src/com/android/settings/display/SmartAutoRotatePreferenceFragment.java
+++ b/src/com/android/settings/display/SmartAutoRotatePreferenceFragment.java
@@ -34,10 +34,14 @@
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.widget.SettingsMainSwitchBar;
+import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.search.Indexable;
 import com.android.settingslib.search.SearchIndexable;
+import com.android.settingslib.search.SearchIndexableRaw;
 import com.android.settingslib.widget.FooterPreference;
 
+import java.util.List;
+
 /**
  * Preference fragment used for auto rotation
  */
@@ -60,6 +64,15 @@
     public void onAttach(Context context) {
         super.onAttach(context);
         use(SmartAutoRotateController.class).init(getLifecycle());
+        DeviceStateAutoRotationHelper.initControllers(
+                getLifecycle(),
+                useAll(DeviceStateAutoRotateSettingController.class)
+        );
+    }
+
+    @Override
+    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+        return DeviceStateAutoRotationHelper.createPreferenceControllers(context);
     }
 
     @Override
@@ -79,7 +92,9 @@
 
     @VisibleForTesting
     void createHeader(SettingsActivity activity) {
-        if (isRotationResolverServiceAvailable(activity)) {
+        boolean deviceStateRotationEnabled =
+                DeviceStateAutoRotationHelper.isDeviceStateRotationEnabled(activity);
+        if (isRotationResolverServiceAvailable(activity) && !deviceStateRotationEnabled) {
             final SettingsMainSwitchBar switchBar = activity.getSwitchBar();
             switchBar.setTitle(
                     getContext().getString(R.string.auto_rotate_settings_primary_switch_title));
@@ -127,5 +142,12 @@
     }
 
     public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider(R.xml.auto_rotate_settings);
+            new BaseSearchIndexProvider(R.xml.auto_rotate_settings) {
+
+                @Override
+                public List<SearchIndexableRaw> getRawDataToIndex(
+                        Context context, boolean enabled) {
+                    return DeviceStateAutoRotationHelper.getRawDataToIndex(context, enabled);
+                }
+            };
 }
diff --git a/src/com/android/settings/dream/AutoFitGridLayoutManager.java b/src/com/android/settings/dream/AutoFitGridLayoutManager.java
index 0e5d3e1..7de0eae 100644
--- a/src/com/android/settings/dream/AutoFitGridLayoutManager.java
+++ b/src/com/android/settings/dream/AutoFitGridLayoutManager.java
@@ -24,10 +24,10 @@
 import com.android.settings.R;
 
 /** Grid layout manager that calculates the number of columns for the screen size. */
-final class AutoFitGridLayoutManager extends GridLayoutManager {
+public final class AutoFitGridLayoutManager extends GridLayoutManager {
     private final float mColumnWidth;
 
-    AutoFitGridLayoutManager(Context context) {
+    public AutoFitGridLayoutManager(Context context) {
         super(context, /* spanCount= */ 1);
         this.mColumnWidth = context
                 .getResources()
diff --git a/src/com/android/settings/dream/DreamAdapter.java b/src/com/android/settings/dream/DreamAdapter.java
index e674546..8d0e9d5 100644
--- a/src/com/android/settings/dream/DreamAdapter.java
+++ b/src/com/android/settings/dream/DreamAdapter.java
@@ -37,7 +37,7 @@
 /**
  * RecyclerView adapter which displays list of items for the user to select.
  */
-class DreamAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
+public class DreamAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
     private final List<IDreamItem> mItemList;
     private int mLastSelectedPos = -1;
 
@@ -103,7 +103,7 @@
         }
     }
 
-    DreamAdapter(List<IDreamItem> itemList) {
+    public DreamAdapter(List<IDreamItem> itemList) {
         mItemList = itemList;
     }
 
diff --git a/src/com/android/settings/dream/DreamPickerController.java b/src/com/android/settings/dream/DreamPickerController.java
index e4081ac..6d5463c 100644
--- a/src/com/android/settings/dream/DreamPickerController.java
+++ b/src/com/android/settings/dream/DreamPickerController.java
@@ -19,8 +19,6 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.graphics.drawable.Drawable;
-import android.view.View;
-import android.widget.Button;
 
 import androidx.annotation.Nullable;
 import androidx.preference.Preference;
@@ -46,7 +44,6 @@
     private final DreamBackend mBackend;
     private final MetricsFeatureProvider mMetricsFeatureProvider;
     private final List<DreamInfo> mDreamInfos;
-    private Button mPreviewButton;
     @Nullable
     private DreamInfo mActiveDream;
     private DreamAdapter mAdapter;
@@ -86,17 +83,6 @@
         recyclerView.setLayoutManager(new AutoFitGridLayoutManager(mContext));
         recyclerView.setHasFixedSize(true);
         recyclerView.setAdapter(mAdapter);
-
-        mPreviewButton = ((LayoutPreference) preference).findViewById(R.id.preview_button);
-        mPreviewButton.setVisibility(View.VISIBLE);
-        mPreviewButton.setOnClickListener(v -> mBackend.preview(mActiveDream));
-        updatePreviewButtonState();
-    }
-
-    private void updatePreviewButtonState() {
-        final boolean hasDream = mActiveDream != null;
-        mPreviewButton.setClickable(hasDream);
-        mPreviewButton.setEnabled(hasDream);
     }
 
     @Nullable
@@ -129,7 +115,6 @@
         public void onItemClicked() {
             mActiveDream = mDreamInfo;
             mBackend.setActiveDream(mDreamInfo.componentName);
-            updatePreviewButtonState();
             mMetricsFeatureProvider.action(
                     mContext,
                     SettingsEnums.ACTION_DREAM_SELECT_TYPE,
diff --git a/src/com/android/settings/dream/DreamSettings.java b/src/com/android/settings/dream/DreamSettings.java
index 7ae364e..2acce07 100644
--- a/src/com/android/settings/dream/DreamSettings.java
+++ b/src/com/android/settings/dream/DreamSettings.java
@@ -23,8 +23,13 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+import android.widget.Button;
 
 import androidx.annotation.VisibleForTesting;
+import androidx.recyclerview.widget.RecyclerView;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
@@ -144,6 +149,25 @@
         return controllers;
     }
 
+    @Override
+    public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent,
+            Bundle bundle) {
+
+        final ViewGroup root = getActivity().findViewById(android.R.id.content);
+        final Button previewButton = (Button) getActivity().getLayoutInflater().inflate(
+                R.layout.dream_preview_button, root, false);
+        root.addView(previewButton);
+
+        final DreamBackend dreamBackend = DreamBackend.getInstance(getContext());
+        previewButton.setOnClickListener(v -> dreamBackend.preview(dreamBackend.getActiveDream()));
+
+        final RecyclerView recyclerView = super.onCreateRecyclerView(inflater, parent, bundle);
+        previewButton.post(() -> {
+            recyclerView.setPadding(0, 0, 0, previewButton.getMeasuredHeight());
+        });
+        return recyclerView;
+    }
+
     public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER
             = new BaseSearchIndexProvider(R.xml.dream_fragment_overview) {
 
diff --git a/src/com/android/settings/dream/DreamSetupActivity.java b/src/com/android/settings/dream/DreamSetupActivity.java
deleted file mode 100644
index 6a12671..0000000
--- a/src/com/android/settings/dream/DreamSetupActivity.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2022 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.dream;
-
-import android.app.settings.SettingsEnums;
-import android.content.Intent;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settingslib.dream.DreamBackend;
-
-import com.google.android.setupcompat.template.FooterBarMixin;
-import com.google.android.setupcompat.template.FooterButton;
-import com.google.android.setupcompat.util.WizardManagerHelper;
-import com.google.android.setupdesign.GlifLayout;
-import com.google.android.setupdesign.util.ThemeHelper;
-import com.google.android.setupdesign.util.ThemeResolver;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * The setup activity for dreams which is displayed during setup wizard.
- */
-public class DreamSetupActivity extends SettingsActivity {
-    @Override
-    public Intent getIntent() {
-        Intent modIntent = new Intent(super.getIntent());
-        modIntent.putExtra(EXTRA_SHOW_FRAGMENT, DreamSetupFragment.class.getName());
-        return modIntent;
-    }
-
-    @Override
-    protected boolean isValidFragment(String fragmentName) {
-        return DreamSetupFragment.class.getName().equals(fragmentName);
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstance) {
-        setTheme(ThemeResolver.getDefault().resolve(getIntent()));
-        ThemeHelper.trySetDynamicColor(this);
-        super.onCreate(savedInstance);
-    }
-
-    @Override
-    protected boolean isToolbarEnabled() {
-        return false;
-    }
-
-    /**
-     * Fragment used to control the active dream.
-     */
-    public static class DreamSetupFragment extends SettingsPreferenceFragment {
-        private DreamBackend mBackend;
-        private DreamBackend.DreamInfo mActiveDream;
-        private FooterButton mFooterButton;
-
-        @Override
-        public int getMetricsCategory() {
-            return SettingsEnums.DREAM;
-        }
-
-        @Override
-        public View onCreateView(LayoutInflater inflater, ViewGroup container,
-                Bundle savedInstanceState) {
-            return inflater.inflate(R.layout.dream_setup_layout, container, false);
-        }
-
-        @Override
-        public void onViewCreated(View view, Bundle savedInstanceState) {
-            super.onViewCreated(view, savedInstanceState);
-
-            mBackend = DreamBackend.getInstance(getContext());
-            final List<DreamBackend.DreamInfo> dreamInfos = mBackend.getDreamInfos();
-            mActiveDream = dreamInfos.stream().filter(d -> d.isActive).findFirst().orElse(null);
-            DreamAdapter dreamAdapter = new DreamAdapter(dreamInfos.stream()
-                    .map(DreamItem::new)
-                    .collect(Collectors.toList()));
-
-            final RecyclerView recyclerView = view.findViewById(R.id.dream_setup_list);
-            recyclerView.setLayoutManager(new AutoFitGridLayoutManager(getContext()));
-            recyclerView.setHasFixedSize(true);
-            recyclerView.setAdapter(dreamAdapter);
-
-            final GlifLayout layout = view.findViewById(R.id.setup_wizard_layout);
-            final FooterBarMixin mixin = layout.getMixin(FooterBarMixin.class);
-            mFooterButton = new FooterButton.Builder(getContext())
-                    .setListener(this::onPrimaryButtonClicked)
-                    .setButtonType(FooterButton.ButtonType.NEXT)
-                    .setTheme(R.style.SudGlifButton_Primary)
-                    .build();
-            updateFooterButtonText();
-            mixin.setPrimaryButton(mFooterButton);
-        }
-
-        private void updateFooterButtonText() {
-            final int res = canCustomizeDream() ? R.string.wizard_next : R.string.wizard_finish;
-            mFooterButton.setText(getContext().getString(res));
-        }
-
-        private boolean canCustomizeDream() {
-            return mActiveDream != null && mActiveDream.settingsComponentName != null;
-        }
-
-        private void onPrimaryButtonClicked(View view) {
-            if (canCustomizeDream()) {
-                final Intent intent = new Intent().setComponent(mActiveDream.settingsComponentName);
-                WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent);
-                startActivity(intent);
-            }
-
-            // Use RESULT_CANCELED here so that the user may go back and change this if they wish.
-            setResult(RESULT_CANCELED);
-            finish();
-        }
-
-        private class DreamItem implements IDreamItem {
-            private final DreamBackend.DreamInfo mDreamInfo;
-
-            private DreamItem(DreamBackend.DreamInfo dreamInfo) {
-                mDreamInfo = dreamInfo;
-            }
-
-            @Override
-            public CharSequence getTitle() {
-                return mDreamInfo.caption;
-            }
-
-            @Override
-            public Drawable getIcon() {
-                return mDreamInfo.icon;
-            }
-
-            @Override
-            public void onItemClicked() {
-                mActiveDream = mDreamInfo;
-                mBackend.setActiveDream(mDreamInfo.componentName);
-                updateFooterButtonText();
-            }
-
-            @Override
-            public Drawable getPreviewImage() {
-                return mDreamInfo.previewImage;
-            }
-
-            @Override
-            public boolean isActive() {
-                if (mActiveDream == null) {
-                    return false;
-                }
-                return mDreamInfo.componentName.equals(mActiveDream.componentName);
-            }
-        }
-    }
-}
diff --git a/src/com/android/settings/dream/IDreamItem.java b/src/com/android/settings/dream/IDreamItem.java
index 6652857..c462fe2 100644
--- a/src/com/android/settings/dream/IDreamItem.java
+++ b/src/com/android/settings/dream/IDreamItem.java
@@ -18,7 +18,10 @@
 
 import android.graphics.drawable.Drawable;
 
-interface IDreamItem {
+/**
+ * Interface representing a dream item to be displayed.
+ */
+public interface IDreamItem {
     CharSequence getTitle();
 
     Drawable getIcon();
diff --git a/src/com/android/settings/dream/OWNERS b/src/com/android/settings/dream/OWNERS
new file mode 100644
index 0000000..56e1b39
--- /dev/null
+++ b/src/com/android/settings/dream/OWNERS
@@ -0,0 +1 @@
+lusilva@google.com
\ No newline at end of file
diff --git a/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java b/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java
index 8bef708..94415a1 100644
--- a/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java
+++ b/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java
@@ -68,16 +68,35 @@
     public void onAttach(Context context) {
         super.onAttach(context);
         final int profileType = getArguments().getInt(ProfileSelectFragment.EXTRA_PROFILE);
-        if (profileType == ProfileSelectFragment.ProfileType.WORK) {
-            final UserManager userManager = UserManager.get(context);
-            final UserHandle workUser = Utils.getManagedProfile(userManager);
-            // get work userId
-            mUserId = Utils.getManagedProfileId(userManager, UserHandle.myUserId());
-            mUserAwareContext = context.createContextAsUser(workUser, 0);
-        } else {
-            mUserId = UserHandle.myUserId();
-            mUserAwareContext = context;
+        final UserManager userManager = context.getSystemService(UserManager.class);
+        final int currentUserId = UserHandle.myUserId();
+        final int newUserId;
+        final Context newUserAwareContext;
+        switch (profileType) {
+            case ProfileSelectFragment.ProfileType.WORK: {
+                final UserHandle workUser;
+                if (currentUserId == UserHandle.MIN_SECONDARY_USER_ID) {
+                    newUserId = currentUserId;
+                    workUser = UserHandle.of(currentUserId);
+                } else {
+                    newUserId = Utils.getManagedProfileId(userManager, currentUserId);
+                    workUser = Utils.getManagedProfile(userManager);
+                }
+                newUserAwareContext = context.createContextAsUser(workUser, 0);
+                break;
+            }
+            case ProfileSelectFragment.ProfileType.PERSONAL: {
+                final UserHandle primaryUser = userManager.getPrimaryUser().getUserHandle();
+                newUserId = primaryUser.getIdentifier();
+                newUserAwareContext = context.createContextAsUser(primaryUser, 0);
+                break;
+            }
+            default:
+                newUserId = currentUserId;
+                newUserAwareContext = context;
         }
+        mUserId = newUserId;
+        mUserAwareContext = newUserAwareContext;
     }
 
     @Override
@@ -140,7 +159,7 @@
             // allowed by organization. Doing so will allow the user to disable the input method and
             // remain complaint with the organization's policy. Once disabled, the input method
             // cannot be re-enabled because it is not in the permitted list.
-            final boolean isAllowedByOrganization = permittedList.isEmpty()
+            final boolean isAllowedByOrganization = permittedList == null
                     || permittedList.contains(imi.getPackageName())
                     || enabledImis.contains(imi);
             final InputMethodPreference pref = new InputMethodPreference(prefContext, imi,
diff --git a/src/com/android/settings/applications/assist/DefaultVoiceInputPicker.java b/src/com/android/settings/language/DefaultVoiceInputPicker.java
similarity index 85%
rename from src/com/android/settings/applications/assist/DefaultVoiceInputPicker.java
rename to src/com/android/settings/language/DefaultVoiceInputPicker.java
index d4ea4a9..8a73fdf 100644
--- a/src/com/android/settings/applications/assist/DefaultVoiceInputPicker.java
+++ b/src/com/android/settings/language/DefaultVoiceInputPicker.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settings.applications.assist;
+package com.android.settings.language;
 
 import android.app.settings.SettingsEnums;
 import android.content.ComponentName;
@@ -31,6 +31,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+/** Controls the Voice Input setting. */
 public class DefaultVoiceInputPicker extends DefaultAppPickerFragment {
 
     private VoiceInputHelper mHelper;
@@ -76,7 +77,7 @@
     @Override
     protected boolean setDefaultKey(String value) {
         for (VoiceInputHelper.RecognizerInfo info : mHelper.mAvailableRecognizerInfos) {
-            if (TextUtils.equals(value, info.key)) {
+            if (TextUtils.equals(value, info.mKey)) {
                 Settings.Secure.putString(getContext().getContentResolver(),
                         Settings.Secure.VOICE_RECOGNITION_SERVICE, value);
                 return true;
@@ -85,35 +86,38 @@
         return true;
     }
 
+    /** Gets the current recognition service component. */
     public static ComponentName getCurrentService(VoiceInputHelper helper) {
         return helper.mCurrentRecognizer;
     }
 
+    /** Stores the info of the Voice Input provider. */
     public static class VoiceInputDefaultAppInfo extends DefaultAppInfo {
 
         public VoiceInputHelper.BaseInfo mInfo;
 
         public VoiceInputDefaultAppInfo(Context context, PackageManager pm, int userId,
                 VoiceInputHelper.BaseInfo info, boolean enabled) {
-            super(context, pm, userId, info.componentName, null /* summary */, enabled);
+            super(context, pm, userId, info.mComponentName, null /* summary */, enabled);
             mInfo = info;
         }
 
         @Override
         public String getKey() {
-            return mInfo.key;
+            return mInfo.mKey;
         }
 
         @Override
         public CharSequence loadLabel() {
-            return mInfo.label;
+            return mInfo.mLabel;
         }
 
+        /** Gets the setting intent. */
         public Intent getSettingIntent() {
-            if (mInfo.settings == null) {
+            if (mInfo.mSettings == null) {
                 return null;
             }
-            return new Intent(Intent.ACTION_MAIN).setComponent(mInfo.settings);
+            return new Intent(Intent.ACTION_MAIN).setComponent(mInfo.mSettings);
         }
     }
 }
diff --git a/src/com/android/settings/applications/assist/DefaultVoiceInputPreferenceController.java b/src/com/android/settings/language/DefaultVoiceInputPreferenceController.java
similarity index 94%
rename from src/com/android/settings/applications/assist/DefaultVoiceInputPreferenceController.java
rename to src/com/android/settings/language/DefaultVoiceInputPreferenceController.java
index 59f5731..74c156c 100644
--- a/src/com/android/settings/applications/assist/DefaultVoiceInputPreferenceController.java
+++ b/src/com/android/settings/language/DefaultVoiceInputPreferenceController.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,13 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.settings.applications.assist;
+package com.android.settings.language;
 
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.net.Uri;
 import android.text.TextUtils;
 
 import androidx.preference.Preference;
@@ -33,8 +32,7 @@
 import com.android.settingslib.core.lifecycle.events.OnPause;
 import com.android.settingslib.core.lifecycle.events.OnResume;
 
-import java.util.List;
-
+/** Controller of the Voice Input preference. */
 public class DefaultVoiceInputPreferenceController extends DefaultAppPreferenceController
         implements LifecycleObserver, OnResume, OnPause {
 
@@ -95,7 +93,7 @@
         }
 
         for (VoiceInputHelper.RecognizerInfo info : mHelper.mAvailableRecognizerInfos) {
-            if (TextUtils.equals(defaultKey, info.key)) {
+            if (TextUtils.equals(defaultKey, info.mKey)) {
                 return new DefaultVoiceInputPicker.VoiceInputDefaultAppInfo(mContext,
                         mPackageManager, mUserId, info, true /* enabled */);
             }
diff --git a/src/com/android/settings/language/LanguageAndInputSettings.java b/src/com/android/settings/language/LanguageAndInputSettings.java
index 58c082b..23e37ba 100644
--- a/src/com/android/settings/language/LanguageAndInputSettings.java
+++ b/src/com/android/settings/language/LanguageAndInputSettings.java
@@ -47,8 +47,9 @@
     private static final String TAG = "LangAndInputSettings";
 
     private static final String KEY_KEYBOARDS_CATEGORY = "keyboards_category";
+    private static final String KEY_SPEECH_CATEGORY = "speech_category";
     private static final String KEY_TEXT_TO_SPEECH = "tts_settings_summary";
-    private static final String KEY_POINTER_AND_TTS_CATEGORY = "pointer_and_tts_category";
+    private static final String KEY_POINTER_CATEGORY = "pointer_category";
 
     @Override
     public int getMetricsCategory() {
@@ -109,15 +110,22 @@
                 Arrays.asList(virtualKeyboardPreferenceController,
                         physicalKeyboardPreferenceController)));
 
-        // Pointer and Tts
+        // Speech
+        final DefaultVoiceInputPreferenceController defaultVoiceInputPreferenceController =
+                new DefaultVoiceInputPreferenceController(context, lifecycle);
         final TtsPreferenceController ttsPreferenceController =
                 new TtsPreferenceController(context, KEY_TEXT_TO_SPEECH);
+        controllers.add(defaultVoiceInputPreferenceController);
         controllers.add(ttsPreferenceController);
+        controllers.add(new PreferenceCategoryController(context,
+                KEY_SPEECH_CATEGORY).setChildren(
+                Arrays.asList(defaultVoiceInputPreferenceController, ttsPreferenceController)));
+
+        // Pointer
         final PointerSpeedController pointerController = new PointerSpeedController(context);
         controllers.add(pointerController);
         controllers.add(new PreferenceCategoryController(context,
-                KEY_POINTER_AND_TTS_CATEGORY).setChildren(
-                Arrays.asList(pointerController, ttsPreferenceController)));
+                KEY_POINTER_CATEGORY).setChildren(Arrays.asList(pointerController)));
 
         // Input Assistance
         controllers.add(new SpellCheckerPreferenceController(context));
diff --git a/src/com/android/settings/applications/assist/VoiceInputHelper.java b/src/com/android/settings/language/VoiceInputHelper.java
similarity index 77%
rename from src/com/android/settings/applications/assist/VoiceInputHelper.java
rename to src/com/android/settings/language/VoiceInputHelper.java
index 285f4f7..7915ba4 100644
--- a/src/com/android/settings/applications/assist/VoiceInputHelper.java
+++ b/src/com/android/settings/language/VoiceInputHelper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settings.applications.assist;
+package com.android.settings.language;
 
 import android.content.ComponentName;
 import android.content.Context;
@@ -39,40 +39,46 @@
 import java.util.Collections;
 import java.util.List;
 
+/** Helper class of the Voice Input setting. */
 public final class VoiceInputHelper {
     static final String TAG = "VoiceInputHelper";
     final Context mContext;
 
     final List<ResolveInfo> mAvailableRecognition;
 
-    // TODO: Remove this superclass as we only have 1 class now (RecognizerInfo).
-    static public class BaseInfo implements Comparable {
-        public final ServiceInfo service;
-        public final ComponentName componentName;
-        public final String key;
-        public final ComponentName settings;
-        public final CharSequence label;
-        public final String labelStr;
-        public final CharSequence appLabel;
+    /**
+     * Base info of the Voice Input provider.
+     *
+     * TODO: Remove this superclass as we only have 1 class now (RecognizerInfo).
+     */
+    public static class BaseInfo implements Comparable<BaseInfo> {
+        public final ServiceInfo mService;
+        public final ComponentName mComponentName;
+        public final String mKey;
+        public final ComponentName mSettings;
+        public final CharSequence mLabel;
+        public final String mLabelStr;
+        public final CharSequence mAppLabel;
 
-        public BaseInfo(PackageManager pm, ServiceInfo _service, String _settings) {
-            service = _service;
-            componentName = new ComponentName(_service.packageName, _service.name);
-            key = componentName.flattenToShortString();
-            settings = _settings != null
-                    ? new ComponentName(_service.packageName, _settings) : null;
-            label = _service.loadLabel(pm);
-            labelStr = label.toString();
-            appLabel = _service.applicationInfo.loadLabel(pm);
+        public BaseInfo(PackageManager pm, ServiceInfo service, String settings) {
+            mService = service;
+            mComponentName = new ComponentName(service.packageName, service.name);
+            mKey = mComponentName.flattenToShortString();
+            mSettings = settings != null
+                    ? new ComponentName(service.packageName, settings) : null;
+            mLabel = service.loadLabel(pm);
+            mLabelStr = mLabel.toString();
+            mAppLabel = service.applicationInfo.loadLabel(pm);
         }
 
         @Override
-        public int compareTo(Object another) {
-            return labelStr.compareTo(((BaseInfo) another).labelStr);
+        public int compareTo(BaseInfo another) {
+            return mLabelStr.compareTo(another.mLabelStr);
         }
     }
 
-    static public class RecognizerInfo extends BaseInfo {
+    /** Info of the speech recognizer (i.e. recognition service). */
+    public static class RecognizerInfo extends BaseInfo {
         public final boolean mSelectableAsDefault;
 
         public RecognizerInfo(PackageManager pm,
@@ -96,6 +102,7 @@
                 PackageManager.GET_META_DATA);
     }
 
+    /** Draws the UI of the Voice Input picker page. */
     public void buildUi() {
         // Get the currently selected recognizer from the secure setting.
         String currentSetting = Settings.Secure.getString(
@@ -120,8 +127,8 @@
             try (XmlResourceParser parser = si.loadXmlMetaData(mContext.getPackageManager(),
                     RecognitionService.SERVICE_META_DATA)) {
                 if (parser == null) {
-                    throw new XmlPullParserException("No " + RecognitionService.SERVICE_META_DATA +
-                            " meta-data for " + si.packageName);
+                    throw new XmlPullParserException("No " + RecognitionService.SERVICE_META_DATA
+                            + " meta-data for " + si.packageName);
                 }
 
                 Resources res = mContext.getPackageManager().getResourcesForApplication(
@@ -132,6 +139,7 @@
                 int type;
                 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                         && type != XmlPullParser.START_TAG) {
+                    // Intentionally do nothing.
                 }
 
                 String nodeName = parser.getName();
diff --git a/src/com/android/settings/location/RecentLocationAccessSeeAllPreferenceController.java b/src/com/android/settings/location/RecentLocationAccessSeeAllPreferenceController.java
index e3379c7..75406f7 100644
--- a/src/com/android/settings/location/RecentLocationAccessSeeAllPreferenceController.java
+++ b/src/com/android/settings/location/RecentLocationAccessSeeAllPreferenceController.java
@@ -27,7 +27,9 @@
 
 import com.android.settings.R;
 import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.applications.RecentAppOpsAccess;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.widget.AppPreference;
 
 import java.util.ArrayList;
@@ -37,8 +39,10 @@
 public class RecentLocationAccessSeeAllPreferenceController
         extends LocationBasePreferenceController {
 
-    private PreferenceScreen mCategoryAllRecentLocationAccess;
     private final RecentAppOpsAccess mRecentLocationAccesses;
+
+    private PreferenceScreen mCategoryAllRecentLocationAccess;
+    private MetricsFeatureProvider mMetricsFeatureProvider;
     private boolean mShowSystem = false;
     private Preference mPreference;
 
@@ -47,6 +51,7 @@
         mShowSystem = Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, 0) == 1;
         mRecentLocationAccesses = RecentAppOpsAccess.createForLocation(context);
+        mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
     }
 
     @Override
@@ -99,6 +104,7 @@
         mShowSystem = showSystem;
         if (mPreference != null) {
             updateState(mPreference);
+            mMetricsFeatureProvider.logClickedPreference(mPreference, getMetricsCategory());
         }
     }
 }
diff --git a/src/com/android/settings/network/PrivateDnsModeDialogPreference.java b/src/com/android/settings/network/PrivateDnsModeDialogPreference.java
index 442af38..5c7c54e 100644
--- a/src/com/android/settings/network/PrivateDnsModeDialogPreference.java
+++ b/src/com/android/settings/network/PrivateDnsModeDialogPreference.java
@@ -97,23 +97,19 @@
 
     public PrivateDnsModeDialogPreference(Context context) {
         super(context);
-        initialize();
     }
 
     public PrivateDnsModeDialogPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
-        initialize();
     }
 
     public PrivateDnsModeDialogPreference(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
-        initialize();
     }
 
     public PrivateDnsModeDialogPreference(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
-        initialize();
     }
 
     private final AnnotationSpan.LinkInfo mUrlLinkInfo = new AnnotationSpan.LinkInfo(
@@ -131,12 +127,6 @@
         }
     });
 
-    private void initialize() {
-        // Add the "Restricted" icon resource so that if the preference is disabled by the
-        // admin, an information button will be shown.
-        setWidgetLayoutResource(R.layout.restricted_icon);
-    }
-
     @Override
     public void onBindViewHolder(PreferenceViewHolder holder) {
         super.onBindViewHolder(holder);
@@ -146,13 +136,6 @@
             // by the controller.
             holder.itemView.setEnabled(true);
         }
-
-        final View restrictedIcon = holder.findViewById(R.id.restricted_icon);
-        if (restrictedIcon != null) {
-            // Show the "Restricted" icon if, and only if, the preference was disabled by
-            // the admin.
-            restrictedIcon.setVisibility(isDisabledByAdmin() ? View.VISIBLE : View.GONE);
-        }
     }
 
     @Override
diff --git a/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java b/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java
index c6d1ea0..0b39d6a 100644
--- a/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java
+++ b/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java
@@ -21,14 +21,13 @@
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.UiccCardInfo;
-import android.telephony.UiccSlotMapping;
 import android.telephony.euicc.EuiccManager;
 import android.util.Log;
 
 import com.android.settings.SidecarFragment;
 import com.android.settings.network.telephony.EuiccOperationSidecar;
 
-import java.util.Collection;
+import java.util.Comparator;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -95,11 +94,11 @@
 
         // To check whether the esim slot's port is active. If yes, skip setSlotMapping. If no,
         // set this slot+port into setSimSlotMapping.
-        mPort = (port < 0) ? getTargetPortId(removedSubInfo, targetSlot) : port;
+        mPort = (port < 0) ? getTargetPortId(removedSubInfo) : port;
         mRemovedSubInfo = removedSubInfo;
         Log.d(TAG,
-                String.format("set esim into the Slot%d SubId%d:Port%d",
-                        targetSlot, mSubId, mPort));
+                String.format("set esim into the SubId%d Slot%d:Port%d",
+                        mSubId, targetSlot, mPort));
 
         if (mTelephonyManager.isMultiSimEnabled() && removedSubInfo != null
                 && removedSubInfo.isEmbedded()) {
@@ -115,7 +114,7 @@
         }
     }
 
-    private int getTargetPortId(SubscriptionInfo removedSubInfo, int targetSlot) {
+    private int getTargetPortId(SubscriptionInfo removedSubInfo) {
         if (!mTelephonyManager.isMultiSimEnabled() || !isMultipleEnabledProfilesSupported()) {
             // In the 'SS mode' or 'DSDS+no MEP', the port is 0.
             return 0;
@@ -128,20 +127,25 @@
         }
 
         // In DSDS+MEP mode, the removedSubInfo is psim or is null, it means this esim needs
-        // another port in the esim slot.
-        // To find another esim's port and value is from 0.
+        // a new corresponding port in the esim slot.
         // For example:
         // 1) If there is no enabled esim and the user add new esim. This new esim's port is 0.
-        // 2) If there is one enabled esim and the user add new esim. This new esim's port is 1.
+        // 2) If there is one enabled esim in port0 and the user add new esim. This new esim's
+        // port is 1.
+        // 3) If there is one enabled esim in port1 and the user add new esim. This new esim's
+        // port is 0.
+
         int port = 0;
-        Collection<UiccSlotMapping> uiccSlotMappings = mTelephonyManager.getSimSlotMapping();
-        for (UiccSlotMapping uiccSlotMapping :
-                uiccSlotMappings.stream()
-                        .filter(
-                                uiccSlotMapping -> uiccSlotMapping.getPhysicalSlotIndex()
-                                        == targetSlot)
-                        .collect(Collectors.toList())) {
-            if (uiccSlotMapping.getPortIndex() == port) {
+        SubscriptionManager subscriptionManager = getContext().getSystemService(
+                SubscriptionManager.class);
+        List<SubscriptionInfo> activeEsimSubInfos =
+                SubscriptionUtil.getActiveSubscriptions(subscriptionManager)
+                        .stream()
+                        .filter(i -> i.isEmbedded())
+                        .sorted(Comparator.comparingInt(SubscriptionInfo::getPortIndex))
+                        .collect(Collectors.toList());
+        for (SubscriptionInfo subscriptionInfo : activeEsimSubInfos) {
+            if (subscriptionInfo.getPortIndex() == port) {
                 port++;
             }
         }
diff --git a/src/com/android/settings/nfc/PaymentDefaultDialog.java b/src/com/android/settings/nfc/PaymentDefaultDialog.java
index a888167..75746ce 100644
--- a/src/com/android/settings/nfc/PaymentDefaultDialog.java
+++ b/src/com/android/settings/nfc/PaymentDefaultDialog.java
@@ -58,7 +58,11 @@
         ComponentName component = intent.getParcelableExtra(
                 CardEmulation.EXTRA_SERVICE_COMPONENT);
         String category = intent.getStringExtra(CardEmulation.EXTRA_CATEGORY);
-        int userId = intent.getIntExtra(CardEmulation.EXTRA_USERID, UserHandle.myUserId());
+        UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER);
+        if (userHandle == null) {
+            userHandle = UserHandle.CURRENT;
+        }
+        int userId = userHandle.getIdentifier();
 
         setResult(RESULT_CANCELED);
         if (!buildDialog(component, category, userId)) {
diff --git a/src/com/android/settings/notification/NotificationLockscreenPreference.java b/src/com/android/settings/notification/NotificationLockscreenPreference.java
deleted file mode 100644
index b236014..0000000
--- a/src/com/android/settings/notification/NotificationLockscreenPreference.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.settings.notification;
-
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.ListView;
-
-import androidx.appcompat.app.AlertDialog;
-import androidx.appcompat.app.AlertDialog.Builder;
-
-import com.android.settings.R;
-import com.android.settings.RestrictedListPreference;
-import com.android.settings.Utils;
-import com.android.settingslib.RestrictedLockUtils;
-
-public class NotificationLockscreenPreference extends RestrictedListPreference {
-
-    private boolean mAllowRemoteInput;
-    private Listener mListener;
-    private boolean mShowRemoteInput;
-    private boolean mRemoteInputCheckBoxEnabled = true;
-    private int mUserId = UserHandle.myUserId();
-    private RestrictedLockUtils.EnforcedAdmin mAdminRestrictingRemoteInput;
-
-    public NotificationLockscreenPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public void setRemoteInputCheckBoxEnabled(boolean enabled) {
-        mRemoteInputCheckBoxEnabled = enabled;
-    }
-
-    public void setRemoteInputRestricted(RestrictedLockUtils.EnforcedAdmin admin) {
-        mAdminRestrictingRemoteInput = admin;
-    }
-
-    @Override
-    protected void onClick() {
-        final Context context = getContext();
-        if (!Utils.startQuietModeDialogIfNecessary(context, UserManager.get(context), mUserId)) {
-            // Call super to create preference dialog only when work mode is on
-            // startQuietModeDialogIfNecessary will return false if mUserId is not a managed user
-            super.onClick();
-        }
-    }
-
-    public void setUserId(int userId) {
-        mUserId = userId;
-    }
-
-    @Override
-    protected void onPrepareDialogBuilder(Builder builder,
-            DialogInterface.OnClickListener innerListener) {
-
-        mListener = new Listener(innerListener);
-        builder.setSingleChoiceItems(createListAdapter(builder.getContext()), getSelectedValuePos(),
-                mListener);
-        mShowRemoteInput = getEntryValues().length == 3;
-        mAllowRemoteInput = Settings.Secure.getInt(getContext().getContentResolver(),
-                Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT, 0) != 0;
-        builder.setView(R.layout.lockscreen_remote_input);
-    }
-
-    @Override
-    protected void onDialogCreated(Dialog dialog) {
-        super.onDialogCreated(dialog);
-        dialog.create();
-        CheckBox checkbox = (CheckBox) dialog.findViewById(R.id.lockscreen_remote_input);
-        checkbox.setChecked(!mAllowRemoteInput);
-        checkbox.setOnCheckedChangeListener(mListener);
-        checkbox.setEnabled(mAdminRestrictingRemoteInput == null);
-
-        View restricted = dialog.findViewById(R.id.restricted_lock_icon_remote_input);
-        restricted.setVisibility(mAdminRestrictingRemoteInput == null ? View.GONE : View.VISIBLE);
-
-        if (mAdminRestrictingRemoteInput != null) {
-            checkbox.setClickable(false);
-            dialog.findViewById(com.android.internal.R.id.customPanel)
-                    .setOnClickListener(mListener);
-        }
-    }
-
-    @Override
-    protected void onDialogStateRestored(Dialog dialog, Bundle savedInstanceState) {
-        super.onDialogStateRestored(dialog, savedInstanceState);
-        ListView listView = ((AlertDialog) dialog).getListView();
-        int selectedPosition = listView.getCheckedItemPosition();
-
-        View panel = dialog.findViewById(com.android.internal.R.id.customPanel);
-        panel.setVisibility(checkboxVisibilityForSelectedIndex(selectedPosition,
-                mShowRemoteInput));
-        mListener.setView(panel);
-    }
-
-    @Override
-    protected void onDialogClosed(boolean positiveResult) {
-        super.onDialogClosed(positiveResult);
-        Settings.Secure.putInt(getContext().getContentResolver(),
-                Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT, mAllowRemoteInput ? 1 : 0);
-    }
-
-    @Override
-    protected boolean isAutoClosePreference() {
-        return false;
-    }
-
-    private int checkboxVisibilityForSelectedIndex(int selected,
-            boolean showRemoteAtAll) {
-        return selected == 1 && showRemoteAtAll && mRemoteInputCheckBoxEnabled ? View.VISIBLE
-                : View.GONE;
-    }
-
-    private class Listener implements DialogInterface.OnClickListener,
-            CompoundButton.OnCheckedChangeListener, View.OnClickListener {
-
-        private final DialogInterface.OnClickListener mInner;
-        private View mView;
-
-        public Listener(DialogInterface.OnClickListener inner) {
-            mInner = inner;
-        }
-
-        @Override
-        public void onClick(DialogInterface dialog, int which) {
-            mInner.onClick(dialog, which);
-            ListView listView = ((AlertDialog) dialog).getListView();
-            int selectedPosition = listView.getCheckedItemPosition();
-            if (mView != null) {
-                mView.setVisibility(
-                        checkboxVisibilityForSelectedIndex(selectedPosition, mShowRemoteInput));
-            }
-        }
-
-        @Override
-        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
-            mAllowRemoteInput = !isChecked;
-        }
-
-        public void setView(View view) {
-            mView = view;
-        }
-
-        @Override
-        public void onClick(View v) {
-            if (v.getId() == com.android.internal.R.id.customPanel) {
-                RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(),
-                        mAdminRestrictingRemoteInput);
-            }
-        }
-    }
-}
diff --git a/src/com/android/settings/notification/OWNERS b/src/com/android/settings/notification/OWNERS
index edf266e..a2ae9ce 100644
--- a/src/com/android/settings/notification/OWNERS
+++ b/src/com/android/settings/notification/OWNERS
@@ -1,4 +1,5 @@
 # Default reviewers for this and subdirectories.
-asc@google.com
+beverlyt@google.com
 dsandler@android.com
-juliacr@google.com
\ No newline at end of file
+juliacr@google.com
+yurilin@google.com
\ No newline at end of file
diff --git a/src/com/android/settings/safetycenter/BiometricsSafetySource.java b/src/com/android/settings/safetycenter/BiometricsSafetySource.java
new file mode 100644
index 0000000..f37ea03
--- /dev/null
+++ b/src/com/android/settings/safetycenter/BiometricsSafetySource.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 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.safetycenter;
+
+import android.content.Context;
+
+/** Combined Biometrics Safety Source for Safety Center. */
+public final class BiometricsSafetySource {
+
+    public static final String SAFETY_SOURCE_ID = "BiometricsSafetySource";
+
+    private BiometricsSafetySource() {}
+
+    /** Sends biometric safety data to Safety Center. */
+    public static void sendSafetyData(Context context) {
+        if (!SafetyCenterStatusHolder.get().isEnabled(context)) {
+            return;
+        }
+
+        // TODO(b/215517420): Send biometric data to Safety Center if there are biometrics available
+        // on this device.
+    }
+}
diff --git a/src/com/android/settings/safetycenter/LockScreenSafetySource.java b/src/com/android/settings/safetycenter/LockScreenSafetySource.java
new file mode 100644
index 0000000..66001f2
--- /dev/null
+++ b/src/com/android/settings/safetycenter/LockScreenSafetySource.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 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.safetycenter;
+
+import android.app.PendingIntent;
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.content.Intent;
+import android.safetycenter.SafetySourceData;
+import android.safetycenter.SafetySourceStatus;
+
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.password.ChooseLockGeneric;
+import com.android.settingslib.transition.SettingsTransitionHelper;
+
+/** Lock Screen Safety Source for Safety Center. */
+public final class LockScreenSafetySource {
+
+    public static final String SAFETY_SOURCE_ID = "LockScreenSafetySource";
+
+    private LockScreenSafetySource() {}
+
+    /** Sends lock screen safety data to Safety Center. */
+    public static void sendSafetyData(Context context) {
+        if (!SafetyCenterStatusHolder.get().isEnabled(context)) {
+            return;
+        }
+
+        // TODO(b/215515298): Replace placeholder SafetySourceData with real data.
+        // TODO(b/217409995): Replace SECURITY_ALTERNATIVE with Safety Center metrics category.
+        Intent clickIntent = new SubSettingLauncher(context)
+                .setDestination(ChooseLockGeneric.ChooseLockGenericFragment.class.getName())
+                .setSourceMetricsCategory(SettingsEnums.SECURITY_ALTERNATIVE)
+                .setTransitionType(SettingsTransitionHelper.TransitionType.TRANSITION_SLIDE)
+                .toIntent();
+        PendingIntent pendingIntent = PendingIntent
+                .getActivity(
+                        context,
+                        0 /* requestCode */,
+                        clickIntent,
+                        PendingIntent.FLAG_IMMUTABLE);
+        SafetySourceData safetySourceData =
+                new SafetySourceData.Builder(SAFETY_SOURCE_ID).setStatus(
+                        new SafetySourceStatus.Builder(
+                                "Lock Screen",
+                                "Lock screen settings",
+                                SafetySourceStatus.STATUS_LEVEL_OK,
+                                pendingIntent).build()
+                ).build();
+
+        SafetyCenterManagerWrapper.get().sendSafetyCenterUpdate(context, safetySourceData);
+    }
+}
diff --git a/src/com/android/settings/safetycenter/SafetyCenterManagerWrapper.java b/src/com/android/settings/safetycenter/SafetyCenterManagerWrapper.java
new file mode 100644
index 0000000..7e47f23
--- /dev/null
+++ b/src/com/android/settings/safetycenter/SafetyCenterManagerWrapper.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 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.safetycenter;
+
+import android.content.Context;
+import android.safetycenter.SafetyCenterManager;
+import android.safetycenter.SafetySourceData;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/** A wrapper for the SafetyCenterManager system service. */
+public class SafetyCenterManagerWrapper {
+
+    private static final String TAG = "SafetyCenterManagerWrapper";
+
+    @VisibleForTesting
+    public static SafetyCenterManagerWrapper sInstance;
+
+    private SafetyCenterManagerWrapper() {}
+
+    /** Returns an instance of {@link SafetyCenterManagerWrapper}. */
+    public static SafetyCenterManagerWrapper get() {
+        if (sInstance == null) {
+            sInstance = new SafetyCenterManagerWrapper();
+        }
+        return sInstance;
+    }
+
+    /** Sends updated safety source data to Safety Center. */
+    public void sendSafetyCenterUpdate(Context context, SafetySourceData safetySourceData) {
+        SafetyCenterManager safetyCenterManager =
+                context.getSystemService(SafetyCenterManager.class);
+
+        if (safetyCenterManager == null) {
+            Log.e(TAG, "System service SAFETY_CENTER_SERVICE (SafetyCenterManager) is null");
+            return;
+        }
+
+        try {
+            safetyCenterManager.sendSafetyCenterUpdate(safetySourceData);
+        } catch (Exception e) {
+            Log.e(TAG, "Failed to send SafetySourceData", e);
+            return;
+        }
+    }
+}
diff --git a/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiver.java b/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiver.java
new file mode 100644
index 0000000..0fd0c0d
--- /dev/null
+++ b/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiver.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 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.safetycenter;
+
+import static android.safetycenter.SafetyCenterManager.EXTRA_REFRESH_SAFETY_SOURCE_IDS;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+import com.google.common.collect.ImmutableList;
+
+/** Broadcast receiver for handling requests from Safety Center for fresh data. */
+public class SafetySourceBroadcastReceiver extends BroadcastReceiver {
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if (!SafetyCenterStatusHolder.get().isEnabled(context)) {
+            return;
+        }
+
+        String[] sourceIdsExtra = intent.getStringArrayExtra(EXTRA_REFRESH_SAFETY_SOURCE_IDS);
+        if (sourceIdsExtra != null && sourceIdsExtra.length > 0) {
+            ImmutableList<String> sourceIds = ImmutableList.copyOf(sourceIdsExtra);
+
+            if (sourceIds.contains(LockScreenSafetySource.SAFETY_SOURCE_ID)) {
+                LockScreenSafetySource.sendSafetyData(context);
+            }
+
+            if (sourceIds.contains(BiometricsSafetySource.SAFETY_SOURCE_ID)) {
+                BiometricsSafetySource.sendSafetyData(context);
+            }
+        }
+    }
+}
diff --git a/src/com/android/settings/security/ChangeScreenLockPreferenceController.java b/src/com/android/settings/security/ChangeScreenLockPreferenceController.java
index 5439fef..4e54238 100644
--- a/src/com/android/settings/security/ChangeScreenLockPreferenceController.java
+++ b/src/com/android/settings/security/ChangeScreenLockPreferenceController.java
@@ -16,40 +16,32 @@
 
 package com.android.settings.security;
 
-import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.os.storage.StorageManager;
 import android.text.TextUtils;
 
 import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 
 import com.android.internal.widget.LockPatternUtils;
-import com.android.settings.R;
 import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.Utils;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.SubSettingLauncher;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.password.ChooseLockGeneric;
-import com.android.settings.security.screenlock.ScreenLockSettings;
 import com.android.settings.widget.GearPreference;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.RestrictedLockUtilsInternal;
 import com.android.settingslib.RestrictedPreference;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
-import com.android.settingslib.transition.SettingsTransitionHelper;
 
 public class ChangeScreenLockPreferenceController extends AbstractPreferenceController implements
         PreferenceControllerMixin, GearPreference.OnGearClickListener {
 
     private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change";
 
-    protected final DevicePolicyManager mDPM;
     protected final SettingsPreferenceFragment mHost;
     protected final UserManager mUm;
     protected final LockPatternUtils mLockPatternUtils;
@@ -57,24 +49,26 @@
     protected final int mUserId = UserHandle.myUserId();
     protected final int mProfileChallengeUserId;
     private final MetricsFeatureProvider mMetricsFeatureProvider;
+    private final ScreenLockPreferenceDetailsUtils mScreenLockPreferenceDetailUtils;
 
     protected RestrictedPreference mPreference;
 
     public ChangeScreenLockPreferenceController(Context context, SettingsPreferenceFragment host) {
         super(context);
         mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
-        mDPM = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
         mLockPatternUtils = FeatureFactory.getFactory(context)
                 .getSecurityFeatureProvider()
                 .getLockPatternUtils(context);
         mHost = host;
         mProfileChallengeUserId = Utils.getManagedProfileId(mUm, mUserId);
         mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
+        mScreenLockPreferenceDetailUtils =
+                new ScreenLockPreferenceDetailsUtils(context, host.getMetricsCategory());
     }
 
     @Override
     public boolean isAvailable() {
-        return mContext.getResources().getBoolean(R.bool.config_show_unlock_set_or_change);
+        return mScreenLockPreferenceDetailUtils.isAvailable();
     }
 
     @Override
@@ -91,7 +85,7 @@
     @Override
     public void updateState(Preference preference) {
         if (mPreference != null && mPreference instanceof GearPreference) {
-            if (mLockPatternUtils.isSecure(mUserId)) {
+            if (mScreenLockPreferenceDetailUtils.shouldShowGearMenu()) {
                 ((GearPreference) mPreference).setOnGearClickListener(this);
             } else {
                 ((GearPreference) mPreference).setOnGearClickListener(null);
@@ -112,10 +106,7 @@
         if (TextUtils.equals(p.getKey(), getPreferenceKey())) {
             mMetricsFeatureProvider.logClickedPreference(p,
                     p.getExtras().getInt(DashboardFragment.CATEGORY));
-            new SubSettingLauncher(mContext)
-                    .setDestination(ScreenLockSettings.class.getName())
-                    .setSourceMetricsCategory(mHost.getMetricsCategory())
-                    .launch();
+            mScreenLockPreferenceDetailUtils.openScreenLockSettings();
         }
     }
 
@@ -124,51 +115,11 @@
         if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
             return super.handlePreferenceTreeClick(preference);
         }
-        // TODO(b/35930129): Remove once existing password can be passed into vold directly.
-        // Currently we need this logic to ensure that the QUIET_MODE is off for any work
-        // profile with unified challenge on FBE-enabled devices. Otherwise, vold would not be
-        // able to complete the operation due to the lack of (old) encryption key.
-        if (mProfileChallengeUserId != UserHandle.USER_NULL
-                && !mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)
-                && StorageManager.isFileEncryptedNativeOnly()) {
-            if (Utils.startQuietModeDialogIfNecessary(mContext, mUm, mProfileChallengeUserId)) {
-                return false;
-            }
-        }
-
-        new SubSettingLauncher(mContext)
-                .setDestination(ChooseLockGeneric.ChooseLockGenericFragment.class.getName())
-                .setSourceMetricsCategory(mHost.getMetricsCategory())
-                .setTransitionType(SettingsTransitionHelper.TransitionType.TRANSITION_SLIDE)
-                .launch();
-        return true;
+        return mScreenLockPreferenceDetailUtils.openChooseLockGenericFragment();
     }
 
     protected void updateSummary(Preference preference, int userId) {
-        if (!mLockPatternUtils.isSecure(userId)) {
-            if (userId == mProfileChallengeUserId
-                    || mLockPatternUtils.isLockScreenDisabled(userId)) {
-                preference.setSummary(R.string.unlock_set_unlock_mode_off);
-            } else {
-                preference.setSummary(R.string.unlock_set_unlock_mode_none);
-            }
-        } else {
-            switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(userId)) {
-                case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
-                    preference.setSummary(R.string.unlock_set_unlock_mode_pattern);
-                    break;
-                case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
-                case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
-                    preference.setSummary(R.string.unlock_set_unlock_mode_pin);
-                    break;
-                case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
-                case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
-                case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
-                case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
-                    preference.setSummary(R.string.unlock_set_unlock_mode_password);
-                    break;
-            }
-        }
+        preference.setSummary(mScreenLockPreferenceDetailUtils.getSummary(userId));
         mPreference.setEnabled(true);
     }
 
@@ -181,10 +132,7 @@
     void disableIfPasswordQualityManaged(int userId) {
         final RestrictedLockUtils.EnforcedAdmin admin = RestrictedLockUtilsInternal
                 .checkIfPasswordQualityIsSet(mContext, userId);
-        final DevicePolicyManager dpm = (DevicePolicyManager) mContext
-                .getSystemService(Context.DEVICE_POLICY_SERVICE);
-        if (admin != null && dpm.getPasswordQuality(admin.component, userId)
-                == DevicePolicyManager.PASSWORD_QUALITY_MANAGED) {
+        if (mScreenLockPreferenceDetailUtils.isPasswordQualityManaged(userId, admin)) {
             mPreference.setDisabledByAdmin(admin);
         }
     }
diff --git a/src/com/android/settings/security/ScreenLockPreferenceDetailsUtils.java b/src/com/android/settings/security/ScreenLockPreferenceDetailsUtils.java
new file mode 100644
index 0000000..abcacf0
--- /dev/null
+++ b/src/com/android/settings/security/ScreenLockPreferenceDetailsUtils.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2022 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 android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.os.storage.StorageManager;
+
+import androidx.annotation.StringRes;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment;
+import com.android.settings.security.screenlock.ScreenLockSettings;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.transition.SettingsTransitionHelper;
+
+/**
+ * Utilities for screen lock details shared between Security Settings and Safety Center.
+ */
+public class ScreenLockPreferenceDetailsUtils {
+
+    private final int mUserId = UserHandle.myUserId();
+    private final Context mContext;
+    private final LockPatternUtils mLockPatternUtils;
+    private final int mProfileChallengeUserId;
+    private final UserManager mUm;
+    private final int mSourceMetricsCategory;
+
+    public ScreenLockPreferenceDetailsUtils(Context context, int sourceMetricsCategory) {
+        mContext = context;
+        mUm = context.getSystemService(UserManager.class);
+        mLockPatternUtils = FeatureFactory.getFactory(context)
+                .getSecurityFeatureProvider()
+                .getLockPatternUtils(context);
+        mProfileChallengeUserId = Utils.getManagedProfileId(mUm, mUserId);
+        mSourceMetricsCategory = sourceMetricsCategory;
+    }
+
+    /**
+     * Returns whether the screen lock settings entity should be shown.
+     */
+    public boolean isAvailable() {
+        return mContext.getResources().getBoolean(R.bool.config_show_unlock_set_or_change);
+    }
+
+    /**
+     * Returns the summary of screen lock settings entity.
+     */
+    public String getSummary(int userId) {
+        final Integer summaryResId = getSummaryResId(userId);
+        return summaryResId != null ? mContext.getResources().getString(summaryResId) : null;
+    }
+
+    /**
+     * Returns whether the password quality is managed by device admin.
+     */
+    public boolean isPasswordQualityManaged(int userId, RestrictedLockUtils.EnforcedAdmin admin) {
+        final DevicePolicyManager dpm = (DevicePolicyManager) mContext
+                .getSystemService(Context.DEVICE_POLICY_SERVICE);
+        return admin != null && dpm.getPasswordQuality(admin.component, userId)
+                == DevicePolicyManager.PASSWORD_QUALITY_MANAGED;
+    }
+
+    /**
+     * Returns whether the Gear Menu should be shown.
+     */
+    public boolean shouldShowGearMenu() {
+        return mLockPatternUtils.isSecure(mUserId);
+    }
+
+    /**
+     * Launches the {@link ScreenLockSettings}.
+     */
+    public void openScreenLockSettings() {
+        new SubSettingLauncher(mContext)
+                .setDestination(ScreenLockSettings.class.getName())
+                .setSourceMetricsCategory(mSourceMetricsCategory)
+                .launch();
+    }
+
+    /**
+     * Tries to launch the {@link ChooseLockGenericFragment} if Quiet Mode is not enabled
+     * for managed profile, otherwise shows a dialog to disable the Quiet Mode.
+     *
+     * @return true if the {@link ChooseLockGenericFragment} is launching.
+     */
+    public boolean openChooseLockGenericFragment() {
+        // TODO(b/35930129): Remove once existing password can be passed into vold directly.
+        // Currently we need this logic to ensure that the QUIET_MODE is off for any work
+        // profile with unified challenge on FBE-enabled devices. Otherwise, vold would not be
+        // able to complete the operation due to the lack of (old) encryption key.
+        if (mProfileChallengeUserId != UserHandle.USER_NULL
+                && !mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)
+                && StorageManager.isFileEncryptedNativeOnly()) {
+            if (Utils.startQuietModeDialogIfNecessary(mContext, mUm, mProfileChallengeUserId)) {
+                return false;
+            }
+        }
+
+        new SubSettingLauncher(mContext)
+                .setDestination(ChooseLockGenericFragment.class.getName())
+                .setSourceMetricsCategory(mSourceMetricsCategory)
+                .setTransitionType(SettingsTransitionHelper.TransitionType.TRANSITION_SLIDE)
+                .launch();
+        return true;
+    }
+
+    @StringRes
+    private Integer getSummaryResId(int userId) {
+        if (!mLockPatternUtils.isSecure(userId)) {
+            if (userId == mProfileChallengeUserId
+                    || mLockPatternUtils.isLockScreenDisabled(userId)) {
+                return R.string.unlock_set_unlock_mode_off;
+            } else {
+                return R.string.unlock_set_unlock_mode_none;
+            }
+        } else {
+            int keyguardStoredPasswordQuality =
+                    mLockPatternUtils.getKeyguardStoredPasswordQuality(userId);
+            switch (keyguardStoredPasswordQuality) {
+                case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
+                    return R.string.unlock_set_unlock_mode_pattern;
+                case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
+                case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
+                    return R.string.unlock_set_unlock_mode_pin;
+                case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
+                case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
+                case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
+                case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
+                    return R.string.unlock_set_unlock_mode_password;
+                default:
+                    return null;
+            }
+        }
+    }
+}
diff --git a/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java b/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java
index 2f8d58d..49f94c8 100644
--- a/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java
+++ b/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java
@@ -32,14 +32,12 @@
     private static final int MY_USER_ID = UserHandle.myUserId();
 
     private final LockPatternUtils mLockPatternUtils;
-    private TrustAgentManager mTrustAgentManager;
 
     public ManageTrustAgentsPreferenceController(Context context, String key) {
         super(context, key);
         final SecurityFeatureProvider securityFeatureProvider = FeatureFactory.getFactory(context)
                 .getSecurityFeatureProvider();
         mLockPatternUtils = securityFeatureProvider.getLockPatternUtils(context);
-        mTrustAgentManager = securityFeatureProvider.getTrustAgentManager();
     }
 
     @Override
@@ -66,6 +64,6 @@
     }
 
     private int getTrustAgentCount() {
-        return mTrustAgentManager.getActiveTrustAgents(mContext, mLockPatternUtils).size();
+        return mLockPatternUtils.getEnabledTrustAgents(MY_USER_ID).size();
     }
 }
diff --git a/src/com/android/settings/sim/receivers/SimSlotChangeHandler.java b/src/com/android/settings/sim/receivers/SimSlotChangeHandler.java
index 8c8964f..61241d0 100644
--- a/src/com/android/settings/sim/receivers/SimSlotChangeHandler.java
+++ b/src/com/android/settings/sim/receivers/SimSlotChangeHandler.java
@@ -26,12 +26,14 @@
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.telephony.UiccCardInfo;
 import android.telephony.UiccSlotInfo;
 import android.util.Log;
 
 import com.android.settings.network.SubscriptionUtil;
 import com.android.settings.network.UiccSlotUtil;
 import com.android.settings.network.UiccSlotsException;
+import com.android.settings.network.telephony.ToggleSubscriptionDialogActivity;
 import com.android.settings.sim.ChooseSimActivity;
 import com.android.settings.sim.DsdsDialogActivity;
 import com.android.settings.sim.SimActivationNotifier;
@@ -40,6 +42,7 @@
 
 import com.google.common.collect.ImmutableList;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -83,8 +86,8 @@
             throw new IllegalStateException("Cannot be called from main thread.");
         }
 
-        if (mTelMgr.getActiveModemCount() > 1) {
-            Log.i(TAG, "The device is already in DSDS mode. Do nothing.");
+        if (mTelMgr.getActiveModemCount() > 1 && !isMultipleEnabledProfilesSupported()) {
+            Log.i(TAG, "The device is already in DSDS mode and no MEP. Do nothing.");
             return;
         }
 
@@ -96,17 +99,30 @@
 
         int lastRemovableSlotState = getLastRemovableSimSlotState(mContext);
         int currentRemovableSlotState = removableSlotInfo.getCardStateInfo();
+        boolean isRemovableSimInserted =
+                lastRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_ABSENT
+                        && currentRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_PRESENT;
+        boolean isRemovableSimRemoved =
+                lastRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_PRESENT
+                        && currentRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_ABSENT;
 
         // Sets the current removable slot state.
         setRemovableSimSlotState(mContext, currentRemovableSlotState);
 
-        if (lastRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_ABSENT
-                && currentRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_PRESENT) {
+        if (mTelMgr.getActiveModemCount() > 1 && isMultipleEnabledProfilesSupported()) {
+            if(!isRemovableSimInserted) {
+                Log.i(TAG, "Removable Sim is not inserted in DSDS mode and MEP. Do nothing.");
+                return;
+            }
+            handleRemovableSimInsertUnderDsdsMep(removableSlotInfo);
+            return;
+        }
+
+        if (isRemovableSimInserted) {
             handleSimInsert(removableSlotInfo);
             return;
         }
-        if (lastRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_PRESENT
-                && currentRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_ABSENT) {
+        if (isRemovableSimRemoved) {
             handleSimRemove(removableSlotInfo);
             return;
         }
@@ -232,6 +248,23 @@
         startChooseSimActivity(false);
     }
 
+    private void handleRemovableSimInsertUnderDsdsMep(UiccSlotInfo removableSlotInfo) {
+        Log.i(TAG, "Handle Removable SIM inserted under DSDS+Mep.");
+
+        if (removableSlotInfo.getPorts().stream().findFirst().get().isActive()) {
+            Log.i(TAG, "The removable slot is already active. Do nothing. removableSlotInfo: "
+                    + removableSlotInfo);
+            return;
+        }
+
+        List<SubscriptionInfo> subscriptionInfos = getAvailableRemovableSubscription();
+        if (subscriptionInfos == null && subscriptionInfos.get(0) != null) {
+            Log.e(TAG, "Unable to find the removable subscriptionInfo. Do nothing.");
+            return;
+        }
+        startSimConfirmDialogActivity(subscriptionInfos.get(0).getSubscriptionId());
+    }
+
     private int getLastRemovableSimSlotState(Context context) {
         final SharedPreferences prefs = context.getSharedPreferences(EUICC_PREFS, MODE_PRIVATE);
         return prefs.getInt(KEY_REMOVABLE_SLOT_STATE, UiccSlotInfo.CARD_STATE_INFO_ABSENT);
@@ -261,7 +294,6 @@
         }
         for (UiccSlotInfo slotInfo : slotInfos) {
             if (slotInfo != null && slotInfo.isRemovable()) {
-
                 return slotInfo;
             }
         }
@@ -297,6 +329,16 @@
                         .collect(Collectors.toList()));
     }
 
+    protected List<SubscriptionInfo> getAvailableRemovableSubscription() {
+        List<SubscriptionInfo> subList = new ArrayList<>();
+        for (SubscriptionInfo info : SubscriptionUtil.getAvailableSubscriptions(mContext)) {
+            if (!info.isEmbedded()) {
+                subList.add(info);
+            }
+        }
+        return subList;
+    }
+
     private void startChooseSimActivity(boolean psimInserted) {
         Intent intent = ChooseSimActivity.getIntent(mContext);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -317,5 +359,25 @@
         mContext.startActivity(intent);
     }
 
+    private void startSimConfirmDialogActivity(int subId) {
+        if (!SubscriptionManager.isUsableSubscriptionId(subId)) {
+            Log.i(TAG, "Unable to enable subscription due to invalid subscription ID.");
+            return;
+        }
+        Intent intent = ToggleSubscriptionDialogActivity.getIntent(mContext, subId, true);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(intent);
+    }
+
+    private boolean isMultipleEnabledProfilesSupported() {
+        List<UiccCardInfo> cardInfos = mTelMgr.getUiccCardsInfo();
+        if (cardInfos == null) {
+            Log.w(TAG, "UICC cards info list is empty.");
+            return false;
+        }
+        return cardInfos.stream().anyMatch(
+                cardInfo -> cardInfo.isMultipleEnabledProfilesSupported());
+    }
+
     private SimSlotChangeHandler() {}
 }
diff --git a/src/com/android/settings/widget/RestrictedAppPreference.java b/src/com/android/settings/widget/RestrictedAppPreference.java
index cd95357..f93b935 100644
--- a/src/com/android/settings/widget/RestrictedAppPreference.java
+++ b/src/com/android/settings/widget/RestrictedAppPreference.java
@@ -20,12 +20,10 @@
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.AttributeSet;
-import android.view.View;
 
 import androidx.preference.PreferenceManager;
 import androidx.preference.PreferenceViewHolder;
 
-import com.android.settings.R;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.RestrictedPreferenceHelper;
 import com.android.settingslib.widget.AppPreference;
@@ -55,7 +53,6 @@
     }
 
     private void initialize(AttributeSet attrs, String userRestriction) {
-        setWidgetLayoutResource(R.layout.restricted_icon);
         mHelper = new RestrictedPreferenceHelper(getContext(), this, attrs);
         this.userRestriction = userRestriction;
     }
@@ -64,10 +61,6 @@
     public void onBindViewHolder(PreferenceViewHolder holder) {
         super.onBindViewHolder(holder);
         mHelper.onBindViewHolder(holder);
-        final View restrictedIcon = holder.findViewById(R.id.restricted_icon);
-        if (restrictedIcon != null) {
-            restrictedIcon.setVisibility(isDisabledByAdmin() ? View.VISIBLE : View.GONE);
-        }
     }
 
     @Override
diff --git a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java
index dd0c20a..6f26826 100644
--- a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java
+++ b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java
@@ -100,7 +100,6 @@
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
-        setIfOnlyAvailableForAdmins(true);
         mIsUiRestricted = isUiRestricted();
     }
 
diff --git a/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java b/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java
index f9d0db0..e3181e3 100644
--- a/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java
+++ b/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java
@@ -435,9 +435,9 @@
             mDataUsageSummaryPref = screen.findPreference(KEY_DATA_USAGE_HEADER);
             mDataUsageSummaryPref.setVisible(true);
             mSummaryHeaderController =
-                new WifiDataUsageSummaryPreferenceController(mFragment.getActivity(),
-                        mLifecycle, (PreferenceFragmentCompat) mFragment,
-                        mWifiEntry.getTitle());
+                    new WifiDataUsageSummaryPreferenceController(mFragment.getActivity(),
+                            mLifecycle, (PreferenceFragmentCompat) mFragment,
+                            mWifiEntry.getWifiConfiguration().getAllNetworkKeys());
             return;
         }
 
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java
index 06a046b..ea0f317 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java
@@ -40,6 +40,7 @@
 
 import androidx.annotation.Nullable;
 import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.FragmentActivity;
 import androidx.preference.PreferenceManager;
 import androidx.preference.PreferenceScreen;
 import androidx.test.core.app.ApplicationProvider;
@@ -53,6 +54,7 @@
 import org.mockito.Answers;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 import org.robolectric.shadow.api.Shadow;
@@ -92,6 +94,7 @@
         when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
         when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext);
         when(mFragment.getContext()).thenReturn(mContext);
+        when(mFragment.getActivity()).thenReturn(Robolectric.setupActivity(FragmentActivity.class));
         mScreen = spy(new PreferenceScreen(mContext, null));
         when(mScreen.getPreferenceManager()).thenReturn(mPreferenceManager);
         doReturn(mScreen).when(mFragment).getPreferenceScreen();
diff --git a/tests/robotests/src/com/android/settings/accessibility/AudioDescriptionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AudioDescriptionPreferenceControllerTest.java
new file mode 100644
index 0000000..1d3ffa8
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/AudioDescriptionPreferenceControllerTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2022 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.accessibility;
+
+import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
+import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.core.BasePreferenceController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+
+@RunWith(RobolectricTestRunner.class)
+public class AudioDescriptionPreferenceControllerTest {
+
+    private static final String KEY_AUDIO_DESCRIPTION =
+            Settings.Secure.ENABLED_ACCESSIBILITY_AUDIO_DESCRIPTION_BY_DEFAULT;
+    private static final int UNKNOWN = -1;
+
+    private final Context mContext = ApplicationProvider.getApplicationContext();
+    private final SwitchPreference mSwitchPreference = spy(new SwitchPreference(mContext));
+    private final AudioDescriptionPreferenceController mController =
+            new AudioDescriptionPreferenceController(mContext,
+                    AudioDescriptionPreferenceController.PREF_KEY);
+
+    @Before
+    public void setUp() {
+        final PreferenceManager preferenceManager = new PreferenceManager(mContext);
+        final PreferenceScreen screen = preferenceManager.createPreferenceScreen(mContext);
+        mSwitchPreference.setKey(AudioDescriptionPreferenceController.PREF_KEY);
+        screen.addPreference(mSwitchPreference);
+        mController.displayPreference(screen);
+    }
+
+    @Test
+    public void getAvailabilityStatus_byDefault_shouldReturnAvailable() {
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BasePreferenceController.AVAILABLE);
+    }
+
+    @Test
+    public void isChecked_disableAudioDescription_onResumeShouldReturnFalse() {
+        Settings.Secure.putInt(mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, OFF);
+
+        mController.updateState(mSwitchPreference);
+
+        assertThat(mController.isChecked()).isFalse();
+        assertThat(mSwitchPreference.isChecked()).isFalse();
+    }
+
+    @Test
+    public void isChecked_enableAudioDescription_onResumeShouldReturnTrue() {
+        Settings.Secure.putInt(mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, ON);
+
+        mController.updateState(mSwitchPreference);
+
+        assertThat(mController.isChecked()).isTrue();
+        assertThat(mSwitchPreference.isChecked()).isTrue();
+    }
+
+    @Test
+    public void performClick_enableAudioDescription_shouldReturnTrue() {
+        Settings.Secure.putInt(mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, OFF);
+
+        mController.updateState(mSwitchPreference);
+
+        mSwitchPreference.performClick();
+
+        verify(mSwitchPreference).setChecked(true);
+        assertThat(mController.isChecked()).isTrue();
+        assertThat(mSwitchPreference.isChecked()).isTrue();
+    }
+
+    @Test
+    public void performClick_disableAudioDescription_shouldReturnFalse() {
+        Settings.Secure.putInt(mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, ON);
+
+        mController.updateState(mSwitchPreference);
+
+        mSwitchPreference.performClick();
+
+        verify(mSwitchPreference).setChecked(false);
+        assertThat(mController.isChecked()).isFalse();
+        assertThat(mSwitchPreference.isChecked()).isFalse();
+    }
+
+    @Test
+    public void setChecked_setFalse_shouldDisableAudioDescription() {
+        mController.setChecked(false);
+
+        assertThat(Settings.Secure.getInt(
+            mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, UNKNOWN)).isEqualTo(OFF);
+    }
+
+    @Test
+    public void setChecked_setTrue_shouldEnableAudioDescription() {
+        mController.setChecked(true);
+
+        assertThat(Settings.Secure.getInt(
+            mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, UNKNOWN)).isEqualTo(ON);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/CaptionAppearancePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/CaptionAppearancePreferenceControllerTest.java
new file mode 100644
index 0000000..cfa683ba
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/CaptionAppearancePreferenceControllerTest.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2022 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.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.view.accessibility.CaptioningManager;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowCaptioningManager;
+
+/** Tests for {@link CaptionAppearancePreferenceController}. */
+@RunWith(RobolectricTestRunner.class)
+public class CaptionAppearancePreferenceControllerTest {
+
+    private static final String TEST_KEY = "test_key";
+    private static final int DEFAULT_PRESET_INDEX = 1;
+    private static final int DEFAULT_FONT_SCALE_INDEX = 2;
+
+    private final Context mContext = ApplicationProvider.getApplicationContext();
+    private CaptionAppearancePreferenceController mController;
+    private ShadowCaptioningManager mShadowCaptioningManager;
+
+    @Before
+    public void setUp() {
+        CaptioningManager captioningManager = mContext.getSystemService(CaptioningManager.class);
+        mShadowCaptioningManager = Shadow.extract(captioningManager);
+        mController = new CaptionAppearancePreferenceController(mContext, TEST_KEY);
+    }
+
+    @Test
+    public void getAvailabilityStatus_shouldReturnAvailable() {
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BasePreferenceController.AVAILABLE);
+    }
+
+    @Test
+    public void getSummary_noScale_shouldReturnDefaultSummary() {
+        final String expectedSummary =
+                getSummaryCombo(DEFAULT_FONT_SCALE_INDEX, DEFAULT_PRESET_INDEX);
+        assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+    }
+
+    @Test
+    public void getSummary_smallestScale_shouldReturnExpectedSummary() {
+        mShadowCaptioningManager.setFontScale(0.25f);
+
+        final String expectedSummary =
+                getSummaryCombo(/* fontScaleIndex= */ 0, DEFAULT_PRESET_INDEX);
+        assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+    }
+
+    @Test
+    public void getSummary_smallScale_shouldReturnExpectedSummary() {
+        mShadowCaptioningManager.setFontScale(0.5f);
+
+        final String expectedSummary =
+                getSummaryCombo(/* fontScaleIndex= */ 1, DEFAULT_PRESET_INDEX);
+        assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+    }
+
+    @Test
+    public void getSummary_mediumScale_shouldReturnExpectedSummary() {
+        mShadowCaptioningManager.setFontScale(1.0f);
+
+        final String expectedSummary =
+                getSummaryCombo(/* fontScaleIndex= */ 2, DEFAULT_PRESET_INDEX);
+        assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+    }
+
+    @Test
+    public void getSummary_largeScale_shouldReturnExpectedSummary() {
+        mShadowCaptioningManager.setFontScale(1.5f);
+
+        final String expectedSummary =
+                getSummaryCombo(/* fontScaleIndex= */ 3, DEFAULT_PRESET_INDEX);
+        assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+    }
+
+    @Test
+    public void getSummary_largestScale_shouldReturnExpectedSummary() {
+        mShadowCaptioningManager.setFontScale(2.0f);
+
+        final String expectedSummary =
+                getSummaryCombo(/* fontScaleIndex= */ 4, DEFAULT_PRESET_INDEX);
+        assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+    }
+
+    @Test
+    public void getSummary_setByAppPreset_shouldReturnExpectedSummary() {
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, 4);
+
+        final String expectedSummary =
+                getSummaryCombo(DEFAULT_FONT_SCALE_INDEX, /* presetIndex= */ 0);
+        assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+    }
+
+    @Test
+    public void getSummary_whiteOnBlackPreset_shouldReturnExpectedSummary() {
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, 0);
+
+        final String expectedSummary =
+                getSummaryCombo(DEFAULT_FONT_SCALE_INDEX, /* presetIndex= */ 1);
+        assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+    }
+
+    @Test
+    public void getSummary_blackOnWhitePreset_shouldReturnExpectedSummary() {
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, 1);
+
+        final String expectedSummary =
+                getSummaryCombo(DEFAULT_FONT_SCALE_INDEX, /* presetIndex= */ 2);
+        assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+    }
+
+    @Test
+    public void getSummary_yellowOnBlackPreset_shouldReturnExpectedSummary() {
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, 2);
+
+        final String expectedSummary =
+                getSummaryCombo(DEFAULT_FONT_SCALE_INDEX, /* presetIndex= */ 3);
+        assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+    }
+
+    @Test
+    public void getSummary_yellowOnBluePreset_shouldReturnExpectedSummary() {
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, 3);
+
+        final String expectedSummary =
+                getSummaryCombo(DEFAULT_FONT_SCALE_INDEX, /* presetIndex= */ 4);
+        assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+    }
+
+    @Test
+    public void getSummary_customPreset_shouldReturnExpectedSummary() {
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, -1);
+
+        final String expectedSummary =
+                getSummaryCombo(DEFAULT_FONT_SCALE_INDEX, /* presetIndex= */ 5);
+        assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+    }
+
+    private String getSummaryCombo(int fontScaleIndex, int presetIndex) {
+        final String[] fontScaleArray = mContext.getResources().getStringArray(
+                R.array.captioning_font_size_selector_titles);
+        final String[] presetArray = mContext.getResources().getStringArray(
+                R.array.captioning_preset_selector_titles);
+        return mContext.getString(R.string.preference_summary_default_combination,
+                fontScaleArray[fontScaleIndex], presetArray[presetIndex]);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/TextAndDisplayFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ColorAndMotionFragmentTest.java
similarity index 89%
rename from tests/robotests/src/com/android/settings/accessibility/TextAndDisplayFragmentTest.java
rename to tests/robotests/src/com/android/settings/accessibility/ColorAndMotionFragmentTest.java
index 96756ecd..0bb227e 100644
--- a/tests/robotests/src/com/android/settings/accessibility/TextAndDisplayFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/ColorAndMotionFragmentTest.java
@@ -32,17 +32,17 @@
 import java.util.List;
 
 @RunWith(RobolectricTestRunner.class)
-public class TextAndDisplayFragmentTest {
+public class ColorAndMotionFragmentTest {
 
     private Context mContext = ApplicationProvider.getApplicationContext();
 
     @Test
     public void getNonIndexableKeys_existInXmlLayout() {
-        final List<String> niks = TextAndDisplayFragment.SEARCH_INDEX_DATA_PROVIDER
+        final List<String> niks = ColorAndMotionFragment.SEARCH_INDEX_DATA_PROVIDER
                 .getNonIndexableKeys(mContext);
         final List<String> keys =
                 XmlTestUtils.getKeysFromPreferenceXml(mContext,
-                        R.xml.accessibility_text_and_display);
+                        R.xml.accessibility_color_and_motion);
 
         assertThat(keys).containsAtLeastElementsIn(niks);
     }
diff --git a/tests/robotests/src/com/android/settings/accessibility/DisplaySizeDataTest.java b/tests/robotests/src/com/android/settings/accessibility/DisplaySizeDataTest.java
new file mode 100644
index 0000000..fabf123
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/DisplaySizeDataTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 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.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+/**
+ * Tests for {@link DisplaySizeData}.
+ */
+@RunWith(RobolectricTestRunner.class)
+public class DisplaySizeDataTest {
+    private final Context mContext = ApplicationProvider.getApplicationContext();
+    private DisplaySizeData mDisplaySizeData;
+
+    @Before
+    public void setUp() {
+        mDisplaySizeData = new DisplaySizeData(mContext);
+    }
+
+    @Ignore("Ignore it since a NPE is happened in ShadowWindowManagerGlobal. (Ref. b/214161063)")
+    @Test
+    public void commit_success() {
+        final int progress = 4;
+
+        mDisplaySizeData.commit(progress);
+        final float density = mContext.getResources().getDisplayMetrics().density;
+
+        assertThat(density).isEqualTo(mDisplaySizeData.getValues().get(progress));
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/FontSizeDataTest.java b/tests/robotests/src/com/android/settings/accessibility/FontSizeDataTest.java
new file mode 100644
index 0000000..7e35714
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/FontSizeDataTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 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.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+/**
+ * Tests for {@link FontSizeData}.
+ */
+@RunWith(RobolectricTestRunner.class)
+public class FontSizeDataTest {
+    private final Context mContext = ApplicationProvider.getApplicationContext();
+    private FontSizeData mFontSizeData;
+
+    @Before
+    public void setUp() {
+        mFontSizeData = new FontSizeData(mContext);
+    }
+
+    @Test
+    public void commit_success() {
+        final int progress = 3;
+
+        mFontSizeData.commit(progress);
+        final float currentScale =
+                Settings.System.getFloat(mContext.getContentResolver(), Settings.System.FONT_SCALE,
+                        /* def= */ 1.0f);
+
+        assertThat(currentScale).isEqualTo(mFontSizeData.getValues().get(progress));
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragmentTest.java
index 0c656b3..c44352f 100644
--- a/tests/robotests/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragmentTest.java
@@ -83,9 +83,8 @@
     }
 
     @Test
-    public void getTileName_noTileServiceAssigned_noMatchString() {
-        final CharSequence tileName = mFragment.getTileName();
-        assertThat(tileName.toString()).isEqualTo("");
+    public void getTileName_noTileServiceAssigned_returnNull() {
+        assertThat(mFragment.getTileName()).isNull();
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/accessibility/LockScreenRotationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/LockScreenRotationPreferenceControllerTest.java
index ef8f569..f908b8a 100644
--- a/tests/robotests/src/com/android/settings/accessibility/LockScreenRotationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/LockScreenRotationPreferenceControllerTest.java
@@ -26,6 +26,7 @@
 
 import com.android.internal.view.RotationPolicy;
 import com.android.settings.core.BasePreferenceController;
+import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
 import com.android.settings.testutils.shadow.ShadowRotationPolicy;
 
 import org.junit.Before;
@@ -50,7 +51,10 @@
     }
 
     @Test
-    @Config(shadows = {ShadowRotationPolicy.class})
+    @Config(shadows = {
+            ShadowRotationPolicy.class,
+            ShadowDeviceStateRotationLockSettingsManager.class
+    })
     public void getAvailabilityStatus_supportedRotation_shouldReturnAvailable() {
         ShadowRotationPolicy.setRotationSupported(true /* supported */);
 
@@ -59,8 +63,23 @@
     }
 
     @Test
-    @Config(shadows = {ShadowRotationPolicy.class})
-    public void getAvailabilityStatus_unsupportedRotation_shouldReturnUnsupportedOnDevice() {
+    @Config(shadows = {
+            ShadowRotationPolicy.class,
+            ShadowDeviceStateRotationLockSettingsManager.class
+    })
+    public void getAvailabilityStatus_deviceStateRotationEnabled_returnsUnsupported() {
+        ShadowRotationPolicy.setRotationSupported(true /* supported */);
+        ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BasePreferenceController.UNSUPPORTED_ON_DEVICE);
+    }
+
+    @Test
+    @Config(shadows = {
+            ShadowRotationPolicy.class,
+            ShadowDeviceStateRotationLockSettingsManager.class
+    })    public void getAvailabilityStatus_unsupportedRotation_shouldReturnUnsupportedOnDevice() {
         ShadowRotationPolicy.setRotationSupported(false /* supported */);
 
         assertThat(mController.getAvailabilityStatus()).isEqualTo(
diff --git a/tests/robotests/src/com/android/settings/accessibility/PreviewSizeSeekBarControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/PreviewSizeSeekBarControllerTest.java
new file mode 100644
index 0000000..d33d80e
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/PreviewSizeSeekBarControllerTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2022 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.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.widget.LabeledSeekBarPreference;
+
+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;
+
+/**
+ * Tests for {@link PreviewSizeSeekBarController}.
+ */
+@RunWith(RobolectricTestRunner.class)
+public class PreviewSizeSeekBarControllerTest {
+    private static final String FONT_SIZE_KEY = "font_size";
+    private final Context mContext = ApplicationProvider.getApplicationContext();
+    private PreviewSizeSeekBarController mSeekBarController;
+    private FontSizeData mFontSizeData;
+    private LabeledSeekBarPreference mSeekBarPreference;
+
+    @Mock
+    private PreferenceScreen mPreferenceScreen;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mFontSizeData = new FontSizeData(mContext);
+
+        mSeekBarController =
+                new PreviewSizeSeekBarController(mContext, FONT_SIZE_KEY, mFontSizeData);
+
+        mSeekBarPreference = spy(new LabeledSeekBarPreference(mContext, /* attrs= */ null));
+        when(mPreferenceScreen.findPreference(anyString())).thenReturn(mSeekBarPreference);
+    }
+
+    @Test
+    public void initMax_matchResult() {
+        when(mPreferenceScreen.findPreference(anyString())).thenReturn(mSeekBarPreference);
+
+        mSeekBarController.displayPreference(mPreferenceScreen);
+
+        assertThat(mSeekBarPreference.getMax()).isEqualTo(
+                mFontSizeData.getValues().size() - 1);
+    }
+
+    @Test
+    public void initProgress_matchResult() {
+        when(mPreferenceScreen.findPreference(anyString())).thenReturn(mSeekBarPreference);
+
+        mSeekBarController.displayPreference(mPreferenceScreen);
+
+        verify(mSeekBarPreference).setProgress(mFontSizeData.getInitialIndex());
+    }
+
+    @Test
+    public void resetToDefaultState_matchResult() {
+        final int defaultProgress =
+                mFontSizeData.getValues().indexOf(mFontSizeData.getDefaultValue());
+        when(mPreferenceScreen.findPreference(anyString())).thenReturn(mSeekBarPreference);
+
+        mSeekBarController.displayPreference(mPreferenceScreen);
+        mSeekBarPreference.setProgress(defaultProgress + 1);
+        mSeekBarController.resetState();
+
+        assertThat(mSeekBarPreference.getProgress()).isEqualTo(defaultProgress);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewControllerTest.java
new file mode 100644
index 0000000..b630509
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewControllerTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2022 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.accessibility;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.display.PreviewPagerAdapter;
+import com.android.settings.widget.LabeledSeekBarPreference;
+
+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.annotation.Config;
+import org.robolectric.shadows.ShadowChoreographer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link TextReadingPreviewController}.
+ */
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowChoreographer.class)
+public class TextReadingPreviewControllerTest {
+    private static final String PREVIEW_KEY = "preview";
+    private static final String FONT_SIZE_KEY = "font_size";
+    private static final String DISPLAY_SIZE_KEY = "display_size";
+    private final Context mContext = ApplicationProvider.getApplicationContext();
+    private TextReadingPreviewController mPreviewController;
+    private TextReadingPreviewPreference mPreviewPreference;
+    private LabeledSeekBarPreference mFontSizePreference;
+    private LabeledSeekBarPreference mDisplaySizePreference;
+
+    @Mock
+    private DisplaySizeData mDisplaySizeData;
+
+    @Mock
+    private PreferenceScreen mPreferenceScreen;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        final FontSizeData fontSizeData = new FontSizeData(mContext);
+        final List<Integer> displayData = createFakeDisplayData();
+        when(mDisplaySizeData.getValues()).thenReturn(displayData);
+        mPreviewPreference = spy(new TextReadingPreviewPreference(mContext, /* attr= */ null));
+        mPreviewController = new TextReadingPreviewController(mContext, PREVIEW_KEY, fontSizeData,
+                mDisplaySizeData);
+        mFontSizePreference = new LabeledSeekBarPreference(mContext, /* attr= */ null);
+        mDisplaySizePreference = new LabeledSeekBarPreference(mContext, /* attr= */ null);
+    }
+
+    @Test
+    public void initPreviewerAdapter_verifyAction() {
+        when(mPreferenceScreen.findPreference(PREVIEW_KEY)).thenReturn(mPreviewPreference);
+        when(mPreferenceScreen.findPreference(FONT_SIZE_KEY)).thenReturn(mFontSizePreference);
+        when(mPreferenceScreen.findPreference(DISPLAY_SIZE_KEY)).thenReturn(mDisplaySizePreference);
+
+        mPreviewController.displayPreference(mPreferenceScreen);
+
+        verify(mPreviewPreference).setPreviewAdapter(any(PreviewPagerAdapter.class));
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void initPreviewerAdapterWithoutDisplaySizePreference_throwNPE() {
+        when(mPreferenceScreen.findPreference(PREVIEW_KEY)).thenReturn(mPreviewPreference);
+        when(mPreferenceScreen.findPreference(DISPLAY_SIZE_KEY)).thenReturn(mDisplaySizePreference);
+
+        mPreviewController.displayPreference(mPreferenceScreen);
+
+        verify(mPreviewPreference).setPreviewAdapter(any(PreviewPagerAdapter.class));
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void initPreviewerAdapterWithoutFontSizePreference_throwNPE() {
+        when(mPreferenceScreen.findPreference(PREVIEW_KEY)).thenReturn(mPreviewPreference);
+        when(mPreferenceScreen.findPreference(FONT_SIZE_KEY)).thenReturn(mFontSizePreference);
+
+        mPreviewController.displayPreference(mPreferenceScreen);
+
+        verify(mPreviewPreference).setPreviewAdapter(any(PreviewPagerAdapter.class));
+    }
+
+    private List<Integer> createFakeDisplayData() {
+        final List<Integer> list = new ArrayList<>();
+        list.add(1);
+        list.add(2);
+        list.add(3);
+        list.add(4);
+
+        return list;
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewPreferenceTest.java b/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewPreferenceTest.java
index 6b9395a..3dc82da 100644
--- a/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewPreferenceTest.java
@@ -16,8 +16,16 @@
 
 package com.android.settings.accessibility;
 
+import static com.android.settings.accessibility.TextReadingPreviewController.PREVIEW_SAMPLE_RES_IDS;
+
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
 import android.content.Context;
 import android.content.res.Configuration;
 import android.view.LayoutInflater;
@@ -50,12 +58,11 @@
     @Before
     public void setUp() {
         final Context context = ApplicationProvider.getApplicationContext();
-        final int[] sampleResIds = new int[]{1, 2, 3, 4, 5, 6};
-        final Configuration[] configurations = createConfigurations(6);
+        final Configuration[] configurations = createConfigurations(PREVIEW_SAMPLE_RES_IDS.length);
         mTextReadingPreviewPreference = new TextReadingPreviewPreference(context);
         mPreviewPagerAdapter =
-                new PreviewPagerAdapter(context, /* isLayoutRtl= */ false, sampleResIds,
-                        configurations);
+                spy(new PreviewPagerAdapter(context, /* isLayoutRtl= */ false,
+                        PREVIEW_SAMPLE_RES_IDS, configurations));
         final LayoutInflater inflater = LayoutInflater.from(context);
         final View view =
                 inflater.inflate(mTextReadingPreviewPreference.getLayoutResource(),
@@ -87,7 +94,7 @@
 
     @Test
     public void setCurrentItem_success() {
-        final int currentItem = 3;
+        final int currentItem = 1;
         mTextReadingPreviewPreference.setPreviewAdapter(mPreviewPagerAdapter);
         mTextReadingPreviewPreference.onBindViewHolder(mHolder);
 
@@ -104,6 +111,24 @@
         mTextReadingPreviewPreference.setCurrentItem(currentItem);
     }
 
+    @Test(expected = NullPointerException.class)
+    public void updatePagerWithoutPreviewAdapter_throwNPE() {
+        final int index = 1;
+
+        mTextReadingPreviewPreference.notifyPreviewPagerChanged(index);
+    }
+
+    @Test
+    public void notifyPreviewPager_setPreviewLayer() {
+        final int index = 2;
+        mTextReadingPreviewPreference.setPreviewAdapter(mPreviewPagerAdapter);
+        mTextReadingPreviewPreference.onBindViewHolder(mHolder);
+
+        mTextReadingPreviewPreference.notifyPreviewPagerChanged(index);
+
+        verify(mPreviewPagerAdapter).setPreviewLayer(eq(index), anyInt(), anyInt(), anyBoolean());
+    }
+
     private static Configuration[] createConfigurations(int count) {
         final Configuration[] configurations = new Configuration[count];
         for (int i = 0; i < count; i++) {
diff --git a/tests/robotests/src/com/android/settings/accessibility/TextReadingResetControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/TextReadingResetControllerTest.java
new file mode 100644
index 0000000..2ae8e24
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/TextReadingResetControllerTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2022 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.accessibility;
+
+import static com.android.settings.accessibility.TextReadingResetController.ResetStateListener;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.view.View;
+
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.widget.LayoutPreference;
+
+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 java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link TextReadingResetController}.
+ */
+@RunWith(RobolectricTestRunner.class)
+public class TextReadingResetControllerTest {
+    private static final String TEST_KEY = "test";
+    private static final String RESET_KEY = "reset";
+    private final Context mContext = ApplicationProvider.getApplicationContext();
+    private final View mResetView = new View(mContext);
+    private final List<ResetStateListener> mListeners = new ArrayList<>();
+    private TextReadingResetController mResetController;
+    private TestPreferenceController mPreferenceController;
+
+    @Mock
+    private PreferenceScreen mPreferenceScreen;
+
+    @Mock
+    private LayoutPreference mLayoutPreference;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mPreferenceController = new TestPreferenceController(mContext, TEST_KEY);
+        mListeners.add(mPreferenceController);
+        mResetController = new TextReadingResetController(mContext, RESET_KEY, mListeners);
+    }
+
+    @Test
+    public void setClickListener_success() {
+        setupResetButton();
+
+        mResetController.displayPreference(mPreferenceScreen);
+
+        assertThat(mResetView.hasOnClickListeners()).isTrue();
+    }
+
+    @Test
+    public void triggerResetState_success() {
+        setupResetButton();
+
+        mResetController.displayPreference(mPreferenceScreen);
+        mResetView.callOnClick();
+
+        assertThat(mPreferenceController.isReset()).isTrue();
+    }
+
+    private void setupResetButton() {
+        when(mPreferenceScreen.findPreference(RESET_KEY)).thenReturn(mLayoutPreference);
+        when(mLayoutPreference.findViewById(R.id.reset_button)).thenReturn(mResetView);
+    }
+
+    private static class TestPreferenceController extends BasePreferenceController implements
+            ResetStateListener {
+        private boolean mIsReset = false;
+
+        TestPreferenceController(Context context, String preferenceKey) {
+            super(context, preferenceKey);
+        }
+
+        @Override
+        public void resetState() {
+            mIsReset = true;
+        }
+
+        @Override
+        public int getAvailabilityStatus() {
+            return AVAILABLE;
+        }
+
+        boolean isReset() {
+            return mIsReset;
+        }
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragmentTest.java
index db5b83c..236f9f2 100644
--- a/tests/robotests/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragmentTest.java
@@ -83,9 +83,8 @@
     }
 
     @Test
-    public void getTileName_noTileServiceAssigned_noMatchString() {
-        final CharSequence tileName = mFragment.getTileName();
-        assertThat(tileName.toString()).isEqualTo("");
+    public void getTileName_noTileServiceAssigned_returnNull() {
+        assertThat(mFragment.getTileName()).isNull();
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java
index 5ea4edc..34a2f5b 100644
--- a/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java
@@ -51,6 +51,7 @@
 import com.android.settings.accessibility.AccessibilityDialogUtils.DialogType;
 import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
 import com.android.settings.testutils.shadow.ShadowFragment;
+import com.android.settingslib.widget.TopIntroPreference;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -81,6 +82,7 @@
     private static final String PLACEHOLDER_DIALOG_TITLE = "title";
     private static final String DEFAULT_SUMMARY = "default summary";
     private static final String DEFAULT_DESCRIPTION = "default description";
+    private static final String DEFAULT_TOP_INTRO = "default top intro";
 
     private static final String SOFTWARE_SHORTCUT_KEY =
             Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
@@ -294,6 +296,23 @@
     }
 
     @Test
+    public void initTopIntroPreference_hasTopIntroTitle_shouldSetAsExpectedValue() {
+        mFragment.mTopIntroTitle = DEFAULT_TOP_INTRO;
+        mFragment.initTopIntroPreference();
+
+        TopIntroPreference topIntroPreference =
+                (TopIntroPreference) mFragment.getPreferenceScreen().getPreference(/* index= */ 0);
+        assertThat(topIntroPreference.getTitle().toString()).isEqualTo(DEFAULT_TOP_INTRO);
+    }
+
+    @Test
+    public void initTopIntroPreference_topIntroTitleIsNull_shouldNotAdded() {
+        mFragment.initTopIntroPreference();
+
+        assertThat(mFragment.getPreferenceScreen().getPreferenceCount()).isEqualTo(0);
+    }
+
+    @Test
     public void createFooterPreference_shouldSetAsExpectedValue() {
         mFragment.createFooterPreference(mFragment.getPreferenceScreen(),
                 DEFAULT_SUMMARY, DEFAULT_DESCRIPTION);
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java
index 2cec3d1..b6401cf 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.applications.appinfo;
 
+import static com.android.settings.applications.appinfo.AppInfoDashboardFragment.ACCESS_RESTRICTED_SETTINGS;
 import static com.android.settings.applications.appinfo.AppInfoDashboardFragment.ARG_PACKAGE_NAME;
 import static com.android.settings.applications.appinfo.AppInfoDashboardFragment.UNINSTALL_ALL_USERS_MENU;
 import static com.android.settings.applications.appinfo.AppInfoDashboardFragment.UNINSTALL_UPDATES;
@@ -165,8 +166,10 @@
         Menu menu = mock(Menu.class);
         final MenuItem uninstallUpdatesMenuItem = mock(MenuItem.class);
         final MenuItem uninstallForAllMenuItem = mock(MenuItem.class);
+        final MenuItem accessRestrictedMenuItem = mock(MenuItem.class);
         when(menu.findItem(UNINSTALL_UPDATES)).thenReturn(uninstallUpdatesMenuItem);
         when(menu.findItem(UNINSTALL_ALL_USERS_MENU)).thenReturn(uninstallForAllMenuItem);
+        when(menu.findItem(ACCESS_RESTRICTED_SETTINGS)).thenReturn(accessRestrictedMenuItem);
 
         // Setup work to prevent NPE
         final ApplicationInfo info = new ApplicationInfo();
diff --git a/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java
index 31687c6..6087ef2 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java
@@ -99,6 +99,7 @@
         mController.mBluetoothAdapter = mBluetoothAdapter;
         when(mCachedDevice.getDevice()).thenReturn(mBluetoothDevice);
         when(mCachedDevice.getAddress()).thenReturn(MAC_ADDRESS);
+        when(mCachedDevice.getIdentityAddress()).thenReturn(MAC_ADDRESS);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerTestBase.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerTestBase.java
index 6401388..6ecbf2e 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerTestBase.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerTestBase.java
@@ -155,6 +155,7 @@
         mDevice = mBluetoothAdapter.getRemoteDevice(config.getAddress());
         when(mCachedDevice.getDevice()).thenReturn(mDevice);
         when(mCachedDevice.getAddress()).thenReturn(config.getAddress());
+        when(mCachedDevice.getIdentityAddress()).thenReturn(config.getAddress());
     }
 
     /**
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragmentTest.java
index ce41a8d..fac8b58 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragmentTest.java
@@ -89,6 +89,7 @@
         when(fragmentManager.beginTransaction()).thenReturn(mFragmentTransaction);
 
         when(mCachedDevice.getAddress()).thenReturn(TEST_ADDRESS);
+        when(mCachedDevice.getIdentityAddress()).thenReturn(TEST_ADDRESS);
         Bundle args = new Bundle();
         args.putString(BluetoothDeviceDetailsFragment.KEY_DEVICE_ADDRESS, TEST_ADDRESS);
         mFragment.setArguments(args);
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java
index ea841fa..bac868f 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java
@@ -305,6 +305,7 @@
         when(cachedDevice.isConnected()).thenReturn(true);
         when(cachedDevice.getDevice()).thenReturn(device2);
         when(cachedDevice.getAddress()).thenReturn(TEST_DEVICE_ADDRESS_B);
+        when(cachedDevice.getIdentityAddress()).thenReturn(TEST_DEVICE_ADDRESS_B);
 
         mFragment.onProfileConnectionStateChanged(cachedDevice, BluetoothProfile.A2DP,
                 BluetoothAdapter.STATE_CONNECTED);
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingServiceTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingServiceTest.java
index e73b447..3194e55 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingServiceTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingServiceTest.java
@@ -106,7 +106,7 @@
 
         mBluetoothPairingService.onStartCommand(intent, /* flags */ 0, /* startId */ 0);
 
-        verify(mDevice).cancelPairing();
+        verify(mDevice).cancelBondProcess();
         verify(mNm).cancel(mBluetoothPairingService.NOTIFICATION_ID);
     }
 
diff --git a/tests/robotests/src/com/android/settings/bluetooth/ForgetDeviceDialogFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/ForgetDeviceDialogFragmentTest.java
index 5c23238..9c266c1 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/ForgetDeviceDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/ForgetDeviceDialogFragmentTest.java
@@ -73,6 +73,7 @@
         FakeFeatureFactory.setupForTest();
         String deviceAddress = "55:66:77:88:99:AA";
         when(mCachedDevice.getAddress()).thenReturn(deviceAddress);
+        when(mCachedDevice.getIdentityAddress()).thenReturn(deviceAddress);
         when(mCachedDevice.getDevice()).thenReturn(mBluetoothDevice);
         when(mCachedDevice.getName()).thenReturn(DEVICE_NAME);
         mFragment = spy(ForgetDeviceDialogFragment.newInstance(deviceAddress));
diff --git a/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java
index c8467b2..ad5b70c 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java
@@ -62,6 +62,7 @@
 
         String deviceAddress = "55:66:77:88:99:AA";
         when(mCachedDevice.getAddress()).thenReturn(deviceAddress);
+        when(mCachedDevice.getIdentityAddress()).thenReturn(deviceAddress);
         mFragment = spy(RemoteDeviceNameDialogFragment.newInstance(mCachedDevice));
         doReturn(mCachedDevice).when(mFragment).getDevice(any());
     }
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
index fd1c8ff..aa5f980 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
@@ -144,6 +144,21 @@
     }
 
     @Test
+    public void useAll_returnsAllControllersOfType() {
+        final TestPreferenceController controller1 = new TestPreferenceController(mContext);
+        final TestPreferenceController controller2 = new TestPreferenceController(mContext);
+        final SubTestPreferenceController controller3 = new SubTestPreferenceController(mContext);
+        mTestFragment.addPreferenceController(controller1);
+        mTestFragment.addPreferenceController(controller2);
+        mTestFragment.addPreferenceController(controller3);
+
+        final List<TestPreferenceController> retrievedControllers = mTestFragment.useAll(
+                TestPreferenceController.class);
+
+        assertThat(retrievedControllers).containsExactly(controller1, controller2);
+    }
+
+    @Test
     public void displayTilesAsPreference_shouldAddTilesWithIntent() {
         when(mFakeFeatureFactory.dashboardFeatureProvider
                 .getTilesForCategory(nullable(String.class)))
@@ -360,6 +375,13 @@
         }
     }
 
+    public static class SubTestPreferenceController extends TestPreferenceController {
+
+        private SubTestPreferenceController(Context context) {
+            super(context);
+        }
+    }
+
     private static class TestFragment extends DashboardFragment {
 
         private final PreferenceManager mPreferenceManager;
diff --git a/tests/robotests/src/com/android/settings/datausage/WifiDataUsageSummaryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/datausage/WifiDataUsageSummaryPreferenceControllerTest.java
new file mode 100644
index 0000000..711f6d7
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/datausage/WifiDataUsageSummaryPreferenceControllerTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2022 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.datausage;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.net.NetworkPolicyManager;
+import android.telephony.TelephonyManager;
+
+import androidx.fragment.app.FragmentActivity;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.net.DataUsageController;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.RobolectricTestRunner;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@RunWith(RobolectricTestRunner.class)
+public class WifiDataUsageSummaryPreferenceControllerTest {
+
+    @Rule
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+    @Spy
+    Context mContext = ApplicationProvider.getApplicationContext();
+    @Mock
+    FragmentActivity mActivity;
+    @Mock
+    Lifecycle mLifecycle;
+    @Mock
+    TelephonyManager mTelephonyManager;
+    @Mock
+    NetworkPolicyManager mNetworkPolicyManager;
+    @Mock
+    DataUsageSummaryPreference mSummaryPreference;
+    @Mock
+    DataUsageController mDataUsageController;
+    @Mock
+    DataUsageController.DataUsageInfo mDataUsageInfo;
+
+    WifiDataUsageSummaryPreferenceController mController;
+    Set<String> mAllNetworkKeys = new HashSet<>();
+
+    @Before
+    public void setUp() {
+        doReturn(mContext.getResources()).when(mActivity).getResources();
+        doReturn(mTelephonyManager).when(mActivity).getSystemService(TelephonyManager.class);
+        doReturn(mNetworkPolicyManager).when(mActivity)
+                .getSystemService(NetworkPolicyManager.class);
+        doNothing().when(mSummaryPreference).setWifiMode(anyBoolean(), anyString(), anyBoolean());
+        doReturn(mDataUsageInfo).when(mDataUsageController).getDataUsageInfo(any());
+
+        mController = spy(new WifiDataUsageSummaryPreferenceController(mActivity, mLifecycle, null,
+                mAllNetworkKeys));
+        doReturn(mDataUsageController).when(mController).createDataUsageController(any());
+    }
+
+    @Test
+    public void updateState_nullOfDataUsageController_shouldNotCrash() {
+        mController.mDataUsageController = null;
+
+        mController.updateState(mSummaryPreference);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java
index 1d175de..54e6b99 100644
--- a/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java
@@ -30,6 +30,7 @@
 
 import androidx.preference.SwitchPreference;
 
+import com.android.internal.R;
 import com.android.internal.view.RotationPolicy;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.testutils.FakeFeatureFactory;
@@ -64,6 +65,7 @@
         mPreference = new SwitchPreference(RuntimeEnvironment.application);
         when(mContext.getPackageManager()).thenReturn(mPackageManager);
         when(mContext.getContentResolver()).thenReturn(mContentResolver);
+        disableDeviceStateRotation();
 
         mController = new AutoRotatePreferenceController(mContext, "auto_rotate");
     }
@@ -112,6 +114,26 @@
     }
 
     @Test
+    public void getAvailabilityStatus_deviceRotationDisabled_returnsAvailable() {
+        enableAutoRotationPreference();
+        disableDeviceStateRotation();
+
+        int availability = mController.getAvailabilityStatus();
+
+        assertThat(availability).isEqualTo(BasePreferenceController.AVAILABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_deviceRotationEnabled_returnsUnsupported() {
+        enableAutoRotationPreference();
+        enableDeviceStateRotation();
+
+        int availability = mController.getAvailabilityStatus();
+
+        assertThat(availability).isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
+    }
+
+    @Test
     public void testIsCheck() {
         assertThat(mController.isChecked()).isFalse();
 
@@ -180,4 +202,15 @@
         Settings.System.putIntForUser(mContentResolver,
                 Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT);
     }
+
+    private void enableDeviceStateRotation() {
+        when(mContext.getResources().getStringArray(
+                R.array.config_perDeviceStateRotationLockDefaults)).thenReturn(
+                new String[]{"0:0", "1:1", "2:2"});
+    }
+
+    private void disableDeviceStateRotation() {
+        when(mContext.getResources().getStringArray(
+                R.array.config_perDeviceStateRotationLockDefaults)).thenReturn(new String[]{});
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateDetailsFragmentTest.java b/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateDetailsFragmentTest.java
new file mode 100644
index 0000000..b773657
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateDetailsFragmentTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.display;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.content.res.Resources;
+
+import com.android.settings.R;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+public class DeviceStateAutoRotateDetailsFragmentTest {
+
+    private final DeviceStateAutoRotateDetailsFragment mFragment =
+            spy(new DeviceStateAutoRotateDetailsFragment());
+    private final Context mContext = spy(RuntimeEnvironment.application);
+    private final Resources mResources = spy(mContext.getResources());
+
+    @Before
+    public void setUp() throws Exception {
+        when(mContext.getResources()).thenReturn(mResources);
+        when(mContext.getApplicationContext()).thenReturn(mContext);
+        when(mFragment.getContext()).thenReturn(mContext);
+        when(mFragment.getResources()).thenReturn(mResources);
+    }
+
+    @Test
+    public void getMetricsCategory_returnsAutoRotateSettings() {
+        assertThat(mFragment.getMetricsCategory()).isEqualTo(
+                SettingsEnums.DISPLAY_AUTO_ROTATE_SETTINGS);
+    }
+
+    @Test
+    public void getPreferenceScreenResId_returnsDeviceStateAutoRotationSettings() {
+        assertThat(mFragment.getPreferenceScreenResId()).isEqualTo(
+                R.xml.device_state_auto_rotate_settings);
+    }
+
+    @Test
+    public void createPreferenceControllers_settableDeviceStates_returnsDeviceStateControllers() {
+        enableDeviceStateSettableRotationStates(new String[]{"0:1", "1:1"},
+                new String[]{"Folded", "Unfolded"});
+
+        List<AbstractPreferenceController> preferenceControllers =
+                mFragment.createPreferenceControllers(mContext);
+
+        assertThat(preferenceControllers).hasSize(2);
+        assertThat(preferenceControllers.get(0)).isInstanceOf(
+                DeviceStateAutoRotateSettingController.class);
+        assertThat(preferenceControllers.get(1)).isInstanceOf(
+                DeviceStateAutoRotateSettingController.class);
+    }
+
+    @Test
+    public void createPreferenceControllers_noSettableDeviceStates_returnsEmptyList() {
+        enableDeviceStateSettableRotationStates(new String[]{}, new String[]{});
+
+        List<AbstractPreferenceController> preferenceControllers =
+                mFragment.createPreferenceControllers(mContext);
+
+        assertThat(preferenceControllers).isEmpty();
+    }
+
+    private void enableDeviceStateSettableRotationStates(String[] settableStates,
+            String[] settableStatesDescriptions) {
+        when(mResources.getStringArray(
+                com.android.internal.R.array.config_perDeviceStateRotationLockDefaults)).thenReturn(
+                settableStates);
+        when(mResources.getStringArray(
+                R.array.config_settableAutoRotationDeviceStatesDescriptions)).thenReturn(
+                settableStatesDescriptions);
+        DeviceStateRotationLockSettingsManager.resetInstance();
+        DeviceStateRotationLockSettingsManager.getInstance(mContext)
+                .resetStateForTesting(mResources);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateOverviewControllerTest.java b/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateOverviewControllerTest.java
new file mode 100644
index 0000000..a5416e7
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateOverviewControllerTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.display;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
+import com.android.settings.testutils.shadow.ShadowRotationPolicy;
+
+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 = {ShadowRotationPolicy.class, ShadowDeviceStateRotationLockSettingsManager.class})
+public class DeviceStateAutoRotateOverviewControllerTest {
+
+    private final DeviceStateAutoRotateOverviewController mController =
+            new DeviceStateAutoRotateOverviewController(
+                    RuntimeEnvironment.application, "device_state_auto_rotate");
+
+    @Test
+    public void getAvailabilityStatus_rotationAndDeviceStateRotationEnabled_returnsAvailable() {
+        ShadowRotationPolicy.setRotationSupported(true);
+        ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
+
+        int availability = mController.getAvailabilityStatus();
+
+        assertThat(availability).isEqualTo(AVAILABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_rotationNotSupported_returnsUnsupportedOnDevice() {
+        ShadowRotationPolicy.setRotationSupported(false);
+        ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
+
+        int availability = mController.getAvailabilityStatus();
+
+        assertThat(availability).isEqualTo(UNSUPPORTED_ON_DEVICE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_deviceStateRotationNotSupported_returnsUnsupportedOnDevice() {
+        ShadowRotationPolicy.setRotationSupported(true);
+        ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(false);
+
+        int availability = mController.getAvailabilityStatus();
+
+        assertThat(availability).isEqualTo(UNSUPPORTED_ON_DEVICE);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateSettingControllerTest.java b/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateSettingControllerTest.java
new file mode 100644
index 0000000..28a071a
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateSettingControllerTest.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.display;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
+import com.android.settings.testutils.shadow.ShadowRotationPolicy;
+import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
+import com.android.settingslib.search.SearchIndexableRaw;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {
+        ShadowRotationPolicy.class,
+        ShadowDeviceStateRotationLockSettingsManager.class
+})
+public class DeviceStateAutoRotateSettingControllerTest {
+
+    private static final int DEFAULT_DEVICE_STATE = 1;
+    private static final String DEFAULT_DEVICE_STATE_DESCRIPTION = "Device state description";
+    private static final int DEFAULT_ORDER = -10;
+
+    private final Context mContext = RuntimeEnvironment.application;
+    private final DeviceStateAutoRotateSettingController mController =
+            new DeviceStateAutoRotateSettingController(mContext, DEFAULT_DEVICE_STATE,
+                    DEFAULT_DEVICE_STATE_DESCRIPTION, DEFAULT_ORDER);
+    private final DeviceStateRotationLockSettingsManager mAutoRotateSettingsManager =
+            DeviceStateRotationLockSettingsManager.getInstance(mContext);
+
+    @Test
+    public void displayPreference_addsPreferenceToPreferenceScreen() {
+        PreferenceScreen screen = new PreferenceManager(mContext).createPreferenceScreen(mContext);
+
+        mController.displayPreference(screen);
+
+        assertThat(screen.getPreferenceCount()).isEqualTo(1);
+        Preference preference = screen.getPreference(0);
+        assertThat(preference.getTitle().toString()).isEqualTo(DEFAULT_DEVICE_STATE_DESCRIPTION);
+        assertThat(preference.getOrder()).isEqualTo(DEFAULT_ORDER);
+        assertThat(preference.getKey()).isEqualTo(mController.getPreferenceKey());
+    }
+
+    @Test
+    public void getAvailabilityStatus_rotationAndDeviceStateRotationEnabled_returnsAvailable() {
+        ShadowRotationPolicy.setRotationSupported(true);
+        ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
+
+        int availability = mController.getAvailabilityStatus();
+
+        assertThat(availability).isEqualTo(AVAILABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_deviceStateRotationDisabled_returnsUnsupported() {
+        ShadowRotationPolicy.setRotationSupported(true);
+        ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(false);
+
+        int availability = mController.getAvailabilityStatus();
+
+        assertThat(availability).isEqualTo(UNSUPPORTED_ON_DEVICE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_rotationDisabled_returnsUnsupported() {
+        ShadowRotationPolicy.setRotationSupported(false);
+        ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
+
+        int availability = mController.getAvailabilityStatus();
+
+        assertThat(availability).isEqualTo(UNSUPPORTED_ON_DEVICE);
+    }
+
+    @Test
+    public void getPreferenceKey_returnsKeyBasedOnDeviceState() {
+        String key = mController.getPreferenceKey();
+
+        String expectedKey = "auto_rotate_device_state_" + DEFAULT_DEVICE_STATE;
+        assertThat(key).isEqualTo(expectedKey);
+    }
+
+    @Test
+    public void isChecked_settingForStateIsUnlocked_returnsTrue() {
+        mAutoRotateSettingsManager.updateSetting(DEFAULT_DEVICE_STATE, /* rotationLocked= */ false);
+
+        assertThat(mController.isChecked()).isTrue();
+    }
+
+    @Test
+    public void isChecked_settingForStateIsLocked_returnsFalse() {
+        mAutoRotateSettingsManager.updateSetting(DEFAULT_DEVICE_STATE, /* rotationLocked= */ true);
+
+        assertThat(mController.isChecked()).isFalse();
+    }
+
+    @Test
+    public void setChecked_true_deviceStateSettingIsUnlocked() {
+        mController.setChecked(true);
+
+        boolean rotationLocked = mAutoRotateSettingsManager.isRotationLocked(DEFAULT_DEVICE_STATE);
+
+        assertThat(rotationLocked).isFalse();
+    }
+
+    @Test
+    public void setChecked_false_deviceStateSettingIsLocked() {
+        mController.setChecked(false);
+
+        boolean rotationLocked = mAutoRotateSettingsManager.isRotationLocked(DEFAULT_DEVICE_STATE);
+
+        assertThat(rotationLocked).isTrue();
+    }
+
+    @Test
+    public void updateRawDataToIndex_addsItemToList() {
+        List<SearchIndexableRaw> rawData = new ArrayList<>();
+
+        mController.updateRawDataToIndex(rawData);
+
+        assertThat(rawData).hasSize(1);
+        SearchIndexableRaw item = rawData.get(0);
+        assertThat(item.key).isEqualTo(mController.getPreferenceKey());
+        assertThat(item.title).isEqualTo(DEFAULT_DEVICE_STATE_DESCRIPTION);
+        assertThat(item.screenTitle).isEqualTo(mContext.getString(R.string.accelerometer_title));
+    }
+
+    @Test
+    public void getSliceHighlightMenuRes_returnsMenuKeyDisplay() {
+        int sliceHighlightMenuRes = mController.getSliceHighlightMenuRes();
+
+        assertThat(sliceHighlightMenuRes).isEqualTo(R.string.menu_key_display);
+    }
+
+    @Test
+    public void isSliceable_returnsTrue() {
+        assertThat(mController.isSliceable()).isTrue();
+    }
+
+    @Test
+    public void isPublicSlice_returnsTrue() {
+        assertThat(mController.isPublicSlice()).isTrue();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/display/SmartAutoRotateControllerTest.java b/tests/robotests/src/com/android/settings/display/SmartAutoRotateControllerTest.java
index 778721a..4fec38b 100644
--- a/tests/robotests/src/com/android/settings/display/SmartAutoRotateControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/SmartAutoRotateControllerTest.java
@@ -39,7 +39,10 @@
 import androidx.preference.Preference;
 
 import com.android.settings.testutils.ResolveInfoBuilder;
+import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
+import com.android.settings.testutils.shadow.ShadowRotationPolicy;
 import com.android.settings.testutils.shadow.ShadowSensorPrivacyManager;
+import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -63,6 +66,8 @@
     @Mock
     private Preference mPreference;
     private ContentResolver mContentResolver;
+    private final DeviceStateRotationLockSettingsManager mDeviceStateAutoRotateSettingsManager =
+            DeviceStateRotationLockSettingsManager.getInstance(RuntimeEnvironment.application);
 
     @Before
     public void setUp() {
@@ -122,6 +127,34 @@
         assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
     }
 
+    @Test
+    @Config(shadows = {
+            ShadowDeviceStateRotationLockSettingsManager.class,
+            ShadowRotationPolicy.class
+    })
+    public void getAvailabilityStatus_deviceStateRotationLocked_returnDisableDependentSetting() {
+        enableDeviceStateRotation();
+        lockDeviceStateRotation();
+
+        int availabilityStatus = mController.getAvailabilityStatus();
+
+        assertThat(availabilityStatus).isEqualTo(DISABLED_DEPENDENT_SETTING);
+    }
+
+    @Test
+    @Config(shadows = {
+            ShadowDeviceStateRotationLockSettingsManager.class,
+            ShadowRotationPolicy.class
+    })
+    public void getAvailabilityStatus_deviceStateRotationUnlocked_returnAvailable() {
+        enableDeviceStateRotation();
+        unlockDeviceStateRotation();
+
+        int availabilityStatus = mController.getAvailabilityStatus();
+
+        assertThat(availabilityStatus).isEqualTo(AVAILABLE);
+    }
+
     private void enableAutoRotation() {
         Settings.System.putIntForUser(mContentResolver,
                 Settings.System.ACCELEROMETER_ROTATION, 1, UserHandle.USER_CURRENT);
@@ -131,4 +164,23 @@
         Settings.System.putIntForUser(mContentResolver,
                 Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT);
     }
+
+    private void enableDeviceStateRotation() {
+        ShadowRotationPolicy.setRotationSupported(true);
+        ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
+    }
+
+    private void lockDeviceStateRotation() {
+        mDeviceStateAutoRotateSettingsManager.updateSetting(
+                /* deviceState= */0, /* rotationLocked= */ true);
+        mDeviceStateAutoRotateSettingsManager.updateSetting(
+                /* deviceState= */1, /* rotationLocked= */ true);
+    }
+
+    private void unlockDeviceStateRotation() {
+        mDeviceStateAutoRotateSettingsManager.updateSetting(
+                /* deviceState= */0, /* rotationLocked= */ false);
+        mDeviceStateAutoRotateSettingsManager.updateSetting(
+                /* deviceState= */1, /* rotationLocked= */ true);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceControllerTest.java
index 068de34..39fdb04 100644
--- a/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceControllerTest.java
@@ -40,6 +40,7 @@
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.ResolveInfoBuilder;
+import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
 import com.android.settings.testutils.shadow.ShadowSensorPrivacyManager;
 
 import org.junit.Before;
@@ -53,7 +54,10 @@
 import org.robolectric.annotation.Config;
 
 @RunWith(RobolectricTestRunner.class)
-@Config(shadows = ShadowSensorPrivacyManager.class)
+@Config(shadows = {
+        ShadowSensorPrivacyManager.class,
+        ShadowDeviceStateRotationLockSettingsManager.class
+})
 public class SmartAutoRotatePreferenceControllerTest {
 
     private static final String PACKAGE_NAME = "package_name";
@@ -95,6 +99,7 @@
                 new SmartAutoRotatePreferenceController(mContext, "smart_auto_rotate"));
         when(mController.isCameraLocked()).thenReturn(false);
         when(mController.isPowerSaveMode()).thenReturn(false);
+        ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(false);
     }
 
     @Test
@@ -199,6 +204,16 @@
                 .UNSUPPORTED_ON_DEVICE);
     }
 
+
+    @Test
+    public void getAvailabilityStatus_deviceStateRotationEnabled_returnsUnsupported() {
+        enableAutoRotationPreference();
+        ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BasePreferenceController.UNSUPPORTED_ON_DEVICE);
+    }
+
     @Test
     public void isSliceableCorrectKey_returnsTrue() {
         final AutoRotatePreferenceController controller =
diff --git a/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceFragmentTest.java
index 877d2c1..942fed6 100644
--- a/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceFragmentTest.java
@@ -18,6 +18,8 @@
 
 import static com.android.settings.display.SmartAutoRotatePreferenceFragment.AUTO_ROTATE_SWITCH_PREFERENCE_ID;
 
+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.doReturn;
@@ -33,6 +35,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
+import android.content.res.Resources;
 import android.view.View;
 
 import androidx.preference.Preference;
@@ -40,7 +43,11 @@
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.testutils.ResolveInfoBuilder;
+import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
+import com.android.settings.testutils.shadow.ShadowRotationPolicy;
 import com.android.settings.widget.SettingsMainSwitchBar;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -49,8 +56,15 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.List;
 
 @RunWith(RobolectricTestRunner.class)
+@Config(shadows = {
+        ShadowDeviceStateRotationLockSettingsManager.class,
+        ShadowRotationPolicy.class
+})
 public class SmartAutoRotatePreferenceFragmentTest {
 
     private static final String PACKAGE_NAME = "package_name";
@@ -70,19 +84,24 @@
 
     @Mock
     private Preference mRotateSwitchPreference;
+    private Resources mResources;
+    private Context mContext;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
-        final Context context = spy(RuntimeEnvironment.application);
+        mContext = spy(RuntimeEnvironment.application);
         ContentResolver mContentResolver = RuntimeEnvironment.application.getContentResolver();
-        when(context.getPackageManager()).thenReturn(mPackageManager);
-        when(context.getContentResolver()).thenReturn(mContentResolver);
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
+        when(mContext.getContentResolver()).thenReturn(mContentResolver);
         doReturn(PACKAGE_NAME).when(mPackageManager).getRotationResolverPackageName();
         doReturn(PackageManager.PERMISSION_GRANTED).when(mPackageManager).checkPermission(
                 Manifest.permission.CAMERA, PACKAGE_NAME);
 
+        mResources = spy(mContext.getResources());
+        when(mContext.getResources()).thenReturn(mResources);
+
         final ResolveInfo resolveInfo = new ResolveInfoBuilder(PACKAGE_NAME).build();
         resolveInfo.serviceInfo = new ServiceInfo();
         when(mPackageManager.resolveService(any(), anyInt())).thenReturn(resolveInfo);
@@ -90,15 +109,16 @@
         mFragment = spy(new SmartAutoRotatePreferenceFragment());
         when(mActivity.getPackageManager()).thenReturn(mPackageManager);
         when(mFragment.getActivity()).thenReturn(mActivity);
-        when(mFragment.getContext()).thenReturn(context);
+        when(mFragment.getContext()).thenReturn(mContext);
         doReturn(mView).when(mFragment).getView();
 
         when(mFragment.findPreference(AUTO_ROTATE_SWITCH_PREFERENCE_ID)).thenReturn(
                 mRotateSwitchPreference);
 
-        mSwitchBar = spy(new SettingsMainSwitchBar(context));
+        mSwitchBar = spy(new SettingsMainSwitchBar(mContext));
         when(mActivity.getSwitchBar()).thenReturn(mSwitchBar);
         doReturn(mSwitchBar).when(mView).findViewById(R.id.switch_bar);
+        ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(false);
     }
 
 
@@ -111,6 +131,17 @@
     }
 
     @Test
+    public void createHeader_deviceStateRotationSupported_switchBarIsDisabled() {
+        ShadowRotationPolicy.setRotationSupported(true);
+        ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
+
+        mFragment.createHeader(mActivity);
+
+        verify(mSwitchBar, never()).show();
+        verify(mRotateSwitchPreference, never()).setVisible(false);
+    }
+
+    @Test
     public void createHeader_faceDetectionUnSupported_switchBarIsDisabled() {
         doReturn(null).when(mPackageManager).getRotationResolverPackageName();
 
@@ -120,4 +151,41 @@
         verify(mRotateSwitchPreference, never()).setVisible(false);
     }
 
+    @Test
+    public void createPreferenceControllers_noSettableDeviceStates_returnsEmptyList() {
+        enableDeviceStateSettableRotationStates(new String[]{}, new String[]{});
+
+        List<AbstractPreferenceController> preferenceControllers =
+                mFragment.createPreferenceControllers(mContext);
+
+        assertThat(preferenceControllers).isEmpty();
+    }
+
+    @Test
+    public void createPreferenceControllers_settableDeviceStates_returnsDeviceStateControllers() {
+        enableDeviceStateSettableRotationStates(new String[]{"0:1", "1:1"},
+                new String[]{"Folded", "Unfolded"});
+
+        List<AbstractPreferenceController> preferenceControllers =
+                mFragment.createPreferenceControllers(mContext);
+
+        assertThat(preferenceControllers).hasSize(2);
+        assertThat(preferenceControllers.get(0)).isInstanceOf(
+                DeviceStateAutoRotateSettingController.class);
+        assertThat(preferenceControllers.get(1)).isInstanceOf(
+                DeviceStateAutoRotateSettingController.class);
+    }
+
+    private void enableDeviceStateSettableRotationStates(String[] settableStates,
+            String[] settableStatesDescriptions) {
+        when(mResources.getStringArray(
+                com.android.internal.R.array.config_perDeviceStateRotationLockDefaults)).thenReturn(
+                settableStates);
+        when(mResources.getStringArray(
+                R.array.config_settableAutoRotationDeviceStatesDescriptions)).thenReturn(
+                settableStatesDescriptions);
+        DeviceStateRotationLockSettingsManager.resetInstance();
+        DeviceStateRotationLockSettingsManager.getInstance(mContext)
+                .resetStateForTesting(mResources);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/dream/DreamPickerControllerTest.java b/tests/robotests/src/com/android/settings/dream/DreamPickerControllerTest.java
index 043fc55..401ffe0 100644
--- a/tests/robotests/src/com/android/settings/dream/DreamPickerControllerTest.java
+++ b/tests/robotests/src/com/android/settings/dream/DreamPickerControllerTest.java
@@ -19,12 +19,9 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.content.ComponentName;
 import android.content.Context;
-import android.widget.Button;
 
 import androidx.preference.PreferenceScreen;
 import androidx.recyclerview.widget.RecyclerView;
@@ -93,19 +90,4 @@
         RecyclerView view = mPreference.findViewById(R.id.dream_list);
         assertThat(view.getAdapter().getItemCount()).isEqualTo(1);
     }
-
-    @Test
-    public void testPreviewButton() {
-        final DreamInfo mockDreamInfo = new DreamInfo();
-        mockDreamInfo.componentName = new ComponentName("package", "class");
-        mockDreamInfo.isActive = true;
-
-        when(mBackend.getDreamInfos()).thenReturn(Collections.singletonList(mockDreamInfo));
-        final DreamPickerController controller = buildController();
-        controller.updateState(mPreference);
-
-        Button view = mPreference.findViewById(R.id.preview_button);
-        view.performClick();
-        verify(mBackend).preview(mockDreamInfo);
-    }
 }
diff --git a/tests/robotests/src/com/android/settings/enterprise/AdminActionPreferenceControllerBaseTest.java b/tests/robotests/src/com/android/settings/enterprise/AdminActionPreferenceControllerBaseTest.java
index 8d5e4da..59e9e3c 100644
--- a/tests/robotests/src/com/android/settings/enterprise/AdminActionPreferenceControllerBaseTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/AdminActionPreferenceControllerBaseTest.java
@@ -18,13 +18,15 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-
-import java.util.Date;
 import org.robolectric.RobolectricTestRunner;
 
+import java.util.Date;
+
 @RunWith(RobolectricTestRunner.class)
+@Ignore
 public class AdminActionPreferenceControllerBaseTest
     extends AdminActionPreferenceControllerTestBase {
 
diff --git a/tests/robotests/src/com/android/settings/enterprise/AlwaysOnVpnCurrentUserPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/AlwaysOnVpnCurrentUserPreferenceControllerTest.java
index 2ff9d17..018a64a 100644
--- a/tests/robotests/src/com/android/settings/enterprise/AlwaysOnVpnCurrentUserPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/AlwaysOnVpnCurrentUserPreferenceControllerTest.java
@@ -28,6 +28,7 @@
 import com.android.settings.testutils.FakeFeatureFactory;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
@@ -36,6 +37,7 @@
 import org.robolectric.RobolectricTestRunner;
 
 @RunWith(RobolectricTestRunner.class)
+@Ignore
 public final class AlwaysOnVpnCurrentUserPreferenceControllerTest {
 
     private static final String VPN_SET_DEVICE = "VPN set";
diff --git a/tests/robotests/src/com/android/settings/enterprise/BugReportsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/BugReportsPreferenceControllerTest.java
index 34853c6..0b5261b 100644
--- a/tests/robotests/src/com/android/settings/enterprise/BugReportsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/BugReportsPreferenceControllerTest.java
@@ -20,6 +20,7 @@
 
 import static org.mockito.Mockito.when;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
@@ -27,6 +28,7 @@
 import java.util.Date;
 
 @RunWith(RobolectricTestRunner.class)
+@Ignore
 public class BugReportsPreferenceControllerTest
         extends AdminActionPreferenceControllerTestBase {
 
diff --git a/tests/robotests/src/com/android/settings/enterprise/CaCertsCurrentUserPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/CaCertsCurrentUserPreferenceControllerTest.java
index 799dd7e..130b3b9 100644
--- a/tests/robotests/src/com/android/settings/enterprise/CaCertsCurrentUserPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/CaCertsCurrentUserPreferenceControllerTest.java
@@ -25,11 +25,13 @@
 import com.android.settings.R;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
 
 @RunWith(RobolectricTestRunner.class)
+@Ignore
 public class CaCertsCurrentUserPreferenceControllerTest
     extends CaCertsPreferenceControllerTestBase {
 
diff --git a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
index e3f58f4..2b64c19 100644
--- a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
@@ -50,6 +50,7 @@
 import com.google.common.collect.ImmutableList;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentMatcher;
@@ -139,6 +140,7 @@
     }
 
     @Test
+    @Ignore
     public void testGetDeviceOwnerDisclosure() {
         when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(null);
         assertThat(mProvider.getDeviceOwnerDisclosure()).isNull();
diff --git a/tests/robotests/src/com/android/settings/enterprise/ImePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/ImePreferenceControllerTest.java
index facdce5..dc9fb0c 100644
--- a/tests/robotests/src/com/android/settings/enterprise/ImePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/ImePreferenceControllerTest.java
@@ -28,6 +28,7 @@
 import com.android.settings.testutils.FakeFeatureFactory;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
@@ -58,6 +59,7 @@
     }
 
     @Test
+    @Ignore
     public void testUpdateState() {
         final Preference preference = new Preference(mContext, null, 0, 0);
 
diff --git a/tests/robotests/src/com/android/settings/enterprise/NetworkLogsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/NetworkLogsPreferenceControllerTest.java
index 89c208c..466ec0e 100644
--- a/tests/robotests/src/com/android/settings/enterprise/NetworkLogsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/NetworkLogsPreferenceControllerTest.java
@@ -20,13 +20,15 @@
 
 import static org.mockito.Mockito.when;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-
-import java.util.Date;
 import org.robolectric.RobolectricTestRunner;
 
+import java.util.Date;
+
 @RunWith(RobolectricTestRunner.class)
+@Ignore
 public class NetworkLogsPreferenceControllerTest extends AdminActionPreferenceControllerTestBase {
 
     @Override
diff --git a/tests/robotests/src/com/android/settings/enterprise/PrivacyPreferenceControllerHelperTest.java b/tests/robotests/src/com/android/settings/enterprise/PrivacyPreferenceControllerHelperTest.java
index cbd6392e..e8a9e17 100644
--- a/tests/robotests/src/com/android/settings/enterprise/PrivacyPreferenceControllerHelperTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/PrivacyPreferenceControllerHelperTest.java
@@ -33,6 +33,7 @@
 import com.android.settings.testutils.FakeFeatureFactory;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
@@ -73,6 +74,7 @@
     }
 
     @Test
+    @Ignore
     public void testUpdateState_noDeviceOwnerName_useGenericPreferenceSummary() {
         final Preference preference = new Preference(mContext, null, 0, 0);
         when(mContext.getString(R.string.enterprise_privacy_settings_summary_generic))
@@ -86,6 +88,7 @@
     }
 
     @Test
+    @Ignore
     public void testUpdateState_deviceOwnerName_usePreferenceSummaryWithDeviceOwnerName() {
         final Preference preference = new Preference(mContext, null, 0, 0);
         when(mContext.getResources().getString(
diff --git a/tests/robotests/src/com/android/settings/enterprise/SecurityLogsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/SecurityLogsPreferenceControllerTest.java
index 8612ee7..98bc82b 100644
--- a/tests/robotests/src/com/android/settings/enterprise/SecurityLogsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/SecurityLogsPreferenceControllerTest.java
@@ -20,13 +20,15 @@
 
 import static org.mockito.Mockito.when;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-
-import java.util.Date;
 import org.robolectric.RobolectricTestRunner;
 
+import java.util.Date;
+
 @RunWith(RobolectricTestRunner.class)
+@Ignore
 public class SecurityLogsPreferenceControllerTest extends AdminActionPreferenceControllerTestBase {
 
     @Override
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java
index e63dd80..64dbbb2 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java
@@ -24,20 +24,26 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 
+import android.app.Activity;
+import android.app.PendingIntent;
 import android.content.Context;
+import android.content.Intent;
 import android.net.Uri;
 
+import androidx.core.graphics.drawable.IconCompat;
 import androidx.slice.Slice;
 import androidx.slice.SliceProvider;
 import androidx.slice.widget.SliceLiveData;
+import androidx.slice.builders.ListBuilder;
+import androidx.slice.builders.SliceAction;
 
+import com.android.settings.R;
 import com.android.settings.slices.CustomSliceRegistry;
-import com.android.settings.wifi.slice.ContextualWifiSlice;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 
@@ -48,6 +54,7 @@
 
     private Context mContext;
     private EligibleCardChecker mEligibleCardChecker;
+    private Activity mActivity;
 
     @Before
     public void setUp() {
@@ -55,22 +62,19 @@
         mEligibleCardChecker =
                 spy(new EligibleCardChecker(mContext, getContextualCard(TEST_SLICE_URI)));
         SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
+        mActivity = Robolectric.buildActivity(Activity.class).create().get();
     }
 
     @Test
-    @Ignore
     public void isSliceToggleable_cardWithToggle_returnTrue() {
-        final ContextualWifiSlice wifiSlice = new ContextualWifiSlice(mContext);
-        final Slice slice = wifiSlice.getSlice();
+        final Slice slice = buildSlice();
 
         assertThat(mEligibleCardChecker.isSliceToggleable(slice)).isTrue();
     }
 
     @Test
-    @Ignore
     public void isCardEligibleToDisplay_toggleSlice_hasInlineActionShouldBeTrue() {
-        final ContextualWifiSlice wifiSlice = new ContextualWifiSlice(mContext);
-        final Slice slice = wifiSlice.getSlice();
+        final Slice slice = buildSlice();
         doReturn(slice).when(mEligibleCardChecker).bindSlice(any(Uri.class));
 
         mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(TEST_SLICE_URI));
@@ -118,10 +122,8 @@
     }
 
     @Test
-    @Ignore
     public void isCardEligibleToDisplay_sliceNotNull_cacheSliceToCard() {
-        final ContextualWifiSlice wifiSlice = new ContextualWifiSlice(mContext);
-        final Slice slice = wifiSlice.getSlice();
+        final Slice slice = buildSlice();
         doReturn(slice).when(mEligibleCardChecker).bindSlice(any(Uri.class));
 
         mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(TEST_SLICE_URI));
@@ -137,4 +139,23 @@
                 .setSliceUri(sliceUri)
                 .build();
     }
+
+    private Slice buildSlice() {
+        final String title = "test_title";
+        final IconCompat icon = IconCompat.createWithResource(mActivity, R.drawable.empty_icon);
+        final PendingIntent pendingIntent = PendingIntent.getActivity(
+                mActivity,
+                title.hashCode() /* requestCode */,
+                new Intent("test action"),
+                PendingIntent.FLAG_IMMUTABLE);
+        final SliceAction action
+                = SliceAction.createDeeplink(pendingIntent, icon, ListBuilder.SMALL_IMAGE, title);
+        return new ListBuilder(mActivity, TEST_SLICE_URI, ListBuilder.INFINITY)
+                .addRow(new ListBuilder.RowBuilder()
+                        .addEndItem(icon, ListBuilder.ICON_IMAGE)
+                        .setTitle(title)
+                        .setPrimaryAction(action))
+                .addAction(SliceAction.createToggle(pendingIntent, null /* actionTitle */, true))
+                .build();
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragmentTest.java b/tests/robotests/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragmentTest.java
index c6c6a66..c6e7a97 100644
--- a/tests/robotests/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragmentTest.java
@@ -20,7 +20,9 @@
 
 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.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -31,6 +33,7 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.os.Bundle;
+import android.os.UserHandle;
 import android.provider.SearchIndexableResource;
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodManager;
@@ -43,6 +46,7 @@
 import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
 import com.android.settings.testutils.shadow.ShadowInputMethodManagerWithMethodList;
 import com.android.settings.testutils.shadow.ShadowSecureSettings;
+import com.android.settings.testutils.shadow.ShadowUserManager;
 import com.android.settingslib.inputmethod.InputMethodPreference;
 import com.android.settingslib.inputmethod.InputMethodSettingValuesWrapper;
 
@@ -62,7 +66,8 @@
 @RunWith(RobolectricTestRunner.class)
 @Config(shadows = {
         ShadowSecureSettings.class,
-        ShadowInputMethodManagerWithMethodList.class
+        ShadowInputMethodManagerWithMethodList.class,
+        ShadowUserManager.class
 })
 public class AvailableVirtualKeyboardFragmentTest {
 
@@ -170,6 +175,7 @@
         when(mFragment.getPreferenceScreen()).thenReturn(mPreferenceScreen);
         when(mPreferenceManager.getContext()).thenReturn(mContext);
         when(mContext.getSystemService(InputMethodManager.class)).thenReturn(mInputMethodManager);
+        doReturn(mContext).when(mContext).createContextAsUser(any(UserHandle.class), anyInt());
     }
 
     private List<InputMethodInfo> createFakeInputMethodInfoList(final String name, int num) {
diff --git a/tests/robotests/src/com/android/settings/network/EthernetTetherPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/EthernetTetherPreferenceControllerTest.java
index 8a81908..bf4811b 100644
--- a/tests/robotests/src/com/android/settings/network/EthernetTetherPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/EthernetTetherPreferenceControllerTest.java
@@ -31,6 +31,7 @@
 import androidx.test.core.app.ApplicationProvider;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -72,6 +73,7 @@
     }
 
     @Test
+    @Ignore
     public void lifecycle_shouldRegisterReceiverOnStart() {
         mController.onStart();
 
diff --git a/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
index fc6481b..dcf086c 100644
--- a/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
@@ -44,6 +44,8 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.Settings.MobileNetworkActivity;
+import com.android.settings.network.helper.SubscriptionAnnotation;
+import com.android.settings.network.helper.SubscriptionGrouping;
 import com.android.settings.widget.AddPreference;
 import com.android.settingslib.RestrictedLockUtils;
 
@@ -123,7 +125,6 @@
 
 
     @Test
-    @Ignore
     public void getSummary_noSubscriptions_correctSummaryAndClickHandler() {
         mController.displayPreference(mPreferenceScreen);
         mController.onResume();
@@ -212,23 +213,6 @@
     }
 
     @Test
-    @Ignore
-    public void getSummary_providerModel_Enabled() {
-        final SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
-        final SubscriptionInfo sub2 = mock(SubscriptionInfo.class);
-        when(sub1.getSubscriptionId()).thenReturn(1);
-        when(sub2.getSubscriptionId()).thenReturn(2);
-        when(sub1.getDisplayName()).thenReturn("sub1");
-        when(sub2.getDisplayName()).thenReturn("sub2");
-
-        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2));
-        SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2));
-        mController.displayPreference(mPreferenceScreen);
-        mController.onResume();
-        assertThat(mController.getSummary()).isEqualTo("sub1, sub2");
-    }
-
-    @Test
     public void addButton_noSubscriptionsNoEuiccMgr_noAddClickListener() {
         when(mEuiccManager.isEnabled()).thenReturn(false);
         mController.displayPreference(mPreferenceScreen);
@@ -319,7 +303,6 @@
     }
 
     @Test
-    @Ignore
     public void onAirplaneModeChanged_oneSubscriptionAirplaneModeGetsTurnedOn_isDisabled() {
         final SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
         SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1));
diff --git a/tests/robotests/src/com/android/settings/security/ChangeScreenLockPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/ChangeScreenLockPreferenceControllerTest.java
index 9913e55..60df553 100644
--- a/tests/robotests/src/com/android/settings/security/ChangeScreenLockPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/security/ChangeScreenLockPreferenceControllerTest.java
@@ -21,6 +21,7 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
@@ -35,11 +36,13 @@
 
 import com.android.internal.widget.LockPatternUtils;
 import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.shadow.ShadowUtils;
 import com.android.settings.widget.GearPreference;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -50,8 +53,11 @@
 
 @RunWith(RobolectricTestRunner.class)
 @Config(shadows = ShadowUtils.class)
+@Ignore
 public class ChangeScreenLockPreferenceControllerTest {
 
+    private static final int METRICS_CATEGORY = 1;
+
     @Mock
     private LockPatternUtils mLockPatternUtils;
     @Mock
@@ -78,7 +84,9 @@
         when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
         when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE))
                 .thenReturn(mDevicePolicyManager);
-        mController = new ChangeScreenLockPreferenceController(mContext, null  /* Host */ );
+        final SettingsPreferenceFragment host = mock(SettingsPreferenceFragment.class);
+        when(host.getMetricsCategory()).thenReturn(METRICS_CATEGORY);
+        mController = new ChangeScreenLockPreferenceController(mContext, host);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceControllerTest.java
index 29a62ea..72bdd39 100644
--- a/tests/robotests/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceControllerTest.java
@@ -21,13 +21,13 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.when;
 
+import android.content.ComponentName;
 import android.content.Context;
 
 import androidx.preference.Preference;
 
 import com.android.internal.widget.LockPatternUtils;
 import com.android.settings.R;
-import com.android.settings.security.trustagent.TrustAgentManager.TrustAgentComponentInfo;
 import com.android.settings.testutils.FakeFeatureFactory;
 
 import org.junit.Before;
@@ -46,8 +46,6 @@
 public class ManageTrustAgentsPreferenceControllerTest {
 
     @Mock
-    private TrustAgentManager mTrustAgentManager;
-    @Mock
     private LockPatternUtils mLockPatternUtils;
 
     private FakeFeatureFactory mFeatureFactory;
@@ -62,8 +60,6 @@
         mFeatureFactory = FakeFeatureFactory.setupForTest();
         when(mFeatureFactory.securityFeatureProvider.getLockPatternUtils(mContext))
                 .thenReturn(mLockPatternUtils);
-        when(mFeatureFactory.securityFeatureProvider.getTrustAgentManager())
-                .thenReturn(mTrustAgentManager);
         mController = new ManageTrustAgentsPreferenceController(mContext, "key");
         mPreference = new Preference(mContext);
         mPreference.setKey(mController.getPreferenceKey());
@@ -94,8 +90,7 @@
     @Test
     public void updateState_isSecure_noTrustAgent_shouldShowGenericSummary() {
         when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
-        when(mTrustAgentManager.getActiveTrustAgents(mContext, mLockPatternUtils))
-                .thenReturn(new ArrayList<>());
+        when(mLockPatternUtils.getEnabledTrustAgents(anyInt())).thenReturn(new ArrayList<>());
 
         mController.updateState(mPreference);
 
@@ -107,8 +102,8 @@
     @Test
     public void updateState_isSecure_hasTrustAgent_shouldShowDetailedSummary() {
         when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
-        when(mTrustAgentManager.getActiveTrustAgents(mContext, mLockPatternUtils))
-                .thenReturn(Collections.singletonList(new TrustAgentComponentInfo()));
+        when(mLockPatternUtils.getEnabledTrustAgents(anyInt())).thenReturn(
+                Collections.singletonList(new ComponentName("packageName", "className")));
 
         mController.updateState(mPreference);
 
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDeviceStateRotationLockSettingsManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDeviceStateRotationLockSettingsManager.java
new file mode 100644
index 0000000..72df3cc
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDeviceStateRotationLockSettingsManager.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 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.testutils.shadow;
+
+import android.content.Context;
+
+import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@Implements(DeviceStateRotationLockSettingsManager.class)
+public class ShadowDeviceStateRotationLockSettingsManager {
+
+    private static boolean sDeviceStateRotationLockEnabled;
+
+    @Implementation
+    public static boolean isDeviceStateRotationLockEnabled(Context context) {
+        return sDeviceStateRotationLockEnabled;
+    }
+
+    public static void setDeviceStateRotationLockEnabled(boolean enabled) {
+        sDeviceStateRotationLockEnabled = enabled;
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java
index 20547d7..74e3971 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java
@@ -40,7 +40,7 @@
     private static Map<Integer, Integer> sUserToProfileComplexityMap = new HashMap<>();
     private static Map<Integer, PasswordMetrics> sUserToMetricsMap = new HashMap<>();
     private static Map<Integer, PasswordMetrics> sUserToProfileMetricsMap = new HashMap<>();
-
+    private static Map<Integer, Boolean> sUserToIsSecureMap = new HashMap<>();
 
     @Resetter
     public static void reset() {
@@ -48,6 +48,7 @@
         sUserToProfileComplexityMap.clear();
         sUserToMetricsMap.clear();
         sUserToProfileMetricsMap.clear();
+        sUserToIsSecureMap.clear();
         sDeviceEncryptionEnabled = false;
     }
 
@@ -57,8 +58,16 @@
     }
 
     @Implementation
-    protected boolean isSecure(int id) {
-        return true;
+    protected boolean isSecure(int userId) {
+        Boolean isSecure = sUserToIsSecureMap.get(userId);
+        if (isSecure == null) {
+            return true;
+        }
+        return isSecure;
+    }
+
+    public static void setIsSecure(int userId, boolean isSecure) {
+        sUserToIsSecureMap.put(userId, isSecure);
     }
 
     @Implementation
@@ -144,4 +153,13 @@
         sUserToProfileMetricsMap.put(UserHandle.myUserId(), metrics);
     }
 
+    @Implementation
+    public boolean isLockScreenDisabled(int userId) {
+        return false;
+    }
+
+    @Implementation
+    public boolean isSeparateProfileChallengeEnabled(int userHandle) {
+        return false;
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
index dc42515..ea51370 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
@@ -44,6 +44,8 @@
 
     private static boolean sIsSupportsMultipleUsers;
 
+    private static final int PRIMARY_USER_ID = 0;
+
     private final List<String> mBaseRestrictions = new ArrayList<>();
     private final List<String> mGuestRestrictions = new ArrayList<>();
     private final Map<String, List<EnforcingUser>> mRestrictionSources = new HashMap<>();
@@ -218,4 +220,10 @@
             mEnabledTypes.remove(type);
         }
     }
+
+    @Implementation
+    protected UserInfo getPrimaryUser() {
+        return new UserInfo(PRIMARY_USER_ID, null, null,
+                UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY);
+    }
 }
diff --git a/tests/unit/src/com/android/settings/accessibility/FontWeightAdjustmentPreferenceControllerTest.java b/tests/unit/src/com/android/settings/accessibility/FontWeightAdjustmentPreferenceControllerTest.java
index 7f4048d..e3d2408 100644
--- a/tests/unit/src/com/android/settings/accessibility/FontWeightAdjustmentPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/accessibility/FontWeightAdjustmentPreferenceControllerTest.java
@@ -31,6 +31,9 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+/**
+ * Tests for {@link FontWeightAdjustmentPreferenceController}.
+ */
 @RunWith(AndroidJUnit4.class)
 public class FontWeightAdjustmentPreferenceControllerTest {
     private static final int ON = FontWeightAdjustmentPreferenceController.BOLD_TEXT_ADJUSTMENT;
@@ -91,4 +94,14 @@
         assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.FONT_WEIGHT_ADJUSTMENT, OFF)).isEqualTo(OFF);
     }
+
+    @Test
+    public void resetState_shouldDisableBoldText() {
+        mController.setChecked(true);
+
+        mController.resetState();
+
+        assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.FONT_WEIGHT_ADJUSTMENT, OFF)).isEqualTo(OFF);
+    }
 }
diff --git a/tests/unit/src/com/android/settings/accessibility/HighTextContrastPreferenceControllerTest.java b/tests/unit/src/com/android/settings/accessibility/HighTextContrastPreferenceControllerTest.java
index 6250fef..1ada051 100644
--- a/tests/unit/src/com/android/settings/accessibility/HighTextContrastPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/accessibility/HighTextContrastPreferenceControllerTest.java
@@ -31,6 +31,9 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+/**
+ * Tests for {@link HighTextContrastPreferenceController}.
+ */
 @RunWith(AndroidJUnit4.class)
 public class HighTextContrastPreferenceControllerTest {
 
@@ -93,4 +96,14 @@
         assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, UNKNOWN)).isEqualTo(OFF);
     }
+
+    @Test
+    public void resetState_shouldDisableTextContrast() {
+        mController.setChecked(true);
+
+        mController.resetState();
+
+        assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, UNKNOWN)).isEqualTo(OFF);
+    }
 }
diff --git a/tests/unit/src/com/android/settings/applications/appinfo/AppLocaleDetailsTest.java b/tests/unit/src/com/android/settings/applications/appinfo/AppLocaleDetailsTest.java
index ed4c127..0f9d54b 100644
--- a/tests/unit/src/com/android/settings/applications/appinfo/AppLocaleDetailsTest.java
+++ b/tests/unit/src/com/android/settings/applications/appinfo/AppLocaleDetailsTest.java
@@ -20,6 +20,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.LocaleManager;
@@ -32,7 +33,7 @@
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
-import com.google.common.collect.Iterables;
+import com.android.settingslib.widget.RadioButtonPreference;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -40,8 +41,14 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Locale;
 
+/**
+ * Unittest for ApplocaleDetails
+ * TODO Need to add a unittest for the UI preference component.
+ */
 @RunWith(AndroidJUnit4.class)
 public class AppLocaleDetailsTest {
     private static final String APP_PACKAGE_NAME = "app_package_name";
@@ -52,7 +59,7 @@
     private LocaleManager mLocaleManager;
 
     private Context mContext;
-    private LocaleList mSystemLocales;
+    private Collection<Locale> mSystemLocales;
     private LocaleList mAppLocale;
     private String[] mAssetLocales;
     private LocaleList mPackageLocales;
@@ -69,12 +76,48 @@
         when(mContext.getSystemService(LocaleManager.class)).thenReturn(mLocaleManager);
 
         setupInitialLocales(
-                /* appLocale= */ "en",
+                /* appLocale= */ "en-gb",
                 /* simCountry= */ "tw",
                 /* networkCountry= */ "jp",
-                /* systemLocales= */ "en, uk, jp, ne",
-                /* packageLocales= */ "pa, cn, tw, en",
-                /* assetLocales= */ new String[]{"en", "ne", "ms", "pa"});
+                /* systemLocales= */ "en-gb, ru, ja-jp, ne, zh-tw",
+                /* packageLocales= */ "pa, cn, zh-tw, en-gb, ja-jp",
+                /* assetLocales= */ new String[]{"en-gb", "ne", "ms", "pa", "zh-tw", "ja-jp"});
+    }
+
+    @Test
+    @UiThreadTest
+    public void onRadioButtonClicked_setCurrentLocaleToSystem() {
+        AppLocaleDetails appLocaleDetails = new AppLocaleDetails() {
+            @Override
+            void refreshUiInternal() {}
+        };
+        DummyAppLocaleDetailsHelper helper =
+                spy(new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME));
+        appLocaleDetails.mAppLocaleDetailsHelper = helper;
+        RadioButtonPreference pref = new RadioButtonPreference(mContext);
+        pref.setKey(AppLocaleDetails.KEY_SYSTEM_DEFAULT_LOCALE);
+
+        appLocaleDetails.onRadioButtonClicked(pref);
+
+        verify(helper).setAppDefaultLocale(LocaleList.forLanguageTags(""));
+    }
+
+    @Test
+    @UiThreadTest
+    public void onRadioButtonClicked_setCurrentLocaleForUserSelected() {
+        AppLocaleDetails appLocaleDetails = new AppLocaleDetails() {
+            @Override
+            void refreshUiInternal() {}
+        };
+        DummyAppLocaleDetailsHelper helper =
+                spy(new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME));
+        appLocaleDetails.mAppLocaleDetailsHelper = helper;
+        RadioButtonPreference pref = new RadioButtonPreference(mContext);
+        pref.setKey("en");
+
+        appLocaleDetails.onRadioButtonClicked(pref);
+
+        verify(helper).setAppDefaultLocale("en");
     }
 
     @Test
@@ -90,7 +133,7 @@
 
     @Test
     @UiThreadTest
-    public void handleAllLocalesData_1stLocaleOfSuggestedLocaleListIsAppLocale() {
+    public void handleAllLocalesData_1stLocaleIsAppLocaleAndHasSimAndNetwork() {
         Locale simCountryLocale = new Locale("zh", "TW");
         Locale networkCountryLocale = new Locale("ja", "JP");
         DummyAppLocaleDetailsHelper helper =
@@ -98,36 +141,122 @@
 
         helper.handleAllLocalesData();
 
-        Locale locale = Iterables.get(helper.getSuggestedLocales(), 0);
+        Collection<Locale> suggestedLocales = helper.getSuggestedLocales();
+        Locale locale = suggestedLocales.iterator().next();
         assertTrue(locale.equals(mAppLocale.get(0)));
-        assertTrue(helper.getSuggestedLocales().contains(simCountryLocale));
-        assertTrue(helper.getSuggestedLocales().contains(networkCountryLocale));
+        assertTrue(suggestedLocales.contains(simCountryLocale));
+        assertTrue(suggestedLocales.contains(networkCountryLocale));
     }
 
     @Test
     @UiThreadTest
-    public void handleAllLocalesData_withoutAppLocale_1stSuggestedLocaleIsSimCountryLocale() {
-        Locale simCountryLocale = new Locale("zh", "TW");
+    public void
+            handleAllLocalesData_noAppAndNoSupportedSimLocale_1stSuggestedLocaleIsAssetLocale() {
+        Locale firstAssetLocale = new Locale("en", "GB");
         setupInitialLocales(
                 /* appLocale= */ "",
                 /* simCountry= */ "tw",
                 /* networkCountry= */ "",
-                /* systemLocales= */ "en, uk, jp, ne",
+                /* systemLocales= */ "en-gb, ru, ja-jp, ne, zh-tw",
                 /* packageLocales= */ "",
-                /* assetLocales= */ new String[]{});
+                /* assetLocales= */ new String[]{"en-gb", "ne", "ms", "pa", "ja-jp"});
         DummyAppLocaleDetailsHelper helper =
                 new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME);
 
         helper.handleAllLocalesData();
 
-        Locale locale = Iterables.get(helper.getSuggestedLocales(), 0);
-        assertTrue(locale.equals(simCountryLocale));
-        assertFalse(helper.getSuggestedLocales().contains(mAppLocale.get(0)));
+        Collection<Locale> suggestedLocales = helper.getSuggestedLocales();
+        Locale locale = suggestedLocales.iterator().next();
+        assertTrue(locale.equals(firstAssetLocale));
     }
 
     @Test
     @UiThreadTest
-    public void handleAllLocalesData_withoutAppLocale_1stSuggestedLocaleIsNetworkCountryLocale() {
+    public void handleAllLocalesData_noAppButHasSupportedSimLocale_1stSuggestedLocaleIsSim() {
+        Locale simLocale = new Locale("zh", "tw");
+        setupInitialLocales(
+                /* appLocale= */ "",
+                /* simCountry= */ "tw",
+                /* networkCountry= */ "",
+                /* systemLocales= */ "en-gb, ru, ja-jp, ne, zh-tw",
+                /* packageLocales= */ "",
+                /* assetLocales= */ new String[]{"en-gb", "ne", "ms", "pa", "ja-jp", "zh-tw"});
+        DummyAppLocaleDetailsHelper helper =
+                new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME);
+
+        helper.handleAllLocalesData();
+
+        Collection<Locale> suggestedLocales = helper.getSuggestedLocales();
+        Locale locale = suggestedLocales.iterator().next();
+        assertTrue(locale.equals(simLocale));
+    }
+
+    @Test
+    @UiThreadTest
+    public void
+            handleAllLocalesData_noAppButHasSupportedNetworkLocale_1stSuggestedLocaleIsNetwork() {
+        Locale networkLocale = new Locale("ja", "JP");
+        setupInitialLocales(
+                /* appLocale= */ "",
+                /* simCountry= */ "",
+                /* networkCountry= */ "jp",
+                /* systemLocales= */ "en-gb, ru, ja-jp, ne, zh-tw",
+                /* packageLocales= */ "",
+                /* assetLocales= */ new String[]{"en-gb", "ne", "ms", "pa", "ja-jp"});
+        DummyAppLocaleDetailsHelper helper =
+                new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME);
+
+        helper.handleAllLocalesData();
+
+        Collection<Locale> suggestedLocales = helper.getSuggestedLocales();
+        Locale locale = suggestedLocales.iterator().next();
+        assertTrue(locale.equals(networkLocale));
+    }
+
+    @Test
+    @UiThreadTest
+    public void handleAllLocalesData_noAppSimOrNetworkLocale_suggestedLocalesHasSystemLocale() {
+        setupInitialLocales(
+                /* appLocale= */ "",
+                /* simCountry= */ "",
+                /* networkCountry= */ "",
+                /* systemLocales= */ "en-gb, ru, ja-jp, ne, zh-tw",
+                /* packageLocales= */ "",
+                /* assetLocales= */ new String[]{"en-gb", "ne", "ms", "pa", "zh-tw", "ja-jp"});
+        DummyAppLocaleDetailsHelper helper =
+                new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME);
+        helper.handleAllLocalesData();
+
+        Collection<Locale> suggestedLocales = helper.getSuggestedLocales();
+        assertTrue(suggestedLocales.contains(Locale.forLanguageTag("ne")));
+        // ru language is not present in the asset locales
+        assertFalse(suggestedLocales.contains(Locale.forLanguageTag("ru")));
+    }
+
+    @Test
+    @UiThreadTest
+    public void handleAllLocalesData_noAppButHasSimAndNetworkLocale_1stLocaleIsSimLocale() {
+        Locale simCountryLocale = new Locale("zh", "TW");
+        setupInitialLocales(
+                /* appLocale= */ "",
+                /* simCountry= */ "tw",
+                /* networkCountry= */ "jp",
+                /* systemLocales= */ "en-gb, ru, ja-jp, ne, zh-tw",
+                /* packageLocales= */ "",
+                /* assetLocales= */ new String[]{"en-gb", "ne", "ms", "pa", "zh-tw", "ja-jp"});
+
+        DummyAppLocaleDetailsHelper helper =
+                new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME);
+        helper.handleAllLocalesData();
+
+        Collection<Locale> suggestedLocales = helper.getSuggestedLocales();
+        Locale locale = suggestedLocales.iterator().next();
+        assertTrue(locale.equals(simCountryLocale));
+    }
+
+    @Test
+    @UiThreadTest
+    public void handleAllLocalesData_noSupportedLocale_noSuggestedLocales() {
         Locale networkCountryLocale = new Locale("en", "GB");
         setupInitialLocales(
                 /* appLocale= */ "",
@@ -141,28 +270,8 @@
 
         helper.handleAllLocalesData();
 
-        Locale locale = Iterables.get(helper.getSuggestedLocales(), 0);
-        assertTrue(locale.equals(networkCountryLocale));
-        assertFalse(helper.getSuggestedLocales().contains(mAppLocale.get(0)));
-    }
-
-    @Test
-    @UiThreadTest
-    public void handleAllLocalesData_noAppAndSimNetworkLocale_1stLocaleIsFirstOneInSystemLocales() {
-        setupInitialLocales(
-                /* appLocale= */ "",
-                /* simCountry= */ "",
-                /* networkCountry= */ "",
-                /* systemLocales= */ "en, uk, jp, ne",
-                /* packageLocales= */ "",
-                /* assetLocales= */ new String[]{});
-        DummyAppLocaleDetailsHelper helper =
-                new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME);
-
-        helper.handleAllLocalesData();
-
-        Locale locale = Iterables.get(helper.getSuggestedLocales(), 0);
-        assertTrue(locale.equals(mSystemLocales.get(0)));
+        Collection<Locale> suggestedLocales = helper.getSuggestedLocales();
+        assertTrue(suggestedLocales.size() == 0);
     }
 
     @Test
@@ -180,8 +289,10 @@
 
         helper.handleAllLocalesData();
 
-        Locale locale = Iterables.get(helper.getSuggestedLocales(), 0);
-        assertTrue(locale.equals(mSystemLocales.get(0)));
+        Collection<Locale> suggestedLocales = helper.getSuggestedLocales();
+        Locale locale = suggestedLocales.iterator().next();
+        Locale systemLocale = mSystemLocales.iterator().next();
+        assertTrue(locale.equals(systemLocale));
     }
 
     @Test
@@ -248,15 +359,23 @@
             String packageLocales,
             String[] assetLocales) {
         mAppLocale = LocaleList.forLanguageTags(appLocale);
-        mSystemLocales = LocaleList.forLanguageTags(systemLocales);
+        // forLanguageTags does not filter space to the input string. If there is any space included
+        // in string, this will make locale fail to generate.
+        systemLocales = systemLocales.replaceAll("\\s+", "");
+        LocaleList listOfSystemLocales = LocaleList.forLanguageTags(systemLocales);
+        mSystemLocales = new ArrayList<>();
+        for (int i = 0; i < listOfSystemLocales.size(); i++) {
+            mSystemLocales.add(listOfSystemLocales.get(i));
+        }
         mAssetLocales = assetLocales;
+        packageLocales = packageLocales.replaceAll("\\s+", "");
         mPackageLocales = LocaleList.forLanguageTags(packageLocales);
         when(mTelephonyManager.getSimCountryIso()).thenReturn(simCountry);
         when(mTelephonyManager.getNetworkCountryIso()).thenReturn(networkCountry);
         when(mLocaleManager.getApplicationLocales(anyString())).thenReturn(mAppLocale);
     }
 
-    private class DummyAppLocaleDetailsHelper
+    public class DummyAppLocaleDetailsHelper
             extends AppLocaleDetails.AppLocaleDetailsHelper {
 
         DummyAppLocaleDetailsHelper(Context context, String packageName) {
@@ -264,12 +383,12 @@
         }
 
         @Override
-        String[] getAssetSystemLocales() {
+        String[] getAssetLocales() {
             return mAssetLocales;
         }
 
         @Override
-        LocaleList getCurrentSystemLocales() {
+        Collection<Locale> getCurrentSystemLocales() {
             return mSystemLocales;
         }
 
diff --git a/tests/unit/src/com/android/settings/notification/OWNERS b/tests/unit/src/com/android/settings/notification/OWNERS
new file mode 100644
index 0000000..a2ae9ce
--- /dev/null
+++ b/tests/unit/src/com/android/settings/notification/OWNERS
@@ -0,0 +1,5 @@
+# Default reviewers for this and subdirectories.
+beverlyt@google.com
+dsandler@android.com
+juliacr@google.com
+yurilin@google.com
\ No newline at end of file
diff --git a/tests/unit/src/com/android/settings/safetycenter/BiometricsSafetySourceTest.java b/tests/unit/src/com/android/settings/safetycenter/BiometricsSafetySourceTest.java
new file mode 100644
index 0000000..f53d336
--- /dev/null
+++ b/tests/unit/src/com/android/settings/safetycenter/BiometricsSafetySourceTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2022 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.safetycenter;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class BiometricsSafetySourceTest {
+
+    private Context mApplicationContext;
+
+    @Mock
+    private SafetyCenterManagerWrapper mSafetyCenterManagerWrapper;
+
+    @Mock
+    private SafetyCenterStatusHolder mSafetyCenterStatusHolder;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mApplicationContext = ApplicationProvider.getApplicationContext();
+        SafetyCenterManagerWrapper.sInstance = mSafetyCenterManagerWrapper;
+        SafetyCenterStatusHolder.sInstance = mSafetyCenterStatusHolder;
+    }
+
+    @After
+    public void tearDown() {
+        SafetyCenterManagerWrapper.sInstance = null;
+        SafetyCenterStatusHolder.sInstance = null;
+    }
+
+    @Test
+    public void sendSafetyData_whenSafetyCenterIsDisabled_sendsNoData() {
+        when(mSafetyCenterStatusHolder.isEnabled(mApplicationContext)).thenReturn(false);
+
+        BiometricsSafetySource.sendSafetyData(mApplicationContext);
+
+        verify(mSafetyCenterManagerWrapper, never()).sendSafetyCenterUpdate(any(), any());
+    }
+
+    @Test
+    // TODO(b/215517420): Adapt this test when method is implemented.
+    public void sendSafetyData_whenSafetyCenterIsEnabled_sendsNoData() {
+        when(mSafetyCenterStatusHolder.isEnabled(mApplicationContext)).thenReturn(true);
+
+        BiometricsSafetySource.sendSafetyData(mApplicationContext);
+
+        verify(mSafetyCenterManagerWrapper, never()).sendSafetyCenterUpdate(any(), any());
+    }
+}
diff --git a/tests/unit/src/com/android/settings/safetycenter/LockScreenSafetySourceTest.java b/tests/unit/src/com/android/settings/safetycenter/LockScreenSafetySourceTest.java
new file mode 100644
index 0000000..052f981
--- /dev/null
+++ b/tests/unit/src/com/android/settings/safetycenter/LockScreenSafetySourceTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2022 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.safetycenter;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.safetycenter.SafetySourceData;
+import android.safetycenter.SafetySourceStatus;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.settings.SettingsActivity;
+import com.android.settings.password.ChooseLockGeneric;
+
+import org.junit.After;
+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 LockScreenSafetySourceTest {
+
+    private Context mApplicationContext;
+
+    @Mock
+    private SafetyCenterManagerWrapper mSafetyCenterManagerWrapper;
+
+    @Mock
+    private SafetyCenterStatusHolder mSafetyCenterStatusHolder;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mApplicationContext = ApplicationProvider.getApplicationContext();
+        SafetyCenterManagerWrapper.sInstance = mSafetyCenterManagerWrapper;
+        SafetyCenterStatusHolder.sInstance = mSafetyCenterStatusHolder;
+    }
+
+    @After
+    public void tearDown() {
+        SafetyCenterManagerWrapper.sInstance = null;
+        SafetyCenterStatusHolder.sInstance = null;
+    }
+
+    @Test
+    public void sendSafetyData_whenSafetyCenterIsDisabled_sendsNoData() {
+        when(mSafetyCenterStatusHolder.isEnabled(mApplicationContext)).thenReturn(false);
+
+        LockScreenSafetySource.sendSafetyData(mApplicationContext);
+
+        verify(mSafetyCenterManagerWrapper, never()).sendSafetyCenterUpdate(any(), any());
+    }
+
+    @Test
+    public void sendSafetyData_whenSafetyCenterIsEnabled_sendsPlaceholderData() {
+        when(mSafetyCenterStatusHolder.isEnabled(mApplicationContext)).thenReturn(true);
+
+        LockScreenSafetySource.sendSafetyData(mApplicationContext);
+        ArgumentCaptor<SafetySourceData> captor = ArgumentCaptor.forClass(SafetySourceData.class);
+        verify(mSafetyCenterManagerWrapper).sendSafetyCenterUpdate(any(), captor.capture());
+        SafetySourceData safetySourceData = captor.getValue();
+        SafetySourceStatus safetySourceStatus = safetySourceData.getStatus();
+
+        assertThat(safetySourceData.getId()).isEqualTo(LockScreenSafetySource.SAFETY_SOURCE_ID);
+        assertThat(safetySourceStatus.getTitle().toString()).isEqualTo("Lock Screen");
+        assertThat(safetySourceStatus.getSummary().toString())
+                .isEqualTo("Lock screen settings");
+        assertThat(safetySourceStatus.getStatusLevel())
+                .isEqualTo(SafetySourceStatus.STATUS_LEVEL_OK);
+        assertThat(safetySourceStatus.getPendingIntent()).isNotNull();
+        assertThat(safetySourceStatus.getPendingIntent().getIntent().getStringExtra(
+                SettingsActivity.EXTRA_SHOW_FRAGMENT))
+                .isEqualTo(ChooseLockGeneric.ChooseLockGenericFragment.class.getName());
+    }
+}
diff --git a/tests/unit/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiverTest.java b/tests/unit/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiverTest.java
new file mode 100644
index 0000000..8806e50
--- /dev/null
+++ b/tests/unit/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiverTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2022 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.safetycenter;
+
+import static android.safetycenter.SafetyCenterManager.EXTRA_REFRESH_SAFETY_SOURCE_IDS;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.Intent;
+import android.safetycenter.SafetySourceData;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.After;
+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 SafetySourceBroadcastReceiverTest {
+
+    private Context mApplicationContext;
+
+    @Mock
+    private SafetyCenterManagerWrapper mSafetyCenterManagerWrapper;
+
+    @Mock
+    private SafetyCenterStatusHolder mSafetyCenterStatusHolder;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mApplicationContext = ApplicationProvider.getApplicationContext();
+        SafetyCenterManagerWrapper.sInstance = mSafetyCenterManagerWrapper;
+        SafetyCenterStatusHolder.sInstance = mSafetyCenterStatusHolder;
+    }
+
+    @After
+    public void tearDown() {
+        SafetyCenterManagerWrapper.sInstance = null;
+        SafetyCenterStatusHolder.sInstance = null;
+    }
+
+    @Test
+    public void sendSafetyData_whenSafetyCenterIsDisabled_sendsNoData() {
+        when(mSafetyCenterStatusHolder.isEnabled(mApplicationContext)).thenReturn(false);
+        Intent intent =
+                new Intent().putExtra(
+                        EXTRA_REFRESH_SAFETY_SOURCE_IDS,
+                        new String[]{ LockScreenSafetySource.SAFETY_SOURCE_ID });
+
+        new SafetySourceBroadcastReceiver().onReceive(mApplicationContext, intent);
+
+        verify(mSafetyCenterManagerWrapper, never()).sendSafetyCenterUpdate(any(), any());
+    }
+
+    @Test
+    public void sendSafetyData_whenSafetyCenterIsEnabled_withNullSourceIds_sendsNoData() {
+        when(mSafetyCenterStatusHolder.isEnabled(mApplicationContext)).thenReturn(true);
+        Intent intent = new Intent();
+
+        new SafetySourceBroadcastReceiver().onReceive(mApplicationContext, intent);
+
+        verify(mSafetyCenterManagerWrapper, never()).sendSafetyCenterUpdate(any(), any());
+    }
+
+    @Test
+    public void sendSafetyData_whenSafetyCenterIsEnabled_withNoSourceIds_sendsNoData() {
+        when(mSafetyCenterStatusHolder.isEnabled(mApplicationContext)).thenReturn(true);
+        Intent intent = new Intent().putExtra(EXTRA_REFRESH_SAFETY_SOURCE_IDS, new String[]{});
+
+        new SafetySourceBroadcastReceiver().onReceive(mApplicationContext, intent);
+
+        verify(mSafetyCenterManagerWrapper, never()).sendSafetyCenterUpdate(any(), any());
+    }
+
+    @Test
+    public void sendSafetyData_withLockscreenSourceId_sendsLockscreenData() {
+        when(mSafetyCenterStatusHolder.isEnabled(mApplicationContext)).thenReturn(true);
+        Intent intent =
+                new Intent().putExtra(
+                        EXTRA_REFRESH_SAFETY_SOURCE_IDS,
+                        new String[]{ LockScreenSafetySource.SAFETY_SOURCE_ID });
+
+        new SafetySourceBroadcastReceiver().onReceive(mApplicationContext, intent);
+        ArgumentCaptor<SafetySourceData> captor = ArgumentCaptor.forClass(SafetySourceData.class);
+        verify(mSafetyCenterManagerWrapper, times(1))
+                .sendSafetyCenterUpdate(any(), captor.capture());
+        SafetySourceData safetySourceData = captor.getValue();
+
+        assertThat(safetySourceData.getId()).isEqualTo(LockScreenSafetySource.SAFETY_SOURCE_ID);
+    }
+
+    @Test
+    public void sendSafetyData_withBiometricsSourceId_sendsBiometricData() {
+        when(mSafetyCenterStatusHolder.isEnabled(mApplicationContext)).thenReturn(true);
+        Intent intent =
+                new Intent().putExtra(
+                        EXTRA_REFRESH_SAFETY_SOURCE_IDS,
+                        new String[]{ BiometricsSafetySource.SAFETY_SOURCE_ID });
+
+        new SafetySourceBroadcastReceiver().onReceive(mApplicationContext, intent);
+
+        // TODO(b/215517420): Update this test when BiometricSafetySource is implemented.
+        verify(mSafetyCenterManagerWrapper, never()).sendSafetyCenterUpdate(any(), any());
+    }
+}
diff --git a/tests/unit/src/com/android/settings/security/ScreenLockPreferenceDetailsUtilsTest.java b/tests/unit/src/com/android/settings/security/ScreenLockPreferenceDetailsUtilsTest.java
new file mode 100644
index 0000000..3d13b48
--- /dev/null
+++ b/tests/unit/src/com/android/settings/security/ScreenLockPreferenceDetailsUtilsTest.java
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2022 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.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.UserManager;
+import android.os.storage.StorageManager;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.SettingsActivity;
+import com.android.settings.password.ChooseLockGeneric;
+import com.android.settings.security.screenlock.ScreenLockSettings;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.ResourcesUtils;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+
+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 ScreenLockPreferenceDetailsUtilsTest {
+
+    private static final int SOURCE_METRICS_CATEGORY = 10;
+    private static final int USER_ID = 11;
+
+    @Mock
+    private LockPatternUtils mLockPatternUtils;
+    @Mock
+    private UserManager mUserManager;
+    @Mock
+    private DevicePolicyManager mDevicePolicyManager;
+    @Mock
+    private Resources mResources;
+    @Mock
+    private StorageManager mStorageManager;
+
+    private Context mContext;
+
+    private ScreenLockPreferenceDetailsUtils mScreenLockPreferenceDetailsUtils;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
+        when(mContext.getResources()).thenReturn(mResources);
+        when(mContext.getSystemService(StorageManager.class)).thenReturn(mStorageManager);
+        when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE))
+                .thenReturn(mDevicePolicyManager);
+        when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+        doNothing().when(mContext).startActivity(any());
+        when(mUserManager.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[] {});
+
+        final FakeFeatureFactory featureFactory = FakeFeatureFactory.setupForTest();
+        when(featureFactory.securityFeatureProvider.getLockPatternUtils(mContext))
+                .thenReturn(mLockPatternUtils);
+
+        mScreenLockPreferenceDetailsUtils =
+                new ScreenLockPreferenceDetailsUtils(mContext, SOURCE_METRICS_CATEGORY);
+    }
+
+    @Test
+    public void isAvailable_whenEnabled_shouldReturnTrue() {
+        whenConfigShowUnlockSetOrChangeIsEnabled(true);
+
+        assertThat(mScreenLockPreferenceDetailsUtils.isAvailable()).isTrue();
+    }
+
+    @Test
+    public void isAvailable_whenDisabled_shouldReturnFalse() {
+        whenConfigShowUnlockSetOrChangeIsEnabled(false);
+
+        assertThat(mScreenLockPreferenceDetailsUtils.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void getSummary_unsecureAndDisabledPattern_shouldReturnUnlockModeOff() {
+        final String summary = prepareString("unlock_set_unlock_mode_off", "unlockModeOff");
+
+        when(mLockPatternUtils.isSecure(USER_ID)).thenReturn(false);
+        when(mLockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(true);
+
+        assertThat(mScreenLockPreferenceDetailsUtils.getSummary(USER_ID)).isEqualTo(summary);
+    }
+
+    @Test
+    public void getSummary_unsecurePattern_shouldReturnUnlockModeNone() {
+        final String summary =
+                prepareString("unlock_set_unlock_mode_none", "unlockModeNone");
+
+        when(mLockPatternUtils.isSecure(USER_ID)).thenReturn(false);
+        when(mLockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false);
+
+        assertThat(mScreenLockPreferenceDetailsUtils.getSummary(USER_ID)).isEqualTo(summary);
+    }
+
+    @Test
+    public void getSummary_passwordQualitySomething_shouldUnlockModePattern() {
+        final String summary =
+                prepareString("unlock_set_unlock_mode_pattern", "unlockModePattern");
+
+        when(mLockPatternUtils.isSecure(USER_ID)).thenReturn(true);
+        when(mLockPatternUtils.getKeyguardStoredPasswordQuality(USER_ID))
+                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
+
+        assertThat(mScreenLockPreferenceDetailsUtils.getSummary(USER_ID)).isEqualTo(summary);
+    }
+
+    @Test
+    public void getSummary_passwordQualityNumeric_shouldUnlockModePin() {
+        final String summary =
+                prepareString("unlock_set_unlock_mode_pin", "unlockModePin");
+
+        when(mLockPatternUtils.isSecure(USER_ID)).thenReturn(true);
+        when(mLockPatternUtils.getKeyguardStoredPasswordQuality(USER_ID))
+                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
+
+        assertThat(mScreenLockPreferenceDetailsUtils.getSummary(USER_ID)).isEqualTo(summary);
+    }
+
+    @Test
+    public void getSummary_passwordQualityNumericComplex_shouldUnlockModePin() {
+        final String summary = prepareString("unlock_set_unlock_mode_pin", "unlockModePin");
+
+        when(mLockPatternUtils.isSecure(USER_ID)).thenReturn(true);
+        when(mLockPatternUtils.getKeyguardStoredPasswordQuality(USER_ID))
+                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX);
+
+        assertThat(mScreenLockPreferenceDetailsUtils.getSummary(USER_ID)).isEqualTo(summary);
+    }
+
+    @Test
+    public void getSummary_passwordQualityAlphabetic_shouldUnlockModePassword() {
+        final String summary =
+                prepareString("unlock_set_unlock_mode_password", "unlockModePassword");
+
+        when(mLockPatternUtils.isSecure(USER_ID)).thenReturn(true);
+        when(mLockPatternUtils.getKeyguardStoredPasswordQuality(USER_ID))
+                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC);
+
+        assertThat(mScreenLockPreferenceDetailsUtils.getSummary(USER_ID)).isEqualTo(summary);
+    }
+
+    @Test
+    public void getSummary_passwordQualityAlphanumeric_shouldUnlockModePassword() {
+        final String summary =
+                prepareString("unlock_set_unlock_mode_password", "unlockModePassword");
+
+        when(mLockPatternUtils.isSecure(USER_ID)).thenReturn(true);
+        when(mLockPatternUtils.getKeyguardStoredPasswordQuality(USER_ID))
+                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC);
+
+        assertThat(mScreenLockPreferenceDetailsUtils.getSummary(USER_ID)).isEqualTo(summary);
+    }
+
+    @Test
+    public void getSummary_passwordQualityComplex_shouldUnlockModePassword() {
+        final String summary =
+                prepareString("unlock_set_unlock_mode_password", "unlockModePassword");
+
+        when(mLockPatternUtils.isSecure(USER_ID)).thenReturn(true);
+        when(mLockPatternUtils.getKeyguardStoredPasswordQuality(USER_ID))
+                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_COMPLEX);
+
+        assertThat(mScreenLockPreferenceDetailsUtils.getSummary(USER_ID)).isEqualTo(summary);
+    }
+
+    @Test
+    public void getSummary_passwordQualityManaged_shouldUnlockModePassword() {
+        final String summary =
+                prepareString("unlock_set_unlock_mode_password", "unlockModePassword");
+
+        when(mLockPatternUtils.isSecure(USER_ID)).thenReturn(true);
+        when(mLockPatternUtils.getKeyguardStoredPasswordQuality(USER_ID))
+                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_MANAGED);
+
+        assertThat(mScreenLockPreferenceDetailsUtils.getSummary(USER_ID)).isEqualTo(summary);
+    }
+
+
+    @Test
+    public void getSummary_unsupportedPasswordQuality_shouldReturnNull() {
+        when(mLockPatternUtils.isSecure(USER_ID)).thenReturn(true);
+        when(mLockPatternUtils.getKeyguardStoredPasswordQuality(USER_ID))
+                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
+
+        assertNull(mScreenLockPreferenceDetailsUtils.getSummary(USER_ID));
+    }
+
+    @Test
+    public void isPasswordQualityManaged_withoutAdmin_shouldReturnFalse() {
+        final RestrictedLockUtils.EnforcedAdmin admin = null;
+
+        assertThat(mScreenLockPreferenceDetailsUtils.isPasswordQualityManaged(USER_ID, admin))
+                .isFalse();
+    }
+
+    @Test
+    public void isPasswordQualityManaged_passwordQualityIsManaged_shouldReturnTrue() {
+        final RestrictedLockUtils.EnforcedAdmin admin = new RestrictedLockUtils.EnforcedAdmin();
+
+        when(mDevicePolicyManager.getPasswordQuality(admin.component, USER_ID))
+                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_MANAGED);
+
+        assertThat(mScreenLockPreferenceDetailsUtils.isPasswordQualityManaged(USER_ID, admin))
+                .isTrue();
+    }
+
+    @Test
+    public void isPasswordQualityManaged_passwordQualityIsNotManaged_shouldReturnFalse() {
+        final RestrictedLockUtils.EnforcedAdmin admin = new RestrictedLockUtils.EnforcedAdmin();
+
+        when(mDevicePolicyManager.getPasswordQuality(admin.component, USER_ID))
+                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
+
+        assertThat(mScreenLockPreferenceDetailsUtils.isPasswordQualityManaged(USER_ID, admin))
+                .isFalse();
+    }
+
+    @Test
+    public void shouldShowGearMenu_patternIsSecure_shouldReturnTrue() {
+        when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
+
+        assertThat(mScreenLockPreferenceDetailsUtils.shouldShowGearMenu()).isTrue();
+    }
+
+    @Test
+    public void shouldShowGearMenu_patternIsNotSecure_shouldReturnFalse() {
+        when(mLockPatternUtils.isSecure(anyInt())).thenReturn(false);
+
+        assertThat(mScreenLockPreferenceDetailsUtils.shouldShowGearMenu()).isFalse();
+    }
+
+    @Test
+    public void openScreenLockSettings_shouldSendIntent() {
+        mScreenLockPreferenceDetailsUtils.openScreenLockSettings();
+
+        assertFragmentLaunchRequested(ScreenLockSettings.class.getName());
+    }
+
+    @Test
+    public void openChooseLockGenericFragment_noQuietMode_shouldSendIntent_shouldReturnTrue() {
+        when(mUserManager.isQuietModeEnabled(any())).thenReturn(false);
+
+        assertThat(mScreenLockPreferenceDetailsUtils.openChooseLockGenericFragment()).isTrue();
+        assertFragmentLaunchRequested(ChooseLockGeneric.ChooseLockGenericFragment.class.getName());
+    }
+
+    private void whenConfigShowUnlockSetOrChangeIsEnabled(boolean enabled) {
+        final int resId = ResourcesUtils.getResourcesId(
+                ApplicationProvider.getApplicationContext(), "bool",
+                "config_show_unlock_set_or_change");
+        when(mResources.getBoolean(resId)).thenReturn(enabled);
+    }
+
+    private String prepareString(String stringResName, String string) {
+        final int stringResId = ResourcesUtils.getResourcesId(
+                ApplicationProvider.getApplicationContext(), "string", stringResName);
+        when(mResources.getString(stringResId)).thenReturn(string);
+        return string;
+    }
+
+    private void assertFragmentLaunchRequested(String fragmentClassName) {
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mContext).startActivity(intentCaptor.capture());
+
+        Intent intent = intentCaptor.getValue();
+        assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
+                .isEqualTo(fragmentClassName);
+        assertThat(intent.getIntExtra(
+                MetricsFeatureProvider.EXTRA_SOURCE_METRICS_CATEGORY, -1 /* defaultValue */))
+                .isEqualTo(SOURCE_METRICS_CATEGORY);
+    }
+}