Merge "New feature “Text and reading options” for SetupWizard, Wallpaper, and Settings (4/n)."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 9c6b97a..66e4442 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1423,8 +1423,7 @@
         <activity
             android:name=".datausage.AppDataUsageActivity"
             android:exported="true"
-            android:noHistory="true"
-            android:permission="android.permission.QUERY_ALL_PACKAGES">
+            android:noHistory="true">
             <intent-filter android:priority="1">
                 <action android:name="android.settings.IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS" />
                 <category android:name="android.intent.category.DEFAULT" />
@@ -1494,7 +1493,6 @@
         <activity-alias android:name=".applications.InstalledAppDetails"
                 android:label="@string/application_info_label"
                 android:exported="true"
-                android:permission="android.permission.QUERY_ALL_PACKAGES"
                 android:targetActivity=".applications.InstalledAppDetailsTop">
             <intent-filter android:priority="1">
                 <action android:name="android.settings.APPLICATION_DETAILS_SETTINGS" />
@@ -1506,8 +1504,7 @@
 
         <activity android:name=".applications.InstalledAppOpenByDefaultActivity"
                   android:label="@string/application_info_label"
-                  android:exported="true"
-                  android:permission="android.permission.QUERY_ALL_PACKAGES">
+                  android:exported="true">
             <intent-filter android:priority="1">
                 <action android:name="android.settings.APP_OPEN_BY_DEFAULT_SETTINGS" />
                 <!-- Also catch legacy "com." prefixed action. -->
@@ -1864,8 +1861,7 @@
         <activity
             android:name="Settings$AppUsageAccessSettingsActivity"
             android:exported="true"
-            android:label="@string/usage_access_title"
-            android:permission="android.permission.QUERY_ALL_PACKAGES">
+            android:label="@string/usage_access_title">
             <intent-filter>
                 <action android:name="android.settings.USAGE_ACCESS_SETTINGS"/>
                 <category android:name="android.intent.category.DEFAULT"/>
@@ -3980,7 +3976,7 @@
             android:theme="@style/Transparent"
             android:permission="android.permission.DUMP"
             android:excludeFromRecents="true"
-            android:enabled="@bool/config_has_help" />
+            android:enabled="@*android:bool/config_settingsHelpLinksEnabled" />
 
         <activity android:name=".applications.autofill.AutofillPickerActivity"
                 android:excludeFromRecents="true"
diff --git a/color-check-baseline.xml b/color-check-baseline.xml
index 38e3e20..3fced11 100644
--- a/color-check-baseline.xml
+++ b/color-check-baseline.xml
@@ -21,6 +21,38 @@
         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="            &lt;solid android:color=&quot;#BCEDDF&quot;/>"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/drawable/accessibility_qs_tooltips_background.xml"
+            line="22"
+            column="20"/>
+    </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="            &lt;solid android:color=&quot;#BCEDDF&quot;/>"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/drawable/accessibility_qs_tooltips_background.xml"
+            line="35"
+            column="20"/>
+    </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:startColor=&quot;#4D000000&quot;"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -2968,6 +3000,22 @@
         errorLine1="            android:color=&quot;@color/accessibility_feature_background&quot;/>"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
+            file="res/drawable/ic_adaptive_font_download.xml"
+            line="23"
+            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:color=&quot;@color/accessibility_feature_background&quot;/>"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
             file="res/drawable/ic_audio_adjustment.xml"
             line="22"
             column="13"/>
@@ -3221,22 +3269,6 @@
         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_adaptive_font_download.xml"
-            line="23"
-            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:color=&quot;@color/homepage_about_background&quot; />"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -4633,7 +4665,7 @@
         errorLine2="                                                               ~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values-en-rAU/strings.xml"
-            line="3092"
+            line="3104"
             column="64"/>
     </issue>
 
@@ -4649,7 +4681,7 @@
         errorLine2="                                                               ~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values-en-rCA/strings.xml"
-            line="3092"
+            line="3104"
             column="64"/>
     </issue>
 
@@ -4665,7 +4697,7 @@
         errorLine2="                                                               ~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values-en-rGB/strings.xml"
-            line="3092"
+            line="3104"
             column="64"/>
     </issue>
 
@@ -4681,7 +4713,7 @@
         errorLine2="                                                               ~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values-en-rIN/strings.xml"
-            line="3092"
+            line="3104"
             column="64"/>
     </issue>
 
@@ -4697,7 +4729,7 @@
         errorLine2="                                                                                                                                                                         ~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values-en-rXC/strings.xml"
-            line="3092"
+            line="3104"
             column="170"/>
     </issue>
 
@@ -4713,7 +4745,7 @@
         errorLine2="                                   ~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/strings.xml"
-            line="7103"
+            line="7142"
             column="36"/>
     </issue>
 
@@ -4745,7 +4777,7 @@
         errorLine2="                                        ^">
         <location
             file="res/values-night/themes.xml"
-            line="37"
+            line="33"
             column="41"/>
     </issue>
 
@@ -4761,7 +4793,7 @@
         errorLine2="                                        ^">
         <location
             file="res/values-night/themes.xml"
-            line="37"
+            line="33"
             column="41"/>
     </issue>
 
@@ -4841,7 +4873,7 @@
         errorLine2="                                            ^">
         <location
             file="res/values/themes.xml"
-            line="185"
+            line="192"
             column="45"/>
     </issue>
 
@@ -4857,7 +4889,7 @@
         errorLine2="                                                ^">
         <location
             file="res/values/themes.xml"
-            line="186"
+            line="193"
             column="49"/>
     </issue>
 
@@ -4873,7 +4905,7 @@
         errorLine2="                                            ^">
         <location
             file="res/values/themes.xml"
-            line="194"
+            line="201"
             column="45"/>
     </issue>
 
@@ -4889,7 +4921,7 @@
         errorLine2="                                                ^">
         <location
             file="res/values/themes.xml"
-            line="195"
+            line="202"
             column="49"/>
     </issue>
 
diff --git a/libs/window_ext_lib.aar b/libs/window_ext_lib.aar
index ca58b36..d34afbd 100644
--- a/libs/window_ext_lib.aar
+++ b/libs/window_ext_lib.aar
Binary files differ
diff --git a/res/drawable/accessibility_qs_tooltips_background.xml b/res/drawable/accessibility_qs_tooltips_background.xml
new file mode 100644
index 0000000..a704b2e
--- /dev/null
+++ b/res/drawable/accessibility_qs_tooltips_background.xml
@@ -0,0 +1,39 @@
+<?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.
+-->
+
+<layer-list
+    xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:top="8dp">
+        <shape
+            android:shape="rectangle">
+            <solid android:color="#BCEDDF"/>
+            <corners android:radius="28dp" />
+            <padding android:top="8dp" />
+        </shape>
+    </item>
+
+    <item
+        android:width="12dp"
+        android:height="12dp"
+        android:gravity="top|center_horizontal"
+        android:top="-6dp">
+        <rotate android:fromDegrees="45">
+            <shape android:shape="rectangle">
+            <solid android:color="#BCEDDF"/>
+            </shape>
+        </rotate>
+    </item>
+</layer-list>
\ No newline at end of file
diff --git a/res/drawable/accessibility_qs_tooltips_illustration.xml b/res/drawable/accessibility_qs_tooltips_illustration.xml
new file mode 100644
index 0000000..64245f1
--- /dev/null
+++ b/res/drawable/accessibility_qs_tooltips_illustration.xml
@@ -0,0 +1,52 @@
+<?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.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="181dp"
+    android:height="86dp"
+    android:viewportWidth="181"
+    android:viewportHeight="86">
+  <group>
+    <clip-path
+        android:pathData="M0,0h181v86h-181z"/>
+    <path
+        android:pathData="M17.388,4.007L162.381,4.007A13,13 0,0 1,175.381 17.007L175.381,323.989A13,13 0,0 1,162.381 336.989L17.388,336.989A13,13 0,0 1,4.388 323.989L4.388,17.007A13,13 0,0 1,17.388 4.007z"
+        android:strokeWidth="6"
+        android:fillColor="#ffffff"
+        android:strokeColor="#EDEDED"/>
+  </group>
+  <path
+      android:pathData="M21.548,23.014L158.221,23.014A3.078,3.078 0,0 1,161.299 26.092L161.299,26.092A3.078,3.078 0,0 1,158.221 29.17L21.548,29.17A3.078,3.078 0,0 1,18.469 26.092L18.469,26.092A3.078,3.078 0,0 1,21.548 23.014z"
+      android:fillColor="#EDEDED"/>
+  <path
+      android:pathData="M24.469,43.946L78.959,43.946A6,6 0,0 1,84.959 49.946L84.959,68.728A6,6 0,0 1,78.959 74.728L24.469,74.728A6,6 0,0 1,18.469 68.728L18.469,49.946A6,6 0,0 1,24.469 43.946z"
+      android:fillColor="#EDEDED"/>
+  <path
+      android:pathData="M100.81,43.946L155.299,43.946A6,6 0,0 1,161.299 49.946L161.299,68.728A6,6 0,0 1,155.299 74.728L100.81,74.728A6,6 0,0 1,94.81 68.728L94.81,49.946A6,6 0,0 1,100.81 43.946z"
+      android:fillColor="#E0DCDC"/>
+  <path
+      android:pathData="M100.81,43.946L155.299,43.946A6,6 0,0 1,161.299 49.946L161.299,68.728A6,6 0,0 1,155.299 74.728L100.81,74.728A6,6 0,0 1,94.81 68.728L94.81,49.946A6,6 0,0 1,100.81 43.946z"
+      android:fillColor="#797272"/>
+  <path
+      android:pathData="M104.197,55.027L110.047,55.027A2,2 0,0 1,112.047 57.027L112.047,62.878A2,2 0,0 1,110.047 64.878L104.197,64.878A2,2 0,0 1,102.197 62.878L102.197,57.027A2,2 0,0 1,104.197 55.027z"
+      android:fillColor="#ffffff"/>
+  <path
+      android:pathData="M117.588,53.796L139.751,53.796A1.847,1.847 0,0 1,141.598 55.643L141.598,55.643A1.847,1.847 0,0 1,139.751 57.49L117.588,57.49A1.847,1.847 0,0 1,115.741 55.643L115.741,55.643A1.847,1.847 0,0 1,117.588 53.796z"
+      android:fillColor="#ffffff"/>
+  <path
+      android:pathData="M117.588,62.415L152.064,62.415A1.847,1.847 0,0 1,153.911 64.262L153.911,64.262A1.847,1.847 0,0 1,152.064 66.109L117.588,66.109A1.847,1.847 0,0 1,115.741 64.262L115.741,64.262A1.847,1.847 0,0 1,117.588 62.415z"
+      android:fillColor="#C8C5C5"/>
+</vector>
diff --git a/res/layout/accessibility_qs_tooltips.xml b/res/layout/accessibility_qs_tooltips.xml
new file mode 100644
index 0000000..85d9c52
--- /dev/null
+++ b/res/layout/accessibility_qs_tooltips.xml
@@ -0,0 +1,42 @@
+<?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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:gravity="center"
+    android:orientation="vertical"
+    android:background="@drawable/accessibility_qs_tooltips_background">
+
+    <ImageView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingTop="@dimen/accessibility_qs_tooltips_margin_top"
+        android:src="@drawable/accessibility_qs_tooltips_illustration"
+        android:layout_gravity="center_horizontal"
+        android:contentDescription="@null" />
+
+    <TextView
+        android:id="@+id/qs_content"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:padding="@dimen/accessibility_qs_tooltips_margin"
+        android:textColor="@android:color/black"
+        android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
+        android:textSize="16sp" />
+
+</LinearLayout>
diff --git a/res/values/config.xml b/res/values/config.xml
index 48d698c..fe9f42d 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -312,9 +312,6 @@
     <!-- Whether swipe security option is hidden or not -->
     <bool name="config_hide_swipe_security_option">false</bool>
 
-    <!--Whether help links are defined. -->
-    <bool name="config_has_help">false</bool>
-
     <!-- Whether Wi-Fi settings should be shown or not.
     This also controls whether Wi-fi related sub-settings (e.g. Wi-Fi preferences) will
     surface in search results or not.-->
@@ -560,4 +557,7 @@
     
     <!-- Whether to aggregate for network selection list-->
     <bool name="config_network_selection_list_aggregation_enabled">false</bool>
+
+    <!-- Whether to give option to add restricted profiles -->
+    <bool name="config_offer_restricted_profiles">false</bool>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 94de83b..05b949e 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -297,6 +297,10 @@
     <dimen name="accessibility_icon_size">32dp</dimen>
     <dimen name="accessibility_icon_foreground_size">18dp</dimen>
 
+    <!-- Accessibility quick settings tooltips -->
+    <dimen name="accessibility_qs_tooltips_margin">20dp</dimen>
+    <dimen name="accessibility_qs_tooltips_margin_top">27dp</dimen>
+
     <!-- Restricted icon in switch bar -->
     <dimen name="restricted_icon_margin_end">16dp</dimen>
     <!-- Restricted icon size in switch bar -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6240175..3271949 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -5565,8 +5565,10 @@
     <string name="accessibility_autoclick_longer_desc">Longer</string>
     <!-- Description for the seekbar that adjust auto click time. [CHAR_LIMIT=NONE] -->
     <string name="accessibility_autoclick_seekbar_desc">Auto click time</string>
-    <!-- Title for accessibility preference screen for configuring vibrations. -->
+    <!-- Title for preference screen for configuring vibrations. [CHAR LIMIT=NONE] -->
     <string name="accessibility_vibration_settings_title">Vibration &amp; haptics</string>
+    <!-- Summary for preference screen for configuring vibrations. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_vibration_settings_summary">Control the vibration strength for different usages</string>
     <!-- Title for the category of preferences to configure device vibrations related to calls. [CHAR LIMIT=NONE] -->
     <string name="accessibility_call_vibration_category_title">Calls</string>
     <!-- Title for the category of preferences to configure device vibrations related to notifications and alarms. [CHAR LIMIT=NONE] -->
@@ -5583,6 +5585,8 @@
     <string name="accessibility_service_primary_switch_title">Use <xliff:g id="accessibility_app_name" example="TalkBack">%1$s</xliff:g></string>
     <!-- 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>
     <!-- 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] -->
@@ -5734,33 +5738,6 @@
         <item quantity="other"><xliff:g id="click_delay_label">%1$s</xliff:g> seconds</item>
     </plurals>
 
-    <!-- Summary for vibration settings preference when notification vibration and haptic feedback intensity are set. [CHAR LIMIT=50] -->
-    <string name="accessibility_vibration_summary">Ring <xliff:g id="summary_ring" example="Medium">%1$s</xliff:g>, notification <xliff:g id="summary_notification" example="Low">%2$s</xliff:g>, touch <xliff:g id="summary_touch" example="High">%3$s</xliff:g></string>
-
-    <!-- Summary for vibration settings preference when ring & notification are set to off-->
-    <string name="accessibility_vibration_summary_off">Ring &amp; notification set to off</string>
-
-    <!-- Summary for vibration settings preference when ring & notification are set to low-->
-    <string name="accessibility_vibration_summary_low">Ring &amp; notification set to low</string>
-
-    <!-- Summary for vibration settings preference when ring & notification are set to medium-->
-    <string name="accessibility_vibration_summary_medium">Ring &amp; notification set to medium</string>
-
-    <!-- Summary for vibration settings preference when ring & notification are set to high-->
-    <string name="accessibility_vibration_summary_high">Ring &amp; notification set to high</string>
-
-    <!-- Label describing an option turning vibrations off. [CHAR LIMIT=15] -->
-    <string name="accessibility_vibration_intensity_off">Off</string>
-
-    <!-- Label describing a low intensity vibration option. [CHAR LIMIT=15] -->
-    <string name="accessibility_vibration_intensity_low">Low</string>
-
-    <!-- Label describing a medium intensity vibration option. [CHAR LIMIT=15] -->
-    <string name="accessibility_vibration_intensity_medium">Medium</string>
-
-    <!-- Label describing a high intensity vibration option. [CHAR LIMIT=15] -->
-    <string name="accessibility_vibration_intensity_high">High</string>
-
     <!-- Title for accessibility menu item to launch a settings activity. [CHAR LIMIT=15] -->
     <string name="accessibility_menu_item_settings">Settings</string>
 
@@ -8425,6 +8402,8 @@
     <string name="keywords_touch_vibration">haptics, vibrate, screen, sensitivity</string>
     <!-- List of synonyms for ring vibration setting (changes whether your phone vibrates when it rings), used to match in settings search [CHAR LIMIT=NONE] -->
     <string name="keywords_ring_vibration">haptics, vibrate, phone, call, sensitivity, ring</string>
+    <!-- List of synonyms for ring vibration setting (changes whether your phone vibrates when it rings), used to match in settings search [CHAR LIMIT=NONE] -->
+    <string name="keywords_ramping_ringer_vibration">haptics, vibrate, phone, call, ring, gradually</string>
     <!-- List of synonyms for notification vibration setting (changes whether your phone vibrates when it shows a notification), used to match in settings search [CHAR LIMIT=NONE] -->
     <string name="keywords_notification_vibration">haptics, vibrate, sensitivity</string>
     <!-- List of synonyms for vibration and haptics setting, used to match in settings search [CHAR LIMIT=NONE] -->
@@ -13366,7 +13345,7 @@
     <string name="lockscreen_privacy_wallet_summary">Allow access to wallet from lock screen and quick settings</string>
 
     <!-- QR Code Scanner toggle name [CHAR LIMIT=60] -->
-    <string name="lockscreen_privacy_qr_code_scanner_setting_toggle">Show QR Scanner</string>
+    <string name="lockscreen_privacy_qr_code_scanner_setting_toggle">Show QR scanner</string>
     <!-- QR Code Scanner summary [CHAR LIMIT=NONE] -->
     <string name="lockscreen_privacy_qr_code_scanner_summary">Allow access to QR scanner from lock screen</string>
 
@@ -13549,6 +13528,8 @@
     <string name="mobile_data_disable_message">You won\’t have access to data or the internet through <xliff:g id="carrier" example="T-Mobile">%s</xliff:g>. Internet will only be available via Wi\u2011Fi.</string>
     <!-- Text used to refer to the user's current carrier in mobile_data_disable_message if the users's mobile network carrier name is not available [CHAR LIMIT=NONE] -->
     <string name="mobile_data_disable_message_default_carrier">your carrier</string>
+    <!-- Summary for enterprise restriction not allow to use [CHAR LIMIT=NONE] -->
+    <string name="not_allowed_by_ent">Not allowed by your organization</string>
 
     <!-- Summary for preference when Bedtime mode is on [CHAR LIMIT=NONE] -->
     <string name="aware_summary_when_bedtime_on">Unavailable because bedtime mode is on</string>
diff --git a/res/xml/accessibility_notification_vibration_settings.xml b/res/xml/accessibility_notification_vibration_settings.xml
deleted file mode 100644
index b37d363..0000000
--- a/res/xml/accessibility_notification_vibration_settings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2018 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<PreferenceScreen
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:title="@string/accessibility_notification_vibration_title" />
diff --git a/res/xml/accessibility_ring_vibration_settings.xml b/res/xml/accessibility_ring_vibration_settings.xml
deleted file mode 100644
index 078f76c..0000000
--- a/res/xml/accessibility_ring_vibration_settings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2018 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<PreferenceScreen
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:title="@string/accessibility_ring_vibration_title" />
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index d836e24..dcf3fc2 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -110,7 +110,8 @@
             android:persistent="false"
             android:title="@string/accessibility_vibration_settings_title"
             settings:controller="com.android.settings.accessibility.VibrationPreferenceController"
-            settings:keywords="@string/keywords_vibration"/>
+            settings:keywords="@string/keywords_vibration"
+            android:summary="@string/accessibility_vibration_settings_summary"/>
 
     </PreferenceCategory>
 
diff --git a/res/xml/accessibility_touch_vibration_settings.xml b/res/xml/accessibility_touch_vibration_settings.xml
deleted file mode 100644
index ed8f550..0000000
--- a/res/xml/accessibility_touch_vibration_settings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2018 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<PreferenceScreen
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:title="@string/accessibility_touch_vibration_title" />
diff --git a/res/xml/accessibility_vibration_intensity_settings.xml b/res/xml/accessibility_vibration_intensity_settings.xml
new file mode 100644
index 0000000..d9a97f0
--- /dev/null
+++ b/res/xml/accessibility_vibration_intensity_settings.xml
@@ -0,0 +1,64 @@
+<?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"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:title="@string/accessibility_vibration_settings_title">
+
+    <PreferenceCategory
+        android:key="accessibility_call_vibration_category"
+        android:title="@string/accessibility_call_vibration_category_title">
+
+        <com.android.settings.widget.SeekBarPreference
+            android:key="ring_vibration_preference_screen"
+            android:title="@string/accessibility_ring_vibration_title"
+            app:keywords="@string/keywords_ring_vibration"
+            app:controller="com.android.settings.accessibility.RingVibrationIntensityPreferenceController" />
+
+        <SwitchPreference
+            android:key="ramping_ringer"
+            android:title="@string/vibrate_when_ringing_option_ramping_ringer"
+            app:keywords="@string/keywords_ramping_ringer_vibration"
+            app:controller="com.android.settings.accessibility.VibrationRampingRingerTogglePreferenceController"/>
+
+    </PreferenceCategory>
+
+    <PreferenceCategory
+        android:key="accessibility_notification_alarm_vibration_category"
+        android:title="@string/accessibility_notification_alarm_vibration_category_title">
+
+        <com.android.settings.widget.SeekBarPreference
+            android:key="notification_vibration_preference_screen"
+            android:title="@string/accessibility_notification_vibration_title"
+            app:keywords="@string/keywords_notification_vibration"
+            app:controller="com.android.settings.accessibility.NotificationVibrationIntensityPreferenceController" />
+
+    </PreferenceCategory>
+
+    <PreferenceCategory
+        android:key="accessibility_interactive_haptics_category"
+        android:title="@string/accessibility_interactive_haptics_category_title">
+
+        <com.android.settings.widget.SeekBarPreference
+            android:key="touch_vibration_preference_screen"
+            android:title="@string/accessibility_touch_vibration_title"
+            app:keywords="@string/keywords_touch_vibration"
+            app:controller="com.android.settings.accessibility.HapticFeedbackIntensityPreferenceController" />
+
+    </PreferenceCategory>
+
+</PreferenceScreen>
diff --git a/res/xml/accessibility_vibration_settings.xml b/res/xml/accessibility_vibration_settings.xml
index ff10611..18cd718 100644
--- a/res/xml/accessibility_vibration_settings.xml
+++ b/res/xml/accessibility_vibration_settings.xml
@@ -17,25 +17,23 @@
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:title="@string/accessibility_vibration_settings_title">
 
     <PreferenceCategory
         android:key="accessibility_call_vibration_category"
         android:title="@string/accessibility_call_vibration_category_title">
 
-        <Preference
-            android:fragment="com.android.settings.accessibility.RingVibrationPreferenceFragment"
+        <SwitchPreference
             android:key="ring_vibration_preference_screen"
             android:title="@string/accessibility_ring_vibration_title"
-            settings:keywords="@string/keywords_ring_vibration"
-            app:controller="com.android.settings.accessibility.RingVibrationIntensityPreferenceController" />
+            app:keywords="@string/keywords_ring_vibration"
+            app:controller="com.android.settings.accessibility.RingVibrationTogglePreferenceController" />
 
-        <Preference
-            android:fragment="com.android.settings.sound.VibrateForCallsPreferenceFragment"
-            android:key="vibrate_for_calls"
-            android:title="@string/vibrate_when_ringing_title"
-            settings:controller="com.android.settings.sound.VibrateForCallsPreferenceController"/>
+        <SwitchPreference
+            android:key="ramping_ringer"
+            android:title="@string/vibrate_when_ringing_option_ramping_ringer"
+            app:keywords="@string/keywords_ramping_ringer_vibration"
+            app:controller="com.android.settings.accessibility.VibrationRampingRingerTogglePreferenceController"/>
 
     </PreferenceCategory>
 
@@ -43,12 +41,11 @@
         android:key="accessibility_notification_alarm_vibration_category"
         android:title="@string/accessibility_notification_alarm_vibration_category_title">
 
-        <Preference
-            android:fragment="com.android.settings.accessibility.NotificationVibrationPreferenceFragment"
+        <SwitchPreference
             android:key="notification_vibration_preference_screen"
             android:title="@string/accessibility_notification_vibration_title"
-            settings:keywords="@string/keywords_notification_vibration"
-            app:controller="com.android.settings.accessibility.NotificationVibrationIntensityPreferenceController" />
+            app:keywords="@string/keywords_notification_vibration"
+            app:controller="com.android.settings.accessibility.NotificationVibrationTogglePreferenceController" />
 
     </PreferenceCategory>
 
@@ -56,12 +53,11 @@
         android:key="accessibility_interactive_haptics_category"
         android:title="@string/accessibility_interactive_haptics_category_title">
 
-        <Preference
-            android:fragment="com.android.settings.accessibility.TouchVibrationPreferenceFragment"
+        <SwitchPreference
             android:key="touch_vibration_preference_screen"
             android:title="@string/accessibility_touch_vibration_title"
-            settings:keywords="@string/keywords_touch_vibration"
-            app:controller="com.android.settings.accessibility.HapticFeedbackIntensityPreferenceController" />
+            app:keywords="@string/keywords_touch_vibration"
+            app:controller="com.android.settings.accessibility.HapticFeedbackTogglePreferenceController" />
 
     </PreferenceCategory>
 
diff --git a/src/com/android/settings/accessibility/AccessibilityQuickSettingsTooltipWindow.java b/src/com/android/settings/accessibility/AccessibilityQuickSettingsTooltipWindow.java
new file mode 100644
index 0000000..a4986a0
--- /dev/null
+++ b/src/com/android/settings/accessibility/AccessibilityQuickSettingsTooltipWindow.java
@@ -0,0 +1,154 @@
+/*
+ * 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.graphics.drawable.ColorDrawable;
+import android.os.Handler;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.PopupWindow;
+import android.widget.TextView;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.settings.R;
+
+/**
+ * UI container for the accessibility quick settings tooltip.
+ *
+ * <p> The popup window shows the information about the operation of the quick settings. In
+ * addition, the arrow is pointing to the top center of the device to display one-off menu within
+ * {@code mCloseDelayTimeMillis} time.</p>
+ */
+public class AccessibilityQuickSettingsTooltipWindow extends PopupWindow {
+
+    private final Context mContext;
+    private Handler mHandler;
+    private long mCloseDelayTimeMillis;
+
+    public AccessibilityQuickSettingsTooltipWindow(Context context) {
+        super(context);
+        this.mContext = context;
+    }
+
+    /**
+     * Sets up {@link #AccessibilityQuickSettingsTooltipWindow}'s layout and content.
+     *
+     * @param text text to be displayed
+     */
+    public void setup(String text) {
+        this.setup(text, /* closeDelayTimeMillis= */ 0);
+    }
+
+    /**
+     * Sets up {@link #AccessibilityQuickSettingsTooltipWindow}'s layout and content.
+     *
+     * <p> The system will attempt to close popup window to the target duration of the threads if
+     * close delay time is positive number. </p>
+     *
+     * @param text text to be displayed
+     * @param closeDelayTimeMillis how long the popup window be auto-closed
+     */
+    public void setup(String text, long closeDelayTimeMillis) {
+        this.mCloseDelayTimeMillis = closeDelayTimeMillis;
+
+        setBackgroundDrawable(new ColorDrawable(mContext.getColor(android.R.color.transparent)));
+        final LayoutInflater inflater = mContext.getSystemService(LayoutInflater.class);
+        final View popupView =
+                inflater.inflate(R.layout.accessibility_qs_tooltips, /* root= */ null);
+        setContentView(popupView);
+        final TextView textView = getContentView().findViewById(R.id.qs_content);
+        textView.setText(text);
+
+        setWidth(getWindowWidthWith(textView));
+        setHeight(LinearLayout.LayoutParams.WRAP_CONTENT);
+        setFocusable(/* focusable= */ true);
+    }
+
+    /**
+     * Displays the content view in a popup window at the top and center position.
+     *
+     * @param targetView a target view to get the {@link View#getWindowToken()} token from.
+     */
+    public void showAtTopCenter(View targetView) {
+        showAtLocation(targetView, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 0);
+    }
+
+    /**
+     * Disposes of the popup window.
+     *
+     * <p> Remove any pending posts of callbacks and sent messages for closing popup window. </p>
+     */
+    @Override
+    public void dismiss() {
+        super.dismiss();
+        if (mHandler != null) {
+            mHandler.removeCallbacksAndMessages(/* token= */ null);
+        }
+    }
+
+    /**
+     * Displays the content view in a popup window at the specified location.
+     *
+     * <p> The system will attempt to close popup window to the target duration of the threads if
+     * close delay time is positive number. </p>
+     *
+     * @param parent a parent view to get the {@link android.view.View#getWindowToken()} token from
+     * @param gravity the gravity which controls the placement of the popup window
+     * @param x the popup's x location offset
+     * @param y the popup's y location offset
+     */
+    @Override
+    public void showAtLocation(View parent, int gravity, int x, int y) {
+        super.showAtLocation(parent, gravity, x, y);
+        scheduleAutoCloseAction();
+    }
+
+    private void scheduleAutoCloseAction() {
+        if (mCloseDelayTimeMillis <= 0) {
+            return;
+        }
+
+        if (mHandler == null) {
+            mHandler = new Handler(mContext.getMainLooper());
+        }
+        mHandler.removeCallbacksAndMessages(/* token= */ null);
+        mHandler.postDelayed(this::dismiss, mCloseDelayTimeMillis);
+    }
+
+    private int getWindowWidthWith(TextView textView) {
+        final int availableWindowWidth = getAvailableWindowWidth();
+        final int widthSpec =
+                View.MeasureSpec.makeMeasureSpec(availableWindowWidth, View.MeasureSpec.AT_MOST);
+        final int heightSpec =
+                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
+        textView.measure(widthSpec, heightSpec);
+        return textView.getMeasuredWidth();
+    }
+
+    @VisibleForTesting
+    int getAvailableWindowWidth() {
+        final Resources res = mContext.getResources();
+        final int padding = res.getDimensionPixelSize(R.dimen.accessibility_qs_tooltips_margin);
+        final int screenWidth = res.getDisplayMetrics().widthPixels;
+        return screenWidth - padding * 2;
+    }
+}
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index 4030e0d..8e8c7e4 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -294,11 +294,6 @@
         return info.loadDescription(context.getPackageManager());
     }
 
-    static boolean isRampingRingerEnabled(final Context context) {
-        return Settings.System.getInt(
-                context.getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, 0) == 1;
-    }
-
     @VisibleForTesting
     void onContentChanged() {
         // If the fragment is visible then update preferences immediately, else set the flag then
diff --git a/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceController.java b/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceController.java
index f3e9b83..99d2bf5 100644
--- a/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceController.java
+++ b/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceController.java
@@ -16,31 +16,66 @@
 
 package com.android.settings.accessibility;
 
+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.VibrationAttributes;
+import android.os.Vibrator;
 import android.provider.Settings;
 
-import androidx.annotation.VisibleForTesting;
-
+/** Preference controller for haptic feedback intensity */
 public class HapticFeedbackIntensityPreferenceController
         extends VibrationIntensityPreferenceController {
 
-    @VisibleForTesting
-    static final String PREF_KEY = "touch_vibration_preference_screen";
+    /** General configuration for haptic feedback intensity settings. */
+    public static final class HapticFeedbackVibrationPreferenceConfig
+            extends VibrationPreferenceConfig {
 
-    public HapticFeedbackIntensityPreferenceController(Context context) {
-        super(context, PREF_KEY, Settings.System.HAPTIC_FEEDBACK_INTENSITY,
-                Settings.System.HAPTIC_FEEDBACK_ENABLED);
+        public HapticFeedbackVibrationPreferenceConfig(Context context) {
+            super(context, Settings.System.HAPTIC_FEEDBACK_INTENSITY,
+                    VibrationAttributes.USAGE_TOUCH);
+        }
+
+        @Override
+        public int readIntensity() {
+            final int hapticFeedbackEnabled = Settings.System.getInt(mContentResolver,
+                    Settings.System.HAPTIC_FEEDBACK_ENABLED, ON);
+
+            if (hapticFeedbackEnabled == OFF) {
+                // HAPTIC_FEEDBACK_ENABLED is deprecated but should still be applied if the user has
+                // turned it off already.
+                return Vibrator.VIBRATION_INTENSITY_OFF;
+            }
+
+            return super.readIntensity();
+        }
+
+        @Override
+        public boolean updateIntensity(int intensity) {
+            final boolean success = super.updateIntensity(intensity);
+            final boolean isIntensityOff = intensity == Vibrator.VIBRATION_INTENSITY_OFF;
+
+            Settings.System.putInt(mContentResolver, Settings.System.HAPTIC_FEEDBACK_ENABLED,
+                    isIntensityOff ? OFF : ON);
+            // HAPTIC_FEEDBACK_ENABLED is deprecated but should still reflect the intensity setting.
+
+            // HARDWARE_HAPTIC_FEEDBACK_INTENSITY is dependent on this setting, but should not be
+            // disabled by it.
+            Settings.System.putInt(mContentResolver,
+                    Settings.System.HARDWARE_HAPTIC_FEEDBACK_INTENSITY,
+                    isIntensityOff ? getDefaultIntensity() : intensity);
+
+            return success;
+        }
+    }
+
+    public HapticFeedbackIntensityPreferenceController(Context context, String preferenceKey) {
+        super(context, preferenceKey, new HapticFeedbackVibrationPreferenceConfig(context));
     }
 
     @Override
     public int getAvailabilityStatus() {
         return AVAILABLE;
     }
-
-    @Override
-    protected int getDefaultIntensity() {
-        return mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_TOUCH);
-    }
-
 }
diff --git a/src/com/android/settings/accessibility/HapticFeedbackTogglePreferenceController.java b/src/com/android/settings/accessibility/HapticFeedbackTogglePreferenceController.java
new file mode 100644
index 0000000..fdaf140
--- /dev/null
+++ b/src/com/android/settings/accessibility/HapticFeedbackTogglePreferenceController.java
@@ -0,0 +1,34 @@
+/*
+ * 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 com.android.settings.accessibility.HapticFeedbackIntensityPreferenceController.HapticFeedbackVibrationPreferenceConfig;
+
+/** Preference controller for haptic feedback with only a toggle for on/off states. */
+public class HapticFeedbackTogglePreferenceController extends VibrationTogglePreferenceController {
+
+    public HapticFeedbackTogglePreferenceController(Context context, String preferenceKey) {
+        super(context, preferenceKey, new HapticFeedbackVibrationPreferenceConfig(context));
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+}
diff --git a/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceController.java b/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceController.java
index eb396ac..31ae187 100644
--- a/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceController.java
+++ b/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceController.java
@@ -20,25 +20,27 @@
 import android.os.VibrationAttributes;
 import android.provider.Settings;
 
-import androidx.annotation.VisibleForTesting;
-
+/** Preference controller for notification vibration intensity */
 public class NotificationVibrationIntensityPreferenceController
         extends VibrationIntensityPreferenceController {
 
-    @VisibleForTesting
-    static final String PREF_KEY = "notification_vibration_preference_screen";
+    /** General configuration for notification vibration intensity settings. */
+    public static final class NotificationVibrationPreferenceConfig
+            extends VibrationPreferenceConfig {
 
-    public NotificationVibrationIntensityPreferenceController(Context context) {
-        super(context, PREF_KEY, Settings.System.NOTIFICATION_VIBRATION_INTENSITY, "");
+        public NotificationVibrationPreferenceConfig(Context context) {
+            super(context, Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+                    VibrationAttributes.USAGE_NOTIFICATION);
+        }
+    }
+
+    public NotificationVibrationIntensityPreferenceController(Context context,
+            String preferenceKey) {
+        super(context, preferenceKey, new NotificationVibrationPreferenceConfig(context));
     }
 
     @Override
     public int getAvailabilityStatus() {
         return AVAILABLE;
     }
-
-    @Override
-    protected int getDefaultIntensity() {
-        return mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_NOTIFICATION);
-    }
 }
diff --git a/src/com/android/settings/accessibility/NotificationVibrationPreferenceFragment.java b/src/com/android/settings/accessibility/NotificationVibrationPreferenceFragment.java
deleted file mode 100644
index e1d9d47..0000000
--- a/src/com/android/settings/accessibility/NotificationVibrationPreferenceFragment.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.accessibility;
-
-import android.app.settings.SettingsEnums;
-import android.media.AudioAttributes;
-import android.os.VibrationAttributes;
-import android.os.Vibrator;
-import android.provider.Settings;
-
-import com.android.settings.R;
-
-/**
- * Fragment for picking accessibility shortcut service
- */
-public class NotificationVibrationPreferenceFragment extends VibrationPreferenceFragment {
-    @Override
-    public int getMetricsCategory() {
-        return SettingsEnums.ACCESSIBILITY_VIBRATION_NOTIFICATION;
-    }
-
-    @Override
-    protected int getPreferenceScreenResId() {
-        return R.xml.accessibility_notification_vibration_settings;
-    }
-
-    /**
-     * Get the setting string of the vibration intensity setting this preference is dealing with.
-     */
-    @Override
-    protected String getVibrationIntensitySetting() {
-        return Settings.System.NOTIFICATION_VIBRATION_INTENSITY;
-    }
-
-    @Override
-    protected String getVibrationEnabledSetting() {
-        return "";
-    }
-
-    @Override
-    protected int getPreviewVibrationAudioAttributesUsage() {
-        return AudioAttributes.USAGE_NOTIFICATION;
-    }
-
-    @Override
-    protected int getDefaultVibrationIntensity() {
-        Vibrator vibrator = getContext().getSystemService(Vibrator.class);
-        return vibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_NOTIFICATION);
-    }
-}
diff --git a/src/com/android/settings/accessibility/NotificationVibrationTogglePreferenceController.java b/src/com/android/settings/accessibility/NotificationVibrationTogglePreferenceController.java
new file mode 100644
index 0000000..2dc02a1
--- /dev/null
+++ b/src/com/android/settings/accessibility/NotificationVibrationTogglePreferenceController.java
@@ -0,0 +1,35 @@
+/*
+ * 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 com.android.settings.accessibility.NotificationVibrationIntensityPreferenceController.NotificationVibrationPreferenceConfig;
+
+/** Preference controller for notification vibration with only a toggle for on/off states. */
+public class NotificationVibrationTogglePreferenceController
+        extends VibrationTogglePreferenceController {
+
+    public NotificationVibrationTogglePreferenceController(Context context, String preferenceKey) {
+        super(context, preferenceKey, new NotificationVibrationPreferenceConfig(context));
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+}
diff --git a/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceController.java b/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceController.java
index 75cbefb..1ddcf2b 100644
--- a/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceController.java
+++ b/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceController.java
@@ -16,30 +16,63 @@
 
 package com.android.settings.accessibility;
 
+import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
+import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
+
 import android.content.Context;
+import android.media.AudioManager;
 import android.os.VibrationAttributes;
+import android.os.Vibrator;
 import android.provider.Settings;
 
-import androidx.annotation.VisibleForTesting;
-
+/** Preference controller for ringtone vibration intensity */
 public class RingVibrationIntensityPreferenceController
         extends VibrationIntensityPreferenceController {
 
-    @VisibleForTesting
-    static final String PREF_KEY = "ring_vibration_preference_screen";
+    /** General configuration for ringtone vibration intensity settings. */
+    public static final class RingVibrationPreferenceConfig extends VibrationPreferenceConfig {
+        private final AudioManager mAudioManager;
 
-    public RingVibrationIntensityPreferenceController(Context context) {
-        super(context, PREF_KEY, Settings.System.RING_VIBRATION_INTENSITY,
-                Settings.System.VIBRATE_WHEN_RINGING, /* supportRampingRinger= */ true);
+        public RingVibrationPreferenceConfig(Context context) {
+            super(context, Settings.System.RING_VIBRATION_INTENSITY,
+                    VibrationAttributes.USAGE_RINGTONE);
+            mAudioManager = context.getSystemService(AudioManager.class);
+        }
+
+        @Override
+        public int readIntensity() {
+            final int vibrateWhenRinging = Settings.System.getInt(mContentResolver,
+                    Settings.System.VIBRATE_WHEN_RINGING, ON);
+
+            if ((vibrateWhenRinging == OFF)
+                    && !mAudioManager.isRampingRingerEnabled()) {
+                // VIBRATE_WHEN_RINGING is deprecated but should still be applied if the user has
+                // turned it off and has not enabled the ramping ringer (old three-state setting).
+                return Vibrator.VIBRATION_INTENSITY_OFF;
+            }
+
+            return super.readIntensity();
+        }
+
+        @Override
+        public boolean updateIntensity(int intensity) {
+            final boolean success = super.updateIntensity(intensity);
+
+            // VIBRATE_WHEN_RINGING is deprecated but should still reflect the intensity setting.
+            // Ramping ringer is independent of the ring intensity and should not be affected.
+            Settings.System.putInt(mContentResolver, Settings.System.VIBRATE_WHEN_RINGING,
+                    (intensity == Vibrator.VIBRATION_INTENSITY_OFF) ? OFF : ON);
+
+            return success;
+        }
+    }
+
+    public RingVibrationIntensityPreferenceController(Context context, String preferenceKey) {
+        super(context, preferenceKey, new RingVibrationPreferenceConfig(context));
     }
 
     @Override
     public int getAvailabilityStatus() {
         return AVAILABLE;
     }
-
-    @Override
-    protected int getDefaultIntensity() {
-        return mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_RINGTONE);
-    }
 }
diff --git a/src/com/android/settings/accessibility/RingVibrationPreferenceFragment.java b/src/com/android/settings/accessibility/RingVibrationPreferenceFragment.java
deleted file mode 100644
index aa3e313..0000000
--- a/src/com/android/settings/accessibility/RingVibrationPreferenceFragment.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.accessibility;
-
-import android.app.settings.SettingsEnums;
-import android.media.AudioAttributes;
-import android.os.VibrationAttributes;
-import android.os.Vibrator;
-import android.provider.Settings;
-
-import com.android.settings.R;
-
-/**
- * Fragment for picking accessibility shortcut service
- */
-public class RingVibrationPreferenceFragment extends VibrationPreferenceFragment {
-    @Override
-    public int getMetricsCategory() {
-        return SettingsEnums.ACCESSIBILITY_VIBRATION_RING;
-    }
-
-    @Override
-    protected int getPreferenceScreenResId() {
-        return R.xml.accessibility_ring_vibration_settings;
-    }
-
-    /**
-     * Get the setting string of the vibration intensity setting this preference is dealing with.
-     */
-    @Override
-    protected String getVibrationIntensitySetting() {
-        return Settings.System.RING_VIBRATION_INTENSITY;
-    }
-
-    @Override
-    protected String getVibrationEnabledSetting() {
-        if (AccessibilitySettings.isRampingRingerEnabled(getContext())) {
-            return Settings.System.APPLY_RAMPING_RINGER;
-        } else {
-            return Settings.System.VIBRATE_WHEN_RINGING;
-        }
-    }
-
-    @Override
-    protected int getPreviewVibrationAudioAttributesUsage() {
-        return AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
-    }
-
-    @Override
-    protected int getDefaultVibrationIntensity() {
-        Vibrator vibrator = getContext().getSystemService(Vibrator.class);
-        return vibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_RINGTONE);
-    }
-}
diff --git a/src/com/android/settings/accessibility/RingVibrationTogglePreferenceController.java b/src/com/android/settings/accessibility/RingVibrationTogglePreferenceController.java
new file mode 100644
index 0000000..e68b6ce
--- /dev/null
+++ b/src/com/android/settings/accessibility/RingVibrationTogglePreferenceController.java
@@ -0,0 +1,34 @@
+/*
+ * 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 com.android.settings.accessibility.RingVibrationIntensityPreferenceController.RingVibrationPreferenceConfig;
+
+/** Preference controller for ringtone vibration with only a toggle for on/off states. */
+public class RingVibrationTogglePreferenceController extends VibrationTogglePreferenceController {
+
+    public RingVibrationTogglePreferenceController(Context context, String preferenceKey) {
+        super(context, preferenceKey, new RingVibrationPreferenceConfig(context));
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+}
diff --git a/src/com/android/settings/accessibility/TouchVibrationPreferenceFragment.java b/src/com/android/settings/accessibility/TouchVibrationPreferenceFragment.java
deleted file mode 100644
index b1bd847..0000000
--- a/src/com/android/settings/accessibility/TouchVibrationPreferenceFragment.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.accessibility;
-
-import android.app.settings.SettingsEnums;
-import android.media.AudioAttributes;
-import android.os.VibrationAttributes;
-import android.os.Vibrator;
-import android.provider.Settings;
-
-import com.android.settings.R;
-
-/**
- * Fragment for picking accessibility shortcut service
- */
-public class TouchVibrationPreferenceFragment extends VibrationPreferenceFragment {
-    @Override
-    public int getMetricsCategory() {
-        return SettingsEnums.ACCESSIBILITY_VIBRATION_TOUCH;
-    }
-
-    @Override
-    protected int getPreferenceScreenResId() {
-        return R.xml.accessibility_touch_vibration_settings;
-    }
-
-    /**
-     * Get the setting string of the vibration intensity setting this preference is dealing with.
-     */
-    @Override
-    protected String getVibrationIntensitySetting() {
-        return Settings.System.HAPTIC_FEEDBACK_INTENSITY;
-    }
-
-    @Override
-    protected String getVibrationEnabledSetting() {
-        return Settings.System.HAPTIC_FEEDBACK_ENABLED;
-    }
-
-    @Override
-    protected int getDefaultVibrationIntensity() {
-        Vibrator vibrator = getContext().getSystemService(Vibrator.class);
-        return vibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_TOUCH);
-    }
-
-    @Override
-    protected int getPreviewVibrationAudioAttributesUsage() {
-        return AudioAttributes.USAGE_ASSISTANCE_SONIFICATION;
-    }
-}
diff --git a/src/com/android/settings/accessibility/VibrationIntensityPreferenceController.java b/src/com/android/settings/accessibility/VibrationIntensityPreferenceController.java
index 9d71176..e35b42c 100644
--- a/src/com/android/settings/accessibility/VibrationIntensityPreferenceController.java
+++ b/src/com/android/settings/accessibility/VibrationIntensityPreferenceController.java
@@ -17,116 +17,80 @@
 package com.android.settings.accessibility;
 
 import android.content.Context;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Looper;
 import android.os.Vibrator;
-import android.provider.Settings;
 
-import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 
-import com.android.settings.R;
-import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.SliderPreferenceController;
+import com.android.settings.widget.SeekBarPreference;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnStart;
 import com.android.settingslib.core.lifecycle.events.OnStop;
 
-public abstract class VibrationIntensityPreferenceController extends BasePreferenceController
+/**
+ * Abstract preference controller for a vibration intensity setting, that displays multiple
+ * intensity levels to the user as a slider.
+ */
+public abstract class VibrationIntensityPreferenceController extends SliderPreferenceController
         implements LifecycleObserver, OnStart, OnStop {
 
-    protected final Vibrator mVibrator;
-    private final SettingObserver mSettingsContentObserver;
-    private final String mSettingKey;
-    private final String mEnabledKey;
-    private final boolean mSupportRampingRinger;
+    protected final VibrationPreferenceConfig mPreferenceConfig;
+    private final VibrationPreferenceConfig.SettingObserver mSettingsContentObserver;
 
-    private Preference mPreference;
-
-    public VibrationIntensityPreferenceController(Context context, String prefkey,
-            String settingKey, String enabledKey, boolean supportRampingRinger) {
+    protected VibrationIntensityPreferenceController(Context context, String prefkey,
+            VibrationPreferenceConfig preferenceConfig) {
         super(context, prefkey);
-        mVibrator = mContext.getSystemService(Vibrator.class);
-        mSettingKey = settingKey;
-        mEnabledKey = enabledKey;
-        mSupportRampingRinger= supportRampingRinger;
-        mSettingsContentObserver = new SettingObserver(settingKey) {
-            @Override
-            public void onChange(boolean selfChange, Uri uri) {
-                updateState(mPreference);
-            }
-        };
-    }
-
-    public VibrationIntensityPreferenceController(Context context, String prefkey,
-            String settingKey, String enabledKey) {
-        this(context, prefkey, settingKey, enabledKey, /* supportRampingRinger= */ false);
+        mPreferenceConfig = preferenceConfig;
+        mSettingsContentObserver = new VibrationPreferenceConfig.SettingObserver(
+                preferenceConfig);
     }
 
     @Override
     public void onStart() {
-        mContext.getContentResolver().registerContentObserver(
-                mSettingsContentObserver.uri,
-                false /* notifyForDescendants */,
-                mSettingsContentObserver);
+        mSettingsContentObserver.register(mContext.getContentResolver());
     }
 
     @Override
     public void onStop() {
-        mContext.getContentResolver().unregisterContentObserver(mSettingsContentObserver);
+        mSettingsContentObserver.unregister(mContext.getContentResolver());
     }
 
     @Override
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
-        mPreference = screen.findPreference(getPreferenceKey());
+        final SeekBarPreference preference = screen.findPreference(getPreferenceKey());
+        mSettingsContentObserver.onDisplayPreference(this, preference);
+        // TODO: remove this and replace with a different way to play the haptic preview without
+        // relying on the setting being propagated to the service.
+        preference.setContinuousUpdates(true);
+        preference.setMin(getMin());
+        preference.setMax(getMax());
     }
 
     @Override
-    public CharSequence getSummary() {
-        final int intensity = Settings.System.getInt(mContext.getContentResolver(),
-                mSettingKey, getDefaultIntensity());
-        final boolean enabled = (Settings.System.getInt(mContext.getContentResolver(),
-                mEnabledKey, 1) == 1) ||
-                (mSupportRampingRinger && AccessibilitySettings.isRampingRingerEnabled(mContext));
-        return getIntensityString(mContext, enabled ? intensity : Vibrator.VIBRATION_INTENSITY_OFF);
+    public int getMin() {
+        return Vibrator.VIBRATION_INTENSITY_OFF;
     }
 
-    public static CharSequence getIntensityString(Context context, int intensity) {
-        final boolean supportsMultipleIntensities = context.getResources().getBoolean(
-                R.bool.config_vibration_supports_multiple_intensities);
-        if (supportsMultipleIntensities) {
-            switch (intensity) {
-                case Vibrator.VIBRATION_INTENSITY_OFF:
-                    return context.getString(R.string.accessibility_vibration_intensity_off);
-                case Vibrator.VIBRATION_INTENSITY_LOW:
-                    return context.getString(R.string.accessibility_vibration_intensity_low);
-                case Vibrator.VIBRATION_INTENSITY_MEDIUM:
-                    return context.getString(R.string.accessibility_vibration_intensity_medium);
-                case Vibrator.VIBRATION_INTENSITY_HIGH:
-                    return context.getString(R.string.accessibility_vibration_intensity_high);
-                default:
-                    return "";
-            }
-        } else {
-            if (intensity == Vibrator.VIBRATION_INTENSITY_OFF) {
-                return context.getString(R.string.switch_off_text);
-            } else {
-                return context.getString(R.string.switch_on_text);
-            }
-        }
+    @Override
+    public int getMax() {
+        return Vibrator.VIBRATION_INTENSITY_HIGH;
     }
 
-    protected abstract int getDefaultIntensity();
+    @Override
+    public int getSliderPosition() {
+        final int position = mPreferenceConfig.readIntensity();
+        return Math.min(position, getMax());
+    }
 
-    private static class SettingObserver extends ContentObserver {
+    @Override
+    public boolean setSliderPosition(int position) {
+        final boolean success = mPreferenceConfig.updateIntensity(position);
 
-        public final Uri uri;
-
-        public SettingObserver(String settingKey) {
-            super(new Handler(Looper.getMainLooper()));
-            uri = Settings.System.getUriFor(settingKey);
+        if (success && (position != Vibrator.VIBRATION_INTENSITY_OFF)) {
+            mPreferenceConfig.playVibrationPreview();
         }
+
+        return success;
     }
 }
diff --git a/src/com/android/settings/accessibility/VibrationPreferenceConfig.java b/src/com/android/settings/accessibility/VibrationPreferenceConfig.java
new file mode 100644
index 0000000..aa59554
--- /dev/null
+++ b/src/com/android/settings/accessibility/VibrationPreferenceConfig.java
@@ -0,0 +1,126 @@
+/*
+ * 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.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.VibrationAttributes;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
+import android.provider.Settings;
+
+import androidx.preference.Preference;
+
+import com.android.settingslib.core.AbstractPreferenceController;
+
+/**
+ * Vibration intensity settings configuration to be shared between different preference
+ * controllers that handle the same setting key.
+ */
+public abstract class VibrationPreferenceConfig {
+
+    protected final ContentResolver mContentResolver;
+    private final Vibrator mVibrator;
+    private final String mSettingKey;
+    private final int mDefaultIntensity;
+    private final VibrationAttributes mVibrationAttributes;
+
+    public VibrationPreferenceConfig(Context context, String settingKey, int vibrationUsage) {
+        mContentResolver = context.getContentResolver();
+        mVibrator = context.getSystemService(Vibrator.class);
+        mSettingKey = settingKey;
+        mDefaultIntensity = mVibrator.getDefaultVibrationIntensity(vibrationUsage);
+        mVibrationAttributes = new VibrationAttributes.Builder()
+                .setUsage(vibrationUsage)
+                .build();
+    }
+
+    /** Return the setting key for this setting preference. */
+    public String getSettingKey() {
+        return mSettingKey;
+    }
+
+    /** Returns the default intensity to be displayed when the setting value is not set. */
+    public int getDefaultIntensity() {
+        return mDefaultIntensity;
+    }
+
+    /** Reads setting value for corresponding {@link VibrationPreferenceConfig} */
+    public int readIntensity() {
+        return Settings.System.getInt(mContentResolver, mSettingKey, mDefaultIntensity);
+    }
+
+    /** Update setting value for corresponding {@link VibrationPreferenceConfig} */
+    public boolean updateIntensity(int intensity) {
+        return Settings.System.putInt(mContentResolver, mSettingKey, intensity);
+    }
+
+    /** Play a vibration effect with intensity just selected by the user. */
+    public void playVibrationPreview() {
+        mVibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK),
+                mVibrationAttributes);
+    }
+
+    /** {@link ContentObserver} for a setting described by a {@link VibrationPreferenceConfig}. */
+    public static final class SettingObserver extends ContentObserver {
+        private final Uri mUri;
+        private AbstractPreferenceController mPreferenceController;
+        private Preference mPreference;
+
+        /** Creates observer for given preference. */
+        public SettingObserver(VibrationPreferenceConfig preferenceConfig) {
+            super(new Handler(/* async= */ true));
+            mUri = Settings.System.getUriFor(preferenceConfig.getSettingKey());
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            if (mUri.equals(uri) && mPreferenceController != null && mPreference != null) {
+                mPreferenceController.updateState(mPreference);
+            }
+        }
+
+        /**
+         * Register this observer to given {@link ContentResolver}, to be called from lifecycle
+         * {@code onStart} method.
+         */
+        public void register(ContentResolver contentResolver) {
+            contentResolver.registerContentObserver(mUri, /* notifyForDescendants= */ false, this);
+        }
+
+        /**
+         * Unregister this observer from given {@link ContentResolver}, to be called from lifecycle
+         * {@code onStop} method.
+         */
+        public void unregister(ContentResolver contentResolver) {
+            contentResolver.unregisterContentObserver(this);
+        }
+
+        /**
+         * Binds this observer to given controller and preference, once it has been displayed to the
+         * user.
+         */
+        public void onDisplayPreference(AbstractPreferenceController controller,
+                Preference preference) {
+            mPreferenceController = controller;
+            mPreference = preference;
+        }
+    }
+}
diff --git a/src/com/android/settings/accessibility/VibrationPreferenceController.java b/src/com/android/settings/accessibility/VibrationPreferenceController.java
deleted file mode 100644
index b36106d..0000000
--- a/src/com/android/settings/accessibility/VibrationPreferenceController.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.accessibility;
-
-import android.content.Context;
-import android.os.VibrationAttributes;
-import android.os.Vibrator;
-import android.provider.Settings;
-
-import com.android.settings.R;
-import com.android.settings.core.BasePreferenceController;
-
-public class VibrationPreferenceController extends BasePreferenceController {
-
-    private final Vibrator mVibrator;
-
-    public VibrationPreferenceController(Context context, String preferenceKey) {
-        super(context, preferenceKey);
-        mVibrator = mContext.getSystemService(Vibrator.class);
-    }
-
-    @Override
-    public int getAvailabilityStatus() {
-        return AVAILABLE;
-    }
-
-    @Override
-    public CharSequence getSummary() {
-        int ringIntensity = Settings.System.getInt(mContext.getContentResolver(),
-                Settings.System.RING_VIBRATION_INTENSITY,
-                mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_RINGTONE));
-        if (Settings.System.getInt(mContext.getContentResolver(),
-                Settings.System.VIBRATE_WHEN_RINGING, 0) == 0
-                && !AccessibilitySettings.isRampingRingerEnabled(mContext)) {
-            ringIntensity = Vibrator.VIBRATION_INTENSITY_OFF;
-        }
-        final CharSequence ringIntensityString =
-                VibrationIntensityPreferenceController.getIntensityString(mContext, ringIntensity);
-
-        final int notificationIntensity = Settings.System.getInt(mContext.getContentResolver(),
-                Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
-                mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_NOTIFICATION));
-        final CharSequence notificationIntensityString =
-                VibrationIntensityPreferenceController.getIntensityString(mContext,
-                        notificationIntensity);
-
-        int touchIntensity = Settings.System.getInt(mContext.getContentResolver(),
-                Settings.System.HAPTIC_FEEDBACK_INTENSITY,
-                mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_TOUCH));
-        if (Settings.System.getInt(mContext.getContentResolver(),
-                Settings.System.HAPTIC_FEEDBACK_ENABLED, 0) == 0) {
-            touchIntensity = Vibrator.VIBRATION_INTENSITY_OFF;
-        }
-        final CharSequence touchIntensityString =
-                VibrationIntensityPreferenceController.getIntensityString(mContext, touchIntensity);
-
-        if (ringIntensity == touchIntensity && ringIntensity == notificationIntensity) {
-            return ringIntensityString;
-        } else {
-            return mContext.getString(R.string.accessibility_vibration_summary, ringIntensityString,
-                    notificationIntensityString, touchIntensityString);
-        }
-    }
-}
diff --git a/src/com/android/settings/accessibility/VibrationPreferenceFragment.java b/src/com/android/settings/accessibility/VibrationPreferenceFragment.java
deleted file mode 100644
index 2ef8f66..0000000
--- a/src/com/android/settings/accessibility/VibrationPreferenceFragment.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.accessibility;
-
-import static android.os.Vibrator.VibrationIntensity;
-
-import android.content.Context;
-import android.database.ContentObserver;
-import android.graphics.drawable.Drawable;
-import android.media.AudioAttributes;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.VibrationEffect;
-import android.os.Vibrator;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.android.settings.R;
-import com.android.settings.widget.RadioButtonPickerFragment;
-import com.android.settingslib.widget.CandidateInfo;
-
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Fragment for changing vibration settings.
- */
-public abstract class VibrationPreferenceFragment extends RadioButtonPickerFragment {
-    private static final String TAG = "VibrationPreferenceFragment";
-
-    @VisibleForTesting
-    final static String KEY_INTENSITY_OFF = "intensity_off";
-    @VisibleForTesting
-    final static String KEY_INTENSITY_LOW = "intensity_low";
-    @VisibleForTesting
-    final static String KEY_INTENSITY_MEDIUM = "intensity_medium";
-    @VisibleForTesting
-    final static String KEY_INTENSITY_HIGH = "intensity_high";
-    // KEY_INTENSITY_ON is only used when the device doesn't support multiple intensity levels.
-    @VisibleForTesting
-    final static String KEY_INTENSITY_ON = "intensity_on";
-
-    private final Map<String, VibrationIntensityCandidateInfo> mCandidates;
-    private final SettingsObserver mSettingsObserver;
-
-    public VibrationPreferenceFragment() {
-        mCandidates = new ArrayMap<>();
-        mSettingsObserver = new SettingsObserver();
-    }
-
-    @Override
-    public void onAttach(Context context) {
-        super.onAttach(context);
-        mSettingsObserver.register();
-        if (mCandidates.isEmpty()) {
-            loadCandidates(context);
-        }
-    }
-
-    private void loadCandidates(Context context) {
-        final boolean supportsMultipleIntensities = context.getResources().getBoolean(
-                R.bool.config_vibration_supports_multiple_intensities);
-        if (supportsMultipleIntensities) {
-            mCandidates.put(KEY_INTENSITY_OFF,
-                    new VibrationIntensityCandidateInfo(KEY_INTENSITY_OFF,
-                        R.string.accessibility_vibration_intensity_off,
-                        Vibrator.VIBRATION_INTENSITY_OFF));
-            mCandidates.put(KEY_INTENSITY_LOW,
-                    new VibrationIntensityCandidateInfo(KEY_INTENSITY_LOW,
-                        R.string.accessibility_vibration_intensity_low,
-                        Vibrator.VIBRATION_INTENSITY_LOW));
-            mCandidates.put(KEY_INTENSITY_MEDIUM,
-                    new VibrationIntensityCandidateInfo(KEY_INTENSITY_MEDIUM,
-                        R.string.accessibility_vibration_intensity_medium,
-                        Vibrator.VIBRATION_INTENSITY_MEDIUM));
-            mCandidates.put(KEY_INTENSITY_HIGH,
-                    new VibrationIntensityCandidateInfo(KEY_INTENSITY_HIGH,
-                        R.string.accessibility_vibration_intensity_high,
-                        Vibrator.VIBRATION_INTENSITY_HIGH));
-        } else {
-            mCandidates.put(KEY_INTENSITY_OFF,
-                    new VibrationIntensityCandidateInfo(KEY_INTENSITY_OFF,
-                        R.string.switch_off_text, Vibrator.VIBRATION_INTENSITY_OFF));
-            mCandidates.put(KEY_INTENSITY_ON,
-                    new VibrationIntensityCandidateInfo(KEY_INTENSITY_ON,
-                        R.string.switch_on_text, getDefaultVibrationIntensity()));
-        }
-    }
-
-    private boolean hasVibrationEnabledSetting() {
-        return !TextUtils.isEmpty(getVibrationEnabledSetting());
-    }
-
-    private void updateSettings(VibrationIntensityCandidateInfo candidate) {
-        boolean vibrationEnabled = candidate.getIntensity() != Vibrator.VIBRATION_INTENSITY_OFF;
-        if (hasVibrationEnabledSetting()) {
-            // Update vibration enabled setting
-            final String vibrationEnabledSetting = getVibrationEnabledSetting();
-            final boolean wasEnabled = TextUtils.equals(
-                        vibrationEnabledSetting, Settings.System.APPLY_RAMPING_RINGER)
-                    ? true
-                    : (Settings.System.getInt(
-                            getContext().getContentResolver(), vibrationEnabledSetting, 1) == 1);
-            if (vibrationEnabled != wasEnabled) {
-                if (vibrationEnabledSetting.equals(Settings.System.APPLY_RAMPING_RINGER)) {
-                    Settings.Global.putInt(getContext().getContentResolver(),
-                            vibrationEnabledSetting, 0);
-                } else {
-                    Settings.System.putInt(getContext().getContentResolver(),
-                            vibrationEnabledSetting, vibrationEnabled ? 1 : 0);
-                }
-
-                int previousIntensity = Settings.System.getInt(getContext().getContentResolver(),
-                        getVibrationIntensitySetting(), 0);
-                if (vibrationEnabled && previousIntensity == candidate.getIntensity()) {
-                    // We can't play preview effect here for all cases because that causes a data
-                    // race (VibratorService may access intensity settings before these settings
-                    // are updated). But we can't just play it in intensity settings update
-                    // observer, because the intensity settings are not changed if we turn the
-                    // vibration off, then on.
-                    //
-                    // In this case we sould play the preview here.
-                    // To be refactored in b/132952771
-                    playVibrationPreview();
-                }
-            }
-        }
-        // There are two conditions that need to change the intensity.
-        // First: Vibration is enabled and we are changing its strength.
-        // Second: There is no setting to enable this vibration, change the intensity directly.
-        if (vibrationEnabled || !hasVibrationEnabledSetting()) {
-            // Update vibration intensity setting
-            Settings.System.putInt(getContext().getContentResolver(),
-                    getVibrationIntensitySetting(), candidate.getIntensity());
-        }
-    }
-
-    @Override
-    public void onDetach() {
-        super.onDetach();
-        mSettingsObserver.unregister();
-    }
-
-    /**
-     * Get the setting string of the vibration intensity setting this preference is dealing with.
-     */
-    protected abstract String getVibrationIntensitySetting();
-
-    /**
-     * Get the setting string of the vibration enabledness setting this preference is dealing with.
-     */
-    protected abstract String getVibrationEnabledSetting();
-
-    /**
-     * Get the default intensity for the desired setting.
-     */
-    protected abstract int getDefaultVibrationIntensity();
-
-    /**
-     * When a new vibration intensity is selected by the user.
-     */
-    protected void onVibrationIntensitySelected(int intensity) { }
-
-    /**
-     * Play a vibration effect with intensity just selected by user
-     */
-    protected void playVibrationPreview() {
-        Vibrator vibrator = getContext().getSystemService(Vibrator.class);
-        VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
-        AudioAttributes.Builder builder = new AudioAttributes.Builder();
-        builder.setUsage(getPreviewVibrationAudioAttributesUsage());
-        vibrator.vibrate(effect, builder.build());
-    }
-
-    /**
-     * Get the AudioAttributes usage for vibration preview.
-     */
-    protected int getPreviewVibrationAudioAttributesUsage() {
-        return AudioAttributes.USAGE_UNKNOWN;
-    }
-
-    @Override
-    protected List<? extends CandidateInfo> getCandidates() {
-        List<VibrationIntensityCandidateInfo> candidates = new ArrayList<>(mCandidates.values());
-        candidates.sort(
-                Comparator.comparing(VibrationIntensityCandidateInfo::getIntensity).reversed());
-        return candidates;
-    }
-
-    @Override
-    protected String getDefaultKey() {
-        int vibrationIntensity = Settings.System.getInt(getContext().getContentResolver(),
-                getVibrationIntensitySetting(), getDefaultVibrationIntensity());
-        final String vibrationEnabledSetting = getVibrationEnabledSetting();
-        final boolean vibrationEnabled = TextUtils.equals(
-                        vibrationEnabledSetting, Settings.System.APPLY_RAMPING_RINGER)
-                    ? true
-                    : (Settings.System.getInt(
-                            getContext().getContentResolver(), vibrationEnabledSetting, 1) == 1);
-        if (!vibrationEnabled) {
-            vibrationIntensity = Vibrator.VIBRATION_INTENSITY_OFF;
-        }
-        for (VibrationIntensityCandidateInfo candidate : mCandidates.values()) {
-            final boolean matchesIntensity = candidate.getIntensity() == vibrationIntensity;
-            final boolean matchesOn = candidate.getKey().equals(KEY_INTENSITY_ON)
-                    && vibrationIntensity != Vibrator.VIBRATION_INTENSITY_OFF;
-            if (matchesIntensity || matchesOn) {
-                return candidate.getKey();
-            }
-        }
-        return null;
-    }
-
-    @Override
-    protected boolean setDefaultKey(String key) {
-        VibrationIntensityCandidateInfo candidate = mCandidates.get(key);
-        if (candidate == null) {
-            Log.e(TAG, "Tried to set unknown intensity (key=" + key + ")!");
-            return false;
-        }
-        updateSettings(candidate);
-        onVibrationIntensitySelected(candidate.getIntensity());
-        return true;
-    }
-
-    @VisibleForTesting
-    class VibrationIntensityCandidateInfo extends CandidateInfo {
-        private String mKey;
-        private int mLabelId;
-        @VibrationIntensity
-        private int mIntensity;
-
-        public VibrationIntensityCandidateInfo(String key, int labelId, int intensity) {
-            super(true /* enabled */);
-            mKey = key;
-            mLabelId = labelId;
-            mIntensity = intensity;
-        }
-
-        @Override
-        public CharSequence loadLabel() {
-            return getContext().getString(mLabelId);
-        }
-
-        @Override
-        public Drawable loadIcon() {
-            return null;
-        }
-
-        @Override
-        public String getKey() {
-            return mKey;
-        }
-
-        public int getIntensity() {
-            return mIntensity;
-        }
-    }
-
-    private class SettingsObserver extends ContentObserver {
-        public SettingsObserver() {
-            super(new Handler());
-        }
-
-        public void register() {
-            getContext().getContentResolver().registerContentObserver(
-                    Settings.System.getUriFor(getVibrationIntensitySetting()), false, this);
-        }
-
-        public void unregister() {
-            getContext().getContentResolver().unregisterContentObserver(this);
-        }
-
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            updateCandidates();
-            playVibrationPreview();
-        }
-    }
-}
diff --git a/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceController.java b/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceController.java
new file mode 100644
index 0000000..4a86538
--- /dev/null
+++ b/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceController.java
@@ -0,0 +1,140 @@
+/*
+ * 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.database.ContentObserver;
+import android.media.AudioManager;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.VibrationAttributes;
+import android.os.Vibrator;
+import android.provider.DeviceConfig;
+import android.provider.Settings;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.core.TogglePreferenceController;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+
+import com.google.common.annotations.VisibleForTesting;
+
+/**
+ * Preference controller for the ramping ringer setting key, controlled via {@link AudioManager}.
+ *
+ * <p>This preference depends on the {@link Settings.System#RING_VIBRATION_INTENSITY}, and it will
+ * be disabled and display the unchecked state when the ring intensity is set to OFF. The actual
+ * ramping ringer setting will not be overwritten when the ring intensity is turned off, so the
+ * user original value will be naturally restored when the ring intensity is enabled again.
+ */
+public class VibrationRampingRingerTogglePreferenceController
+        extends TogglePreferenceController implements LifecycleObserver, OnStart, OnStop {
+
+    @VisibleForTesting
+    static final String DEVICE_CONFIG_KEY = "ramping_ringer_enabled";
+
+    private final ContentObserver mSettingObserver;
+    private final Vibrator mVibrator;
+    private final AudioManager mAudioManager;
+
+    private Preference mPreference;
+
+    public VibrationRampingRingerTogglePreferenceController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+        mVibrator = context.getSystemService(Vibrator.class);
+        mAudioManager = context.getSystemService(AudioManager.class);
+        mSettingObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
+            @Override
+            public void onChange(boolean selfChange, Uri uri) {
+                updateState(mPreference);
+            }
+        };
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        final boolean rampingRingerEnabledOnTelephonyConfig =
+                DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_TELEPHONY, DEVICE_CONFIG_KEY, false);
+        return (Utils.isVoiceCapable(mContext) && !rampingRingerEnabledOnTelephonyConfig)
+                ? AVAILABLE
+                : UNSUPPORTED_ON_DEVICE;
+    }
+
+    @Override
+    public void onStart() {
+        mContext.getContentResolver().registerContentObserver(
+                Settings.System.getUriFor(Settings.System.APPLY_RAMPING_RINGER),
+                /* notifyForDescendants= */ false,
+                mSettingObserver);
+        mContext.getContentResolver().registerContentObserver(
+                Settings.System.getUriFor(Settings.System.RING_VIBRATION_INTENSITY),
+                /* notifyForDescendants= */ false,
+                mSettingObserver);
+    }
+
+    @Override
+    public void onStop() {
+        mContext.getContentResolver().unregisterContentObserver(mSettingObserver);
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = screen.findPreference(getPreferenceKey());
+        mPreference.setEnabled(isRingVibrationEnabled());
+    }
+
+    @Override
+    public boolean isChecked() {
+        return isRingVibrationEnabled() && mAudioManager.isRampingRingerEnabled();
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        if (isRingVibrationEnabled()) {
+            // Don't update ramping ringer setting value if ring vibration is disabled.
+            mAudioManager.setRampingRingerEnabled(isChecked);
+        }
+        return true;
+    }
+
+    @Override
+    public int getSliceHighlightMenuRes() {
+        return R.string.menu_key_accessibility;
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        super.updateState(preference);
+        if (preference != null) {
+            preference.setEnabled(isRingVibrationEnabled());
+        }
+    }
+
+    private boolean isRingVibrationEnabled() {
+        final int ringIntensity = Settings.System.getInt(mContext.getContentResolver(),
+                Settings.System.RING_VIBRATION_INTENSITY,
+                mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_RINGTONE));
+        return ringIntensity != Vibrator.VIBRATION_INTENSITY_OFF;
+    }
+}
diff --git a/src/com/android/settings/accessibility/VibrationSettings.java b/src/com/android/settings/accessibility/VibrationSettings.java
index 90ee11c..277cfee 100644
--- a/src/com/android/settings/accessibility/VibrationSettings.java
+++ b/src/com/android/settings/accessibility/VibrationSettings.java
@@ -41,7 +41,11 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.accessibility_vibration_settings;
+        final boolean supportsMultipleIntensities = getContext().getResources().getBoolean(
+                R.bool.config_vibration_supports_multiple_intensities);
+        return supportsMultipleIntensities
+                ? R.xml.accessibility_vibration_intensity_settings
+                : R.xml.accessibility_vibration_settings;
     }
 
     @Override
diff --git a/src/com/android/settings/accessibility/VibrationTogglePreferenceController.java b/src/com/android/settings/accessibility/VibrationTogglePreferenceController.java
new file mode 100644
index 0000000..5278b66
--- /dev/null
+++ b/src/com/android/settings/accessibility/VibrationTogglePreferenceController.java
@@ -0,0 +1,87 @@
+/*
+ * 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.os.Vibrator;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.core.TogglePreferenceController;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+
+/** Abstract preference controller for a vibration intensity setting, that has only ON/OFF states */
+public abstract class VibrationTogglePreferenceController extends TogglePreferenceController
+        implements LifecycleObserver, OnStart, OnStop {
+
+    protected final VibrationPreferenceConfig mPreferenceConfig;
+    private final VibrationPreferenceConfig.SettingObserver mSettingsContentObserver;
+
+    protected VibrationTogglePreferenceController(Context context, String preferenceKey,
+            VibrationPreferenceConfig preferenceConfig) {
+        super(context, preferenceKey);
+        mPreferenceConfig = preferenceConfig;
+        mSettingsContentObserver = new VibrationPreferenceConfig.SettingObserver(
+                preferenceConfig);
+    }
+
+    @Override
+    public void onStart() {
+        mSettingsContentObserver.register(mContext.getContentResolver());
+    }
+
+    @Override
+    public void onStop() {
+        mSettingsContentObserver.unregister(mContext.getContentResolver());
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        final Preference preference = screen.findPreference(getPreferenceKey());
+        mSettingsContentObserver.onDisplayPreference(this, preference);
+    }
+
+    @Override
+    public boolean isChecked() {
+        final int position = mPreferenceConfig.readIntensity();
+        return position != Vibrator.VIBRATION_INTENSITY_OFF;
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        final int newIntensity = isChecked
+                ? mPreferenceConfig.getDefaultIntensity()
+                : Vibrator.VIBRATION_INTENSITY_OFF;
+        final boolean success = mPreferenceConfig.updateIntensity(newIntensity);
+
+        if (success && isChecked) {
+            mPreferenceConfig.playVibrationPreview();
+        }
+
+        return success;
+    }
+
+    @Override
+    public int getSliceHighlightMenuRes() {
+        return R.string.menu_key_accessibility;
+    }
+}
diff --git a/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java b/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java
index ac3a01d..ab999ed 100644
--- a/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java
+++ b/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java
@@ -16,10 +16,7 @@
 
 package com.android.settings.activityembedding;
 
-import android.app.Activity;
-import android.app.ActivityTaskManager;
 import android.content.Context;
-import android.graphics.Rect;
 import android.util.DisplayMetrics;
 import android.util.FeatureFlagUtils;
 import android.util.Log;
@@ -65,13 +62,4 @@
 
         return isFlagEnabled && isSplitSupported;
     }
-
-    /** Whether the screen meets two-pane resolution. */
-    public static boolean isTwoPaneResolution(Activity activity) {
-        final Rect currentTaskBounds =
-                ActivityTaskManager.getInstance().getTaskBounds(activity.getTaskId());
-
-        return currentTaskBounds.width() >= getMinCurrentScreenSplitWidthPx(activity)
-                && currentTaskBounds.height() >= getMinSmallestScreenSplitWidthPx(activity);
-    }
 }
diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java
index 183a2fb..c56d89b 100644
--- a/src/com/android/settings/homepage/SettingsHomepageActivity.java
+++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java
@@ -42,6 +42,7 @@
 import androidx.fragment.app.FragmentActivity;
 import androidx.fragment.app.FragmentManager;
 import androidx.fragment.app.FragmentTransaction;
+import androidx.window.embedding.SplitController;
 import androidx.window.embedding.SplitRule;
 
 import com.android.settings.R;
@@ -85,8 +86,9 @@
     private View mTwoPaneSuggestionView;
     private CategoryMixin mCategoryMixin;
     private Set<HomepageLoadedListener> mLoadedListeners;
+    private SplitController mSplitController;
     private boolean mIsEmbeddingActivityEnabled;
-    private boolean mIsTwoPaneLastTime;
+    private boolean mIsTwoPane;
 
     /** A listener receiving homepage loaded events. */
     public interface HomepageLoadedListener {
@@ -149,7 +151,8 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.settings_homepage_container);
         mIsEmbeddingActivityEnabled = ActivityEmbeddingUtils.isEmbeddingActivityEnabled(this);
-        mIsTwoPaneLastTime = ActivityEmbeddingUtils.isTwoPaneResolution(this);
+        mSplitController = SplitController.getInstance();
+        mIsTwoPane = mSplitController.isActivityEmbedded(this);
 
         final View appBar = findViewById(R.id.app_bar_container);
         appBar.setMinimumHeight(getSearchBoxHeight());
@@ -213,9 +216,9 @@
     @Override
     public void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
-        final boolean isTwoPane = ActivityEmbeddingUtils.isTwoPaneResolution(this);
-        if (mIsTwoPaneLastTime != isTwoPane) {
-            mIsTwoPaneLastTime = isTwoPane;
+        final boolean newTwoPaneState = mSplitController.isActivityEmbedded(this);
+        if (mIsTwoPane != newTwoPaneState) {
+            mIsTwoPane = newTwoPaneState;
             updateHomepageAppBar();
             updateHomepageBackground();
         }
@@ -254,7 +257,7 @@
         }
 
         final Window window = getWindow();
-        final int color = ActivityEmbeddingUtils.isTwoPaneResolution(this)
+        final int color = mIsTwoPane
                 ? Utils.getColorAttrDefaultColor(this, com.android.internal.R.attr.colorSurface)
                 : Utils.getColorAttrDefaultColor(this, android.R.attr.colorBackground);
 
@@ -416,7 +419,7 @@
         if (!mIsEmbeddingActivityEnabled) {
             return;
         }
-        if (ActivityEmbeddingUtils.isTwoPaneResolution(this)) {
+        if (mIsTwoPane) {
             findViewById(R.id.homepage_app_bar_regular_phone_view).setVisibility(View.GONE);
             findViewById(R.id.homepage_app_bar_two_pane_view).setVisibility(View.VISIBLE);
         } else {
diff --git a/src/com/android/settings/homepage/TopLevelSettings.java b/src/com/android/settings/homepage/TopLevelSettings.java
index f76a3de..7ce6730 100644
--- a/src/com/android/settings/homepage/TopLevelSettings.java
+++ b/src/com/android/settings/homepage/TopLevelSettings.java
@@ -33,6 +33,7 @@
 import androidx.preference.PreferenceFragmentCompat;
 import androidx.preference.PreferenceScreen;
 import androidx.recyclerview.widget.RecyclerView;
+import androidx.window.embedding.SplitController;
 
 import com.android.settings.R;
 import com.android.settings.Utils;
@@ -144,7 +145,7 @@
         if (mFirstStarted) {
             mFirstStarted = false;
         } else if (mIsEmbeddingActivityEnabled && isOnlyOneActivityInTask()
-                && !ActivityEmbeddingUtils.isTwoPaneResolution(getActivity())) {
+                && !SplitController.getInstance().isActivityEmbedded(getActivity())) {
             // Set default highlight menu key for 1-pane homepage since it will show the placeholder
             // page once changing back to 2-pane.
             Log.i(TAG, "Set default menu key");
diff --git a/src/com/android/settings/notification/app/VibrationPreferenceController.java b/src/com/android/settings/notification/app/VibrationPreferenceController.java
index bfbe768..34d1a54 100644
--- a/src/com/android/settings/notification/app/VibrationPreferenceController.java
+++ b/src/com/android/settings/notification/app/VibrationPreferenceController.java
@@ -25,7 +25,6 @@
 
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.notification.NotificationBackend;
-import com.android.settings.notification.app.NotificationPreferenceController;
 import com.android.settingslib.RestrictedSwitchPreference;
 
 public class VibrationPreferenceController extends NotificationPreferenceController
@@ -36,7 +35,7 @@
 
     public VibrationPreferenceController(Context context, NotificationBackend backend) {
         super(context, backend);
-        mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
+        mVibrator = context.getSystemService(Vibrator.class);
     }
 
     @Override
diff --git a/src/com/android/settings/privacy/PrivacyDashboardFragment.java b/src/com/android/settings/privacy/PrivacyDashboardFragment.java
index cc0e8a1..c2aeeaf 100644
--- a/src/com/android/settings/privacy/PrivacyDashboardFragment.java
+++ b/src/com/android/settings/privacy/PrivacyDashboardFragment.java
@@ -22,6 +22,7 @@
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.notification.LockScreenNotificationPreferenceController;
+import com.android.settings.safetycenter.SafetyCenterStatus;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -89,5 +90,10 @@
                         Context context) {
                     return buildPreferenceControllers(context, null);
                 }
+
+                @Override
+                protected boolean isPageSearchEnabled(Context context) {
+                    return !SafetyCenterStatus.isEnabled();
+                }
             };
 }
diff --git a/src/com/android/settings/sound/VibrateForCallsPreferenceController.java b/src/com/android/settings/sound/VibrateForCallsPreferenceController.java
deleted file mode 100644
index 58c6ba5..0000000
--- a/src/com/android/settings/sound/VibrateForCallsPreferenceController.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.sound;
-
-import android.content.Context;
-import android.provider.DeviceConfig;
-import android.provider.Settings;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.android.settings.R;
-import com.android.settings.Utils;
-import com.android.settings.core.BasePreferenceController;
-
-/**
- * Controller for vibrate for calls settings.
- */
-public class VibrateForCallsPreferenceController extends BasePreferenceController {
-
-    private static final int ON = 1;
-    private static final int OFF = 0;
-    @VisibleForTesting
-    static final String RAMPING_RINGER_ENABLED = "ramping_ringer_enabled";
-
-    public VibrateForCallsPreferenceController(Context context, String preferenceKey) {
-        super(context, preferenceKey);
-    }
-
-    @Override
-    @AvailabilityStatus
-    public int getAvailabilityStatus() {
-        return Utils.isVoiceCapable(mContext) && !DeviceConfig.getBoolean(
-                DeviceConfig.NAMESPACE_TELEPHONY, RAMPING_RINGER_ENABLED, false)
-            ? AVAILABLE
-            : UNSUPPORTED_ON_DEVICE;
-    }
-
-    @Override
-    public CharSequence getSummary() {
-        if (Settings.System.getInt(
-                mContext.getContentResolver(),
-                Settings.System.APPLY_RAMPING_RINGER, OFF) == ON) {
-            return mContext.getText(R.string.vibrate_when_ringing_option_ramping_ringer);
-        } else if (Settings.System.getInt(
-                    mContext.getContentResolver(),
-                    Settings.System.VIBRATE_WHEN_RINGING, OFF) == ON) {
-            return mContext.getText(R.string.vibrate_when_ringing_option_always_vibrate);
-        } else {
-            return mContext.getText(R.string.vibrate_when_ringing_option_never_vibrate);
-        }
-    }
-}
diff --git a/src/com/android/settings/sound/VibrateForCallsPreferenceFragment.java b/src/com/android/settings/sound/VibrateForCallsPreferenceFragment.java
deleted file mode 100644
index a769de1..0000000
--- a/src/com/android/settings/sound/VibrateForCallsPreferenceFragment.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.sound;
-
-import android.app.settings.SettingsEnums;
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.android.settings.R;
-import com.android.settings.widget.RadioButtonPickerFragment;
-import com.android.settingslib.widget.CandidateInfo;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Fragment for changing vibrate for calls options.
- */
-public class VibrateForCallsPreferenceFragment extends RadioButtonPickerFragment {
-    private static final String TAG = "VibrateForCallsPreferenceFragment";
-
-    @VisibleForTesting
-    static final String KEY_NEVER_VIBRATE = "never_vibrate";
-    @VisibleForTesting
-    static final String KEY_ALWAYS_VIBRATE = "always_vibrate";
-    @VisibleForTesting
-    static final String KEY_RAMPING_RINGER = "ramping_ringer";
-
-    private static final int ON = 1;
-    private static final int OFF = 0;
-
-    private final Map<String, VibrateForCallsCandidateInfo> mCandidates;
-
-    public VibrateForCallsPreferenceFragment() {
-        mCandidates = new ArrayMap<>();
-    }
-
-    @Override
-    public void onAttach(Context context) {
-        super.onAttach(context);
-        loadCandidates(context);
-    }
-
-    private void loadCandidates(Context context) {
-        mCandidates.put(KEY_NEVER_VIBRATE,
-                new VibrateForCallsCandidateInfo(
-                        KEY_NEVER_VIBRATE, R.string.vibrate_when_ringing_option_never_vibrate));
-        mCandidates.put(KEY_ALWAYS_VIBRATE,
-                new VibrateForCallsCandidateInfo(
-                        KEY_ALWAYS_VIBRATE, R.string.vibrate_when_ringing_option_always_vibrate));
-        mCandidates.put(KEY_RAMPING_RINGER,
-                new VibrateForCallsCandidateInfo(
-                        KEY_RAMPING_RINGER, R.string.vibrate_when_ringing_option_ramping_ringer));
-    }
-
-    private void updateSettings(VibrateForCallsCandidateInfo candidate) {
-        final String key = candidate.getKey();
-        if (TextUtils.equals(key, KEY_ALWAYS_VIBRATE)) {
-            Settings.System.putInt(
-                    getContext().getContentResolver(), Settings.System.VIBRATE_WHEN_RINGING, ON);
-            Settings.System.putInt(
-                    getContext().getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, OFF);
-        } else if (TextUtils.equals(key, KEY_RAMPING_RINGER)) {
-            Settings.System.putInt(
-                    getContext().getContentResolver(), Settings.System.VIBRATE_WHEN_RINGING, OFF);
-            Settings.System.putInt(
-                    getContext().getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, ON);
-        } else {
-            Settings.System.putInt(
-                    getContext().getContentResolver(), Settings.System.VIBRATE_WHEN_RINGING, OFF);
-            Settings.System.putInt(
-                    getContext().getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, OFF);
-        }
-    }
-
-    @Override
-    protected List<? extends CandidateInfo> getCandidates() {
-        final List<VibrateForCallsCandidateInfo> candidates = new ArrayList<>();
-        candidates.add(mCandidates.get(KEY_NEVER_VIBRATE));
-        candidates.add(mCandidates.get(KEY_ALWAYS_VIBRATE));
-        candidates.add(mCandidates.get(KEY_RAMPING_RINGER));
-        return candidates;
-    }
-
-    @Override
-    protected String getDefaultKey() {
-        if (Settings.System.getInt(
-                 getContext().getContentResolver(),
-                 Settings.System.APPLY_RAMPING_RINGER, OFF) == ON) {
-            return KEY_RAMPING_RINGER;
-        } else if (Settings.System.getInt(
-                    getContext().getContentResolver(),
-                    Settings.System.VIBRATE_WHEN_RINGING, OFF) == ON) {
-            return KEY_ALWAYS_VIBRATE;
-        } else {
-            return KEY_NEVER_VIBRATE;
-        }
-    }
-
-    @Override
-    protected boolean setDefaultKey(String key) {
-        final VibrateForCallsCandidateInfo candidate = mCandidates.get(key);
-        if (candidate == null) {
-            Log.e(TAG, "Unknown vibrate for calls candidate (key = " + key + ")!");
-            return false;
-        }
-        updateSettings(candidate);
-        return true;
-    }
-
-    @Override
-    protected int getPreferenceScreenResId() {
-        return R.xml.vibrate_for_calls_settings;
-    }
-
-    @Override
-    public int getMetricsCategory() {
-        return SettingsEnums.VIBRATE_FOR_CALLS;
-    }
-
-    @VisibleForTesting
-    class VibrateForCallsCandidateInfo extends CandidateInfo {
-        private final String mKey;
-        private final int mLabelId;
-
-        VibrateForCallsCandidateInfo(String key, int labelId) {
-            super(true /* enabled */);
-            mKey = key;
-            mLabelId = labelId;
-        }
-
-        @Override
-        public CharSequence loadLabel() {
-            return getContext().getString(mLabelId);
-        }
-
-        @Override
-        public Drawable loadIcon() {
-            return null;
-        }
-
-        @Override
-        public String getKey() {
-            return mKey;
-        }
-    }
-}
diff --git a/src/com/android/settings/users/UserCapabilities.java b/src/com/android/settings/users/UserCapabilities.java
index 7af6c64..620738f 100644
--- a/src/com/android/settings/users/UserCapabilities.java
+++ b/src/com/android/settings/users/UserCapabilities.java
@@ -23,6 +23,7 @@
 import android.os.UserManager;
 import android.provider.Settings;
 
+import com.android.settings.R;
 import com.android.settings.Utils;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.RestrictedLockUtilsInternal;
@@ -30,7 +31,7 @@
 public class UserCapabilities {
     boolean mEnabled = true;
     boolean mCanAddUser = true;
-    boolean mCanAddRestrictedProfile = true;
+    boolean mCanAddRestrictedProfile;
     boolean mIsAdmin;
     boolean mIsGuest;
     boolean mUserSwitcherEnabled;
@@ -57,12 +58,13 @@
         caps.mIsAdmin = myUserInfo.isAdmin();
         DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
-        // No restricted profiles for tablets with a device owner, or phones.
-        if (dpm.isDeviceManaged()
-                || Utils.isVoiceCapable(context)
-                || !userManager.isUserTypeEnabled(UserManager.USER_TYPE_FULL_RESTRICTED)) {
-            caps.mCanAddRestrictedProfile = false;
-        }
+
+        boolean offerRestricted =
+                context.getResources().getBoolean(R.bool.config_offer_restricted_profiles);
+        caps.mCanAddRestrictedProfile =
+                offerRestricted && !dpm.isDeviceManaged() && userManager.isUserTypeEnabled(
+                        UserManager.USER_TYPE_FULL_RESTRICTED);
+
         caps.updateAddUserCapabilities(context);
         return caps;
     }
diff --git a/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java b/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
index ff8f805..ddd57f3 100644
--- a/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
+++ b/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
@@ -31,10 +31,10 @@
 import androidx.preference.PreferenceGroupAdapter;
 import androidx.preference.PreferenceViewHolder;
 import androidx.recyclerview.widget.RecyclerView;
+import androidx.window.embedding.SplitController;
 
 import com.android.settings.R;
 import com.android.settings.Utils;
-import com.android.settings.activityembedding.ActivityEmbeddingUtils;
 import com.android.settings.homepage.SettingsHomepageActivity;
 
 /**
@@ -255,6 +255,6 @@
     }
 
     private boolean isHighlightNeeded() {
-        return ActivityEmbeddingUtils.isTwoPaneResolution(mHomepageActivity);
+        return SplitController.getInstance().isActivityEmbedded(mHomepageActivity);
     }
 }
diff --git a/src/com/android/settings/wifi/AddWifiNetworkPreference.java b/src/com/android/settings/wifi/AddWifiNetworkPreference.java
index ff4d38e..1820539 100644
--- a/src/com/android/settings/wifi/AddWifiNetworkPreference.java
+++ b/src/com/android/settings/wifi/AddWifiNetworkPreference.java
@@ -26,8 +26,10 @@
 import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
 import com.android.settings.wifi.dpp.WifiDppUtils;
+import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils;
 
 /**
  * The Preference for users to add Wi-Fi networks in WifiSettings
@@ -37,6 +39,8 @@
     private static final String TAG = "AddWifiNetworkPreference";
 
     private final Drawable mScanIconDrawable;
+    @VisibleForTesting
+    boolean mIsAddWifiConfigAllow;
 
     public AddWifiNetworkPreference(Context context) {
         super(context);
@@ -47,6 +51,8 @@
         setTitle(R.string.wifi_add_network);
 
         mScanIconDrawable = getDrawable(R.drawable.ic_scan_24dp);
+        mIsAddWifiConfigAllow = WifiEnterpriseRestrictionUtils.isAddWifiConfigAllowed(context);
+        updatePreferenceForRestriction();
     }
 
     @Override
@@ -73,4 +79,12 @@
         }
         return buttonIcon;
     }
+
+    @VisibleForTesting
+    void updatePreferenceForRestriction() {
+        if (!mIsAddWifiConfigAllow) {
+            setEnabled(false);
+            setSummary(R.string.not_allowed_by_ent);
+        }
+    }
 }
diff --git a/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java b/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java
index 6bf9104..f1e6568 100644
--- a/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java
+++ b/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java
@@ -36,6 +36,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
 import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
+import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils;
 
 /**
  * When apps send a new intent with a WifiConfiguration list extra to Settings APP. Settings APP
@@ -55,6 +56,8 @@
     final Bundle mBundle = new Bundle();
     @VisibleForTesting
     IActivityManager mActivityManager = ActivityManager.getService();
+    @VisibleForTesting
+    boolean mIsAddWifiConfigAllow;
 
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -71,6 +74,8 @@
         window.setGravity(Gravity.BOTTOM);
         window.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
                 WindowManager.LayoutParams.WRAP_CONTENT);
+
+        mIsAddWifiConfigAllow = WifiEnterpriseRestrictionUtils.isAddWifiConfigAllowed(this);
     }
 
     @Override
@@ -85,6 +90,10 @@
 
     @VisibleForTesting
     protected boolean showAddNetworksFragment() {
+        if (!mIsAddWifiConfigAllow) {
+            Log.d(TAG, "Not allowed by Enterprise Restriction");
+            return false;
+        }
         String packageName = getCallingAppPackageName();
         if (TextUtils.isEmpty(packageName)) {
             Log.d(TAG, "Package name is null");
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityQuickSettingsTooltipWindowTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityQuickSettingsTooltipWindowTest.java
new file mode 100644
index 0000000..f1e1121b
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityQuickSettingsTooltipWindowTest.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.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.PopupWindow;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.R;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.shadows.ShadowLooper;
+
+/** Tests for {@link AccessibilityQuickSettingsTooltipWindow}. */
+@RunWith(RobolectricTestRunner.class)
+public class AccessibilityQuickSettingsTooltipWindowTest {
+
+    @Rule
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+    @Mock
+    private PopupWindow.OnDismissListener mMockOnDismissListener;
+
+    private static final String TEST_PACKAGE_NAME = "com.test.package";
+    private final Context mContext = ApplicationProvider.getApplicationContext();
+    private AccessibilityQuickSettingsTooltipWindow mToolTipView;
+    private View mView;
+
+    @Before
+    public void setUp() {
+        mToolTipView = new AccessibilityQuickSettingsTooltipWindow(mContext);
+        mView = new View(RuntimeEnvironment.application);
+    }
+
+    @Test
+    public void initToolTipView_atMostAvailableTextWidth() {
+        final String quickSettingsTooltipsContent = mContext.getString(
+                R.string.accessibility_service_quick_settings_tooltips_content, TEST_PACKAGE_NAME);
+        mToolTipView.setup(quickSettingsTooltipsContent);
+
+        final int getMaxWidth = mToolTipView.getAvailableWindowWidth();
+        assertThat(mToolTipView.getWidth()).isAtMost(getMaxWidth);
+    }
+
+    @Test
+    public void showToolTipView_success() {
+        mToolTipView.setup(TEST_PACKAGE_NAME);
+        assertThat(getLatestPopupWindow()).isNull();
+
+        mToolTipView.showAtTopCenter(mView);
+
+        assertThat(getLatestPopupWindow()).isSameInstanceAs(mToolTipView);
+    }
+
+    @Test
+    public void dismiss_toolTipViewShown_shouldInvokeCallbackAndNotShowing() {
+        mToolTipView.setup(TEST_PACKAGE_NAME);
+        mToolTipView.setOnDismissListener(mMockOnDismissListener);
+        mToolTipView.showAtTopCenter(mView);
+
+        mToolTipView.dismiss();
+
+        verify(mMockOnDismissListener).onDismiss();
+        assertThat(getLatestPopupWindow().isShowing()).isFalse();
+    }
+
+    @Test
+    public void waitAutoCloseDelayTime_toolTipViewShown_shouldInvokeCallbackAndNotShowing() {
+        mToolTipView.setup(TEST_PACKAGE_NAME, /* closeDelayTimeMillis= */ 1);
+        mToolTipView.setOnDismissListener(mMockOnDismissListener);
+        mToolTipView.showAtTopCenter(mView);
+
+        ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
+
+        verify(mMockOnDismissListener).onDismiss();
+        assertThat(getLatestPopupWindow().isShowing()).isFalse();
+    }
+
+    private static PopupWindow getLatestPopupWindow() {
+        final ShadowApplication shadowApplication = Shadow.extract(RuntimeEnvironment.application);
+        return shadowApplication.getLatestPopupWindow();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
index c9f1b66..d1c59f7 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
@@ -52,7 +52,6 @@
 import com.android.internal.content.PackageMonitor;
 import com.android.settings.R;
 import com.android.settings.testutils.XmlTestUtils;
-import com.android.settings.testutils.shadow.ShadowDeviceConfig;
 import com.android.settings.testutils.shadow.ShadowFragment;
 import com.android.settings.testutils.shadow.ShadowUserManager;
 import com.android.settingslib.RestrictedPreference;
@@ -144,22 +143,6 @@
     }
 
     @Test
-    @Config(shadows = {ShadowDeviceConfig.class})
-    public void isRampingRingerEnabled_settingsFlagOn_Enabled() {
-        Settings.System.putInt(
-                mContext.getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, ON);
-        assertThat(AccessibilitySettings.isRampingRingerEnabled(mContext)).isTrue();
-    }
-
-    @Test
-    @Config(shadows = {ShadowDeviceConfig.class})
-    public void isRampingRingerEnabled_settingsFlagOff_Disabled() {
-        Settings.System.putInt(
-                mContext.getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, OFF);
-        assertThat(AccessibilitySettings.isRampingRingerEnabled(mContext)).isFalse();
-    }
-
-    @Test
     public void getServiceSummary_serviceCrash_showsStopped() {
         mServiceInfo.crashed = true;
 
diff --git a/tests/robotests/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceControllerTest.java
index a454831..4e8b3f6 100644
--- a/tests/robotests/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceControllerTest.java
@@ -18,42 +18,136 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
 import android.content.Context;
+import android.os.VibrationAttributes;
+import android.os.Vibrator;
+import android.provider.Settings;
 
 import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
 
 import com.android.settings.core.BasePreferenceController;
+import com.android.settings.widget.SeekBarPreference;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 
 @RunWith(RobolectricTestRunner.class)
 public class HapticFeedbackIntensityPreferenceControllerTest {
 
+    private static final String PREFERENCE_KEY = "preference_key";
+    private static final int OFF = 0;
+    private static final int ON = 1;
+
+    @Mock
+    private PreferenceScreen mScreen;
+
     private LifecycleOwner mLifecycleOwner;
     private Lifecycle mLifecycle;
     private Context mContext;
+    private Vibrator mVibrator;
     private HapticFeedbackIntensityPreferenceController mController;
+    private SeekBarPreference mPreference;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mLifecycleOwner = () -> mLifecycle;
         mLifecycle = new Lifecycle(mLifecycleOwner);
-        mContext = RuntimeEnvironment.application;
-        mController = new HapticFeedbackIntensityPreferenceController(mContext);
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        mVibrator = mContext.getSystemService(Vibrator.class);
+        mController = new HapticFeedbackIntensityPreferenceController(mContext, PREFERENCE_KEY);
+        mLifecycle.addObserver(mController);
+        mPreference = new SeekBarPreference(mContext);
+        mPreference.setSummary("Test summary");
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+        showPreference();
     }
 
     @Test
     public void verifyConstants() {
-        assertThat(mController.getPreferenceKey())
-                .isEqualTo(HapticFeedbackIntensityPreferenceController.PREF_KEY);
+        assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
         assertThat(mController.getAvailabilityStatus())
                 .isEqualTo(BasePreferenceController.AVAILABLE);
+        assertThat(mController.getMin()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+        assertThat(mController.getMax()).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
+    }
+
+    @Test
+    public void missingSetting_shouldReturnDefault() {
+        Settings.System.putString(mContext.getContentResolver(),
+                Settings.System.HAPTIC_FEEDBACK_INTENSITY, /* value= */ null);
+        mController.updateState(mPreference);
+        assertThat(mPreference.getProgress())
+                .isEqualTo(mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_TOUCH));
+    }
+
+    @Test
+    public void updateState_shouldDisplayIntensityInSliderPosition() {
+        updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
+        mController.updateState(mPreference);
+        assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
+
+        updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY,
+                Vibrator.VIBRATION_INTENSITY_MEDIUM);
+        mController.updateState(mPreference);
+        assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_MEDIUM);
+
+        updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
+        mController.updateState(mPreference);
+        assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
+
+        updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
+        mController.updateState(mPreference);
+        assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+    }
+
+    @Test
+    public void setProgress_updatesIntensityAndDependentSettings() throws Exception {
+        mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_OFF);
+        assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY))
+                .isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+        assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED)).isEqualTo(OFF);
+
+        mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_LOW);
+        assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY))
+                .isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
+        assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED)).isEqualTo(ON);
+
+        mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_MEDIUM);
+        assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY))
+                .isEqualTo(Vibrator.VIBRATION_INTENSITY_MEDIUM);
+        assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED)).isEqualTo(ON);
+
+        mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_HIGH);
+        assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY))
+                .isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
+        assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED)).isEqualTo(ON);
+
+        mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_OFF);
+        assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY))
+                .isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+        assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED)).isEqualTo(OFF);
+    }
+
+    private void updateSetting(String key, int value) {
+        Settings.System.putInt(mContext.getContentResolver(), key, value);
+    }
+
+    private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
+        return Settings.System.getInt(mContext.getContentResolver(), settingKey);
+    }
+
+    private void showPreference() {
+        mController.displayPreference(mScreen);
     }
 }
diff --git a/tests/robotests/src/com/android/settings/accessibility/HapticFeedbackTogglePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/HapticFeedbackTogglePreferenceControllerTest.java
new file mode 100644
index 0000000..25455f4
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/HapticFeedbackTogglePreferenceControllerTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.VibrationAttributes;
+import android.os.Vibrator;
+import android.provider.Settings;
+
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class HapticFeedbackTogglePreferenceControllerTest {
+
+    private static final String PREFERENCE_KEY = "preference_key";
+    private static final int OFF = 0;
+    private static final int ON = 1;
+
+    @Mock
+    private PreferenceScreen mScreen;
+
+    private LifecycleOwner mLifecycleOwner;
+    private Lifecycle mLifecycle;
+    private Context mContext;
+    private Vibrator mVibrator;
+    private HapticFeedbackTogglePreferenceController mController;
+    private SwitchPreference mPreference;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mLifecycleOwner = () -> mLifecycle;
+        mLifecycle = new Lifecycle(mLifecycleOwner);
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        mVibrator = mContext.getSystemService(Vibrator.class);
+        mController = new HapticFeedbackTogglePreferenceController(mContext, PREFERENCE_KEY);
+        mLifecycle.addObserver(mController);
+        mPreference = new SwitchPreference(mContext);
+        mPreference.setSummary("Test summary");
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+        showPreference();
+    }
+
+    @Test
+    public void verifyConstants() {
+        assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
+        assertThat(mController.getAvailabilityStatus())
+                .isEqualTo(BasePreferenceController.AVAILABLE);
+    }
+
+    @Test
+    public void missingSetting_shouldReturnDefault() {
+        Settings.System.putString(mContext.getContentResolver(),
+                Settings.System.HAPTIC_FEEDBACK_INTENSITY, /* value= */ null);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isChecked()).isTrue();
+    }
+
+    @Test
+    public void updateState_shouldDisplayOnOffState() {
+        updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isChecked()).isTrue();
+
+        updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY,
+                Vibrator.VIBRATION_INTENSITY_MEDIUM);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isChecked()).isTrue();
+
+        updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isChecked()).isTrue();
+
+        updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isChecked()).isFalse();
+    }
+
+    @Test
+    public void setChecked_updatesIntensityAndDependentSettings() throws Exception {
+        updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isChecked()).isFalse();
+
+        mPreference.setChecked(true);
+        assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY))
+                .isEqualTo(mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_TOUCH));
+        assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED)).isEqualTo(ON);
+
+        mPreference.setChecked(false);
+        assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY))
+                .isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+        assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED)).isEqualTo(OFF);
+    }
+
+    private void updateSetting(String key, int value) {
+        Settings.System.putInt(mContext.getContentResolver(), key, value);
+    }
+
+    private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
+        return Settings.System.getInt(mContext.getContentResolver(), settingKey);
+    }
+
+    private void showPreference() {
+        mController.displayPreference(mScreen);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceControllerTest.java
index 41accfb..9dbd6d1 100644
--- a/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceControllerTest.java
@@ -16,24 +16,22 @@
 
 package com.android.settings.accessibility;
 
-import static android.provider.Settings.System.NOTIFICATION_VIBRATION_INTENSITY;
-
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
-import android.content.res.Resources;
+import android.os.VibrationAttributes;
 import android.os.Vibrator;
 import android.provider.Settings;
 
 import androidx.lifecycle.LifecycleOwner;
-import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
 
-import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
+import com.android.settings.widget.SeekBarPreference;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 
 import org.junit.Before;
@@ -42,115 +40,105 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 
 @RunWith(RobolectricTestRunner.class)
 public class NotificationVibrationIntensityPreferenceControllerTest {
 
+    private static final String PREFERENCE_KEY = "preference_key";
+
     @Mock
     private PreferenceScreen mScreen;
 
     private LifecycleOwner mLifecycleOwner;
     private Lifecycle mLifecycle;
     private Context mContext;
-    private Resources mResources;
+    private Vibrator mVibrator;
     private NotificationVibrationIntensityPreferenceController mController;
-    private Preference mPreference;
+    private SeekBarPreference mPreference;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mLifecycleOwner = () -> mLifecycle;
         mLifecycle = new Lifecycle(mLifecycleOwner);
-        mContext = spy(RuntimeEnvironment.application);
-        mResources = spy(mContext.getResources());
-        when(mContext.getResources()).thenReturn(mResources);
-        when(mResources.getBoolean(R.bool.config_vibration_supports_multiple_intensities))
-            .thenReturn(true);
-        mController = new NotificationVibrationIntensityPreferenceController(mContext) {
-            @Override
-            protected int getDefaultIntensity() {
-                return 10;
-            }
-        };
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        mVibrator = mContext.getSystemService(Vibrator.class);
+        mController = new NotificationVibrationIntensityPreferenceController(mContext,
+                PREFERENCE_KEY);
         mLifecycle.addObserver(mController);
-        mPreference = new Preference(mContext);
-        mPreference.setSummary("Test");
-        when(mScreen.findPreference(mController.getPreferenceKey()))
-                .thenReturn(mPreference);
+        mPreference = new SeekBarPreference(mContext);
+        mPreference.setSummary("Test summary");
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+        showPreference();
     }
 
     @Test
     public void verifyConstants() {
-        assertThat(mController.getPreferenceKey())
-                .isEqualTo(NotificationVibrationIntensityPreferenceController.PREF_KEY);
+        assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
         assertThat(mController.getAvailabilityStatus())
                 .isEqualTo(BasePreferenceController.AVAILABLE);
+        assertThat(mController.getMin()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+        assertThat(mController.getMax()).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
     }
 
     @Test
-    public void updateState_withMultipleIntensitySuport_shouldRefreshSummary() {
-        setSupportsMultipleIntensities(true);
-        showPreference();
-
-        Settings.System.putInt(mContext.getContentResolver(),
-                NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
+    public void missingSetting_shouldReturnDefault() {
+        Settings.System.putString(mContext.getContentResolver(),
+                Settings.System.NOTIFICATION_VIBRATION_INTENSITY, /* value= */ null);
         mController.updateState(mPreference);
-        assertThat(mPreference.getSummary())
-                .isEqualTo(mContext.getString(R.string.accessibility_vibration_intensity_low));
-
-        Settings.System.putInt(mContext.getContentResolver(),
-                NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
-        mController.updateState(mPreference);
-        assertThat(mPreference.getSummary())
-                .isEqualTo(mContext.getString(R.string.accessibility_vibration_intensity_high));
-
-        Settings.System.putInt(mContext.getContentResolver(),
-                NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_MEDIUM);
-        mController.updateState(mPreference);
-        assertThat(mPreference.getSummary())
-                .isEqualTo(mContext.getString(R.string.accessibility_vibration_intensity_medium));
-
-        Settings.System.putInt(mContext.getContentResolver(),
-                NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
-        mController.updateState(mPreference);
-        assertThat(mPreference.getSummary())
-                .isEqualTo(mContext.getString(R.string.accessibility_vibration_intensity_off));
+        assertThat(mPreference.getProgress()).isEqualTo(
+                mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_NOTIFICATION));
     }
 
     @Test
-    public void updateState_withoutMultipleIntensitySupport_shouldRefreshSummary() {
-        setSupportsMultipleIntensities(false);
-        showPreference();
-
-        Settings.System.putInt(mContext.getContentResolver(),
-                NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
+    public void updateState_shouldDisplayIntensityInSliderPosition() {
+        updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+                Vibrator.VIBRATION_INTENSITY_HIGH);
         mController.updateState(mPreference);
-        assertThat(mPreference.getSummary())
-                .isEqualTo(mContext.getString(R.string.switch_on_text));
+        assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
 
-        Settings.System.putInt(mContext.getContentResolver(),
-                NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
+        updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+                Vibrator.VIBRATION_INTENSITY_MEDIUM);
         mController.updateState(mPreference);
-        assertThat(mPreference.getSummary())
-                .isEqualTo(mContext.getString(R.string.switch_on_text));
+        assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_MEDIUM);
 
-        Settings.System.putInt(mContext.getContentResolver(),
-                NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_MEDIUM);
+        updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+                Vibrator.VIBRATION_INTENSITY_LOW);
         mController.updateState(mPreference);
-        assertThat(mPreference.getSummary())
-                .isEqualTo(mContext.getString(R.string.switch_on_text));
+        assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
 
-        Settings.System.putInt(mContext.getContentResolver(),
-                NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
+        updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+                Vibrator.VIBRATION_INTENSITY_OFF);
         mController.updateState(mPreference);
-        assertThat(mPreference.getSummary())
-                .isEqualTo(mContext.getString(R.string.switch_off_text));
+        assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
     }
 
-    private void setSupportsMultipleIntensities(boolean hasSupport) {
-        when(mResources.getBoolean(R.bool.config_vibration_supports_multiple_intensities))
-            .thenReturn(hasSupport);
+
+    @Test
+    public void setProgress_updatesIntensitySetting() throws Exception {
+        mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_OFF);
+        assertThat(readSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY))
+                .isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+
+        mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_LOW);
+        assertThat(readSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY))
+                .isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
+
+        mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_MEDIUM);
+        assertThat(readSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY))
+                .isEqualTo(Vibrator.VIBRATION_INTENSITY_MEDIUM);
+
+        mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_HIGH);
+        assertThat(readSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY))
+                .isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
+    }
+
+    private void updateSetting(String key, int value) {
+        Settings.System.putInt(mContext.getContentResolver(), key, value);
+    }
+
+    private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
+        return Settings.System.getInt(mContext.getContentResolver(), settingKey);
     }
 
     private void showPreference() {
diff --git a/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationTogglePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationTogglePreferenceControllerTest.java
new file mode 100644
index 0000000..d40d779
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationTogglePreferenceControllerTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.VibrationAttributes;
+import android.os.Vibrator;
+import android.provider.Settings;
+
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class NotificationVibrationTogglePreferenceControllerTest {
+
+    private static final String PREFERENCE_KEY = "preference_key";
+
+    @Mock
+    private PreferenceScreen mScreen;
+
+    private LifecycleOwner mLifecycleOwner;
+    private Lifecycle mLifecycle;
+    private Context mContext;
+    private Vibrator mVibrator;
+    private NotificationVibrationTogglePreferenceController mController;
+    private SwitchPreference mPreference;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mLifecycleOwner = () -> mLifecycle;
+        mLifecycle = new Lifecycle(mLifecycleOwner);
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        mVibrator = mContext.getSystemService(Vibrator.class);
+        mController = new NotificationVibrationTogglePreferenceController(mContext, PREFERENCE_KEY);
+        mLifecycle.addObserver(mController);
+        mPreference = new SwitchPreference(mContext);
+        mPreference.setSummary("Test summary");
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+        showPreference();
+    }
+
+    @Test
+    public void verifyConstants() {
+        assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
+        assertThat(mController.getAvailabilityStatus())
+                .isEqualTo(BasePreferenceController.AVAILABLE);
+    }
+
+    @Test
+    public void missingSetting_shouldReturnDefault() {
+        Settings.System.putString(mContext.getContentResolver(),
+                Settings.System.NOTIFICATION_VIBRATION_INTENSITY, /* value= */ null);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isChecked()).isTrue();
+    }
+
+    @Test
+    public void updateState_shouldDisplayOnOffState() {
+        updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+                Vibrator.VIBRATION_INTENSITY_HIGH);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isChecked()).isTrue();
+
+        updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+                Vibrator.VIBRATION_INTENSITY_MEDIUM);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isChecked()).isTrue();
+
+        updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+                Vibrator.VIBRATION_INTENSITY_LOW);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isChecked()).isTrue();
+
+        updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+                Vibrator.VIBRATION_INTENSITY_OFF);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isChecked()).isFalse();
+    }
+
+    @Test
+    public void setChecked_updatesIntensityAndDependentSettings() throws Exception {
+        updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+                Vibrator.VIBRATION_INTENSITY_OFF);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isChecked()).isFalse();
+
+        mPreference.setChecked(true);
+        assertThat(readSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY)).isEqualTo(
+                mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_NOTIFICATION));
+
+        mPreference.setChecked(false);
+        assertThat(readSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY))
+                .isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+    }
+
+    private void updateSetting(String key, int value) {
+        Settings.System.putInt(mContext.getContentResolver(), key, value);
+    }
+
+    private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
+        return Settings.System.getInt(mContext.getContentResolver(), settingKey);
+    }
+
+    private void showPreference() {
+        mController.displayPreference(mScreen);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceControllerTest.java
index bd2206f..4e1730e 100644
--- a/tests/robotests/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceControllerTest.java
@@ -16,20 +16,24 @@
 
 package com.android.settings.accessibility;
 
-import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.os.VibrationAttributes;
 import android.os.Vibrator;
+import android.provider.Settings;
 
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.PreferenceScreen;
 import androidx.test.core.app.ApplicationProvider;
 
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.widget.SeekBarPreference;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -40,30 +44,112 @@
 /** Tests for {@link RingVibrationIntensityPreferenceController}. */
 @RunWith(RobolectricTestRunner.class)
 public class RingVibrationIntensityPreferenceControllerTest {
-    @Mock
-    private Vibrator mVibrator;
 
+    private static final String PREFERENCE_KEY = "preference_key";
+    private static final int OFF = 0;
+    private static final int ON = 1;
+
+    @Mock
+    private PreferenceScreen mScreen;
+
+    private LifecycleOwner mLifecycleOwner;
+    private Lifecycle mLifecycle;
+    private Context mContext;
+    private Vibrator mVibrator;
     private RingVibrationIntensityPreferenceController mController;
+    private SeekBarPreference mPreference;
 
     @Before
-    public void setUp() throws Exception {
+    public void setUp() {
         MockitoAnnotations.initMocks(this);
-
-        final Context mContext = spy(ApplicationProvider.getApplicationContext());
-        doReturn(mVibrator).when(mContext).getSystemService(Vibrator.class);
-        mController = new RingVibrationIntensityPreferenceController(mContext);
+        mLifecycleOwner = () -> mLifecycle;
+        mLifecycle = new Lifecycle(mLifecycleOwner);
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        mVibrator = mContext.getSystemService(Vibrator.class);
+        mController = new RingVibrationIntensityPreferenceController(mContext, PREFERENCE_KEY);
+        mLifecycle.addObserver(mController);
+        mPreference = new SeekBarPreference(mContext);
+        mPreference.setSummary("Test summary");
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+        showPreference();
     }
 
     @Test
-    public void getAvailabilityStatus_available() {
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+    public void verifyConstants() {
+        assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
+        assertThat(mController.getAvailabilityStatus())
+                .isEqualTo(BasePreferenceController.AVAILABLE);
+        assertThat(mController.getMin()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+        assertThat(mController.getMax()).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
     }
 
     @Test
-    public void getDefaultIntensity_success() {
-        doReturn(/* toBeReturned= */ 5).when(mVibrator).getDefaultVibrationIntensity(
-                eq(VibrationAttributes.USAGE_RINGTONE));
+    public void missingSetting_shouldReturnDefault() {
+        Settings.System.putString(mContext.getContentResolver(),
+                Settings.System.RING_VIBRATION_INTENSITY, /* value= */ null);
+        mController.updateState(mPreference);
+        assertThat(mPreference.getProgress()).isEqualTo(
+                mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_RINGTONE));
+    }
 
-        assertThat(mController.getDefaultIntensity()).isEqualTo(/* expected= */ 5);
+    @Test
+    public void updateState_shouldDisplayIntensityInSliderPosition() {
+        updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
+        mController.updateState(mPreference);
+        assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
+
+        updateSetting(Settings.System.RING_VIBRATION_INTENSITY,
+                Vibrator.VIBRATION_INTENSITY_MEDIUM);
+        mController.updateState(mPreference);
+        assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_MEDIUM);
+
+        updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
+        mController.updateState(mPreference);
+        assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
+
+        updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
+        mController.updateState(mPreference);
+        assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+    }
+
+
+    @Test
+    public void setProgress_updatesIntensityAndDependentSettings() throws Exception {
+        mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_OFF);
+        assertThat(readSetting(Settings.System.RING_VIBRATION_INTENSITY))
+                .isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+        assertThat(readSetting(Settings.System.VIBRATE_WHEN_RINGING)).isEqualTo(OFF);
+
+        mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_LOW);
+        assertThat(readSetting(Settings.System.RING_VIBRATION_INTENSITY))
+                .isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
+        assertThat(readSetting(Settings.System.VIBRATE_WHEN_RINGING)).isEqualTo(ON);
+
+        mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_MEDIUM);
+        assertThat(readSetting(Settings.System.RING_VIBRATION_INTENSITY))
+                .isEqualTo(Vibrator.VIBRATION_INTENSITY_MEDIUM);
+        assertThat(readSetting(Settings.System.VIBRATE_WHEN_RINGING)).isEqualTo(ON);
+
+        mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_HIGH);
+        assertThat(readSetting(Settings.System.RING_VIBRATION_INTENSITY))
+                .isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
+        assertThat(readSetting(Settings.System.VIBRATE_WHEN_RINGING)).isEqualTo(ON);
+
+        mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_OFF);
+        assertThat(readSetting(Settings.System.RING_VIBRATION_INTENSITY))
+                .isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+        assertThat(readSetting(Settings.System.VIBRATE_WHEN_RINGING)).isEqualTo(OFF);
+    }
+
+    private void updateSetting(String key, int value) {
+        Settings.System.putInt(mContext.getContentResolver(), key, value);
+    }
+
+    private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
+        return Settings.System.getInt(mContext.getContentResolver(), settingKey);
+    }
+
+    private void showPreference() {
+        mController.displayPreference(mScreen);
     }
 }
diff --git a/tests/robotests/src/com/android/settings/accessibility/RingVibrationPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/RingVibrationPreferenceFragmentTest.java
deleted file mode 100644
index e2b1051..0000000
--- a/tests/robotests/src/com/android/settings/accessibility/RingVibrationPreferenceFragmentTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.accessibility;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-
-import android.content.Context;
-import android.provider.Settings;
-
-import com.android.settings.testutils.shadow.ShadowDeviceConfig;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-@RunWith(RobolectricTestRunner.class)
-public class RingVibrationPreferenceFragmentTest {
-
-    private Context mContext;
-    private RingVibrationPreferenceFragment mFragment;
-
-    @Before
-    public void setUp() {
-        mContext = RuntimeEnvironment.application;
-        mFragment = spy(new RingVibrationPreferenceFragment());
-        doReturn(mContext).when(mFragment).getContext();
-    }
-
-    @Test
-    @Config(shadows = {ShadowDeviceConfig.class})
-    public void getVibrationEnabledSetting_rampingRingerEnabled_returnApplyRampingRinger() {
-        // Turn on both flags to enable ramping ringer.
-        Settings.System.putInt(
-                mContext.getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, 1 /* ON */);
-        assertThat(mFragment.getVibrationEnabledSetting()).isEqualTo(
-                Settings.System.APPLY_RAMPING_RINGER);
-    }
-
-    @Test
-    public void getVibrationEnabledSetting_rampingRingerDisabled_returnVibrationWhenRinging() {
-        // Turn off Settings.System.APPLY_RAMPING_RINGER to disable ramping ringer.
-        Settings.System.putInt(
-                mContext.getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, 0 /* OFF */);
-        assertThat(mFragment.getVibrationEnabledSetting()).isEqualTo(
-            Settings.System.VIBRATE_WHEN_RINGING);
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/accessibility/RingVibrationTogglePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/RingVibrationTogglePreferenceControllerTest.java
new file mode 100644
index 0000000..2d1c69c
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/RingVibrationTogglePreferenceControllerTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.VibrationAttributes;
+import android.os.Vibrator;
+import android.provider.Settings;
+
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class RingVibrationTogglePreferenceControllerTest {
+
+    private static final String PREFERENCE_KEY = "preference_key";
+    private static final int OFF = 0;
+    private static final int ON = 1;
+
+    @Mock
+    private PreferenceScreen mScreen;
+
+    private LifecycleOwner mLifecycleOwner;
+    private Lifecycle mLifecycle;
+    private Context mContext;
+    private Vibrator mVibrator;
+    private RingVibrationTogglePreferenceController mController;
+    private SwitchPreference mPreference;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mLifecycleOwner = () -> mLifecycle;
+        mLifecycle = new Lifecycle(mLifecycleOwner);
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        mVibrator = mContext.getSystemService(Vibrator.class);
+        mController = new RingVibrationTogglePreferenceController(mContext, PREFERENCE_KEY);
+        mLifecycle.addObserver(mController);
+        mPreference = new SwitchPreference(mContext);
+        mPreference.setSummary("Test summary");
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+        showPreference();
+    }
+
+    @Test
+    public void verifyConstants() {
+        assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
+        assertThat(mController.getAvailabilityStatus())
+                .isEqualTo(BasePreferenceController.AVAILABLE);
+    }
+
+    @Test
+    public void missingSetting_shouldReturnDefault() {
+        Settings.System.putString(mContext.getContentResolver(),
+                Settings.System.RING_VIBRATION_INTENSITY, /* value= */ null);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isChecked()).isTrue();
+    }
+
+    @Test
+    public void updateState_shouldDisplayOnOffState() {
+        updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isChecked()).isTrue();
+
+        updateSetting(Settings.System.RING_VIBRATION_INTENSITY,
+                Vibrator.VIBRATION_INTENSITY_MEDIUM);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isChecked()).isTrue();
+
+        updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isChecked()).isTrue();
+
+        updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isChecked()).isFalse();
+    }
+
+    @Test
+    public void setChecked_updatesIntensityAndDependentSettings() throws Exception {
+        updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
+        mController.updateState(mPreference);
+        assertThat(mPreference.isChecked()).isFalse();
+
+        mPreference.setChecked(true);
+        assertThat(readSetting(Settings.System.RING_VIBRATION_INTENSITY)).isEqualTo(
+                mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_RINGTONE));
+        assertThat(readSetting(Settings.System.VIBRATE_WHEN_RINGING)).isEqualTo(ON);
+
+        mPreference.setChecked(false);
+        assertThat(readSetting(Settings.System.RING_VIBRATION_INTENSITY))
+                .isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+        assertThat(readSetting(Settings.System.VIBRATE_WHEN_RINGING)).isEqualTo(OFF);
+    }
+
+    private void updateSetting(String key, int value) {
+        Settings.System.putInt(mContext.getContentResolver(), key, value);
+    }
+
+    private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
+        return Settings.System.getInt(mContext.getContentResolver(), settingKey);
+    }
+
+    private void showPreference() {
+        mController.displayPreference(mScreen);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceControllerTest.java
deleted file mode 100644
index e4d0f45..0000000
--- a/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceControllerTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.accessibility;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.Context;
-import android.os.Vibrator;
-import android.provider.Settings;
-
-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.RuntimeEnvironment;
-
-@RunWith(RobolectricTestRunner.class)
-public class VibrationPreferenceControllerTest {
-
-    private static final String VIBRATION_ON = "On";
-    private static final String VIBRATION_OFF = "Off";
-
-    private Context mContext;
-    private VibrationPreferenceController mController;
-
-    @Before
-    public void setUp() {
-        mContext = RuntimeEnvironment.application;
-        mController = new VibrationPreferenceController(mContext, "vibration_pref");
-    }
-
-    @Test
-    public void getAvailabilityStatus_byDefault_shouldReturnAvailable() {
-        assertThat(mController.getAvailabilityStatus())
-                .isEqualTo(BasePreferenceController.AVAILABLE);
-    }
-
-    @Test
-    public void getSummary_disabledVibration_shouldReturnOffSummary() {
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
-        final String expectedResult = mContext.getString(R.string.switch_off_text);
-
-        assertThat(mController.getSummary()).isEqualTo(expectedResult);
-    }
-
-    @Test
-    public void getSummary_enabledSomeVibration_shouldReturnVibrationOnSummary() {
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_MEDIUM);
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.VIBRATE_WHEN_RINGING, 1);
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_MEDIUM);
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.HAPTIC_FEEDBACK_ENABLED, 1);
-        final String expectedResult = mContext.getString(R.string.accessibility_vibration_summary,
-                VIBRATION_ON /* ring */,
-                VIBRATION_OFF /* notification */,
-                VIBRATION_ON /* touch */);
-
-        assertThat(mController.getSummary()).isEqualTo(expectedResult);
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceFragmentTest.java
deleted file mode 100644
index 9f83f72..0000000
--- a/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceFragmentTest.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.accessibility;
-
-import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_HIGH;
-import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_LOW;
-import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_MEDIUM;
-import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_OFF;
-import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_ON;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.os.UserManager;
-import android.os.Vibrator;
-import android.provider.Settings;
-
-import com.android.settings.R;
-import com.android.settings.accessibility.VibrationPreferenceFragment
-        .VibrationIntensityCandidateInfo;
-import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settingslib.widget.CandidateInfo;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-@RunWith(RobolectricTestRunner.class)
-public class VibrationPreferenceFragmentTest {
-
-    private static final Map<Integer, String> INTENSITY_TO_KEY = new HashMap<>(4);
-    static {
-        INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_OFF, KEY_INTENSITY_OFF);
-        INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_LOW, KEY_INTENSITY_LOW);
-        INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_MEDIUM, KEY_INTENSITY_MEDIUM);
-        INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_HIGH, KEY_INTENSITY_HIGH);
-    }
-
-    @Mock
-    private UserManager mUserManager;
-
-    private Context mContext;
-    private Resources mResources;
-    private TestVibrationPreferenceFragment mFragment;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        FakeFeatureFactory.setupForTest();
-
-        mContext = spy(RuntimeEnvironment.application);
-        mResources = spy(mContext.getResources());
-        when(mContext.getResources()).thenReturn(mResources);
-
-        mFragment = spy(new TestVibrationPreferenceFragment());
-        when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
-    }
-
-    @Test
-    public void changeIntensitySetting_shouldResultInCorrespondingKey() {
-        setSupportsMultipleIntensities(true);
-        mFragment.onAttach(mContext);
-        for (Map.Entry<Integer, String> entry : INTENSITY_TO_KEY.entrySet()) {
-            Settings.System.putInt(mContext.getContentResolver(),
-                    Settings.System.HAPTIC_FEEDBACK_INTENSITY, entry.getKey());
-            assertThat(mFragment.getDefaultKey()).isEqualTo(entry.getValue());
-        }
-    }
-
-    @Test
-    public void changeIntensitySetting_WithoutMultipleIntensitySupport_shouldResultInOn() {
-        setSupportsMultipleIntensities(false);
-        mFragment.onAttach(mContext);
-        for (int intensity : INTENSITY_TO_KEY.keySet()) {
-            Settings.System.putInt(mContext.getContentResolver(),
-                    Settings.System.HAPTIC_FEEDBACK_INTENSITY, intensity);
-            final String expectedKey = intensity == Vibrator.VIBRATION_INTENSITY_OFF
-                    ? KEY_INTENSITY_OFF
-                    : KEY_INTENSITY_ON;
-            assertThat(mFragment.getDefaultKey()).isEqualTo(expectedKey);
-        }
-    }
-
-    @Test
-    public void initialDefaultKey_shouldBeMedium() {
-        setSupportsMultipleIntensities(true);
-        mFragment.onAttach(mContext);
-        assertThat(mFragment.getDefaultKey()).isEqualTo(KEY_INTENSITY_MEDIUM);
-    }
-
-    @Test
-    public void initialDefaultKey_WithoutMultipleIntensitySupport_shouldBeOn() {
-        setSupportsMultipleIntensities(false);
-        mFragment.onAttach(mContext);
-        assertThat(mFragment.getDefaultKey()).isEqualTo(KEY_INTENSITY_ON);
-    }
-
-    @Test
-    public void candidates_shouldBeSortedByIntensity() {
-        setSupportsMultipleIntensities(true);
-        mFragment.onAttach(mContext);
-        final List<? extends CandidateInfo> candidates = mFragment.getCandidates();
-        assertThat(candidates.size()).isEqualTo(INTENSITY_TO_KEY.size());
-        VibrationIntensityCandidateInfo prevCandidate =
-                (VibrationIntensityCandidateInfo) candidates.get(0);
-        for (int i = 1; i < candidates.size(); i++) {
-            VibrationIntensityCandidateInfo candidate =
-                    (VibrationIntensityCandidateInfo) candidates.get(i);
-            assertThat(candidate.getIntensity()).isLessThan(prevCandidate.getIntensity());
-        }
-    }
-
-    private void setSupportsMultipleIntensities(boolean hasSupport) {
-        when(mResources.getBoolean(R.bool.config_vibration_supports_multiple_intensities))
-            .thenReturn(hasSupport);
-    }
-
-    private class TestVibrationPreferenceFragment extends VibrationPreferenceFragment {
-        @Override
-        protected int getPreferenceScreenResId() {
-            return 0;
-        }
-
-        @Override
-        public int getMetricsCategory() {
-            return 0;
-        }
-
-        /**
-        * Get the setting string of the vibration intensity setting this preference is dealing with.
-        */
-        @Override
-        protected String getVibrationIntensitySetting() {
-            return Settings.System.HAPTIC_FEEDBACK_INTENSITY;
-        }
-
-        @Override
-        protected String getVibrationEnabledSetting() {
-            return "";
-        }
-
-        @Override
-        protected int getDefaultVibrationIntensity() {
-            return Vibrator.VIBRATION_INTENSITY_MEDIUM;
-        }
-
-        @Override
-        public Context getContext() {
-            return mContext;
-        }
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceControllerTest.java
new file mode 100644
index 0000000..08831c8
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceControllerTest.java
@@ -0,0 +1,169 @@
+/*
+ * 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.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.media.AudioManager;
+import android.os.Vibrator;
+import android.provider.DeviceConfig;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class VibrationRampingRingerTogglePreferenceControllerTest {
+
+    private static final String PREFERENCE_KEY = "preference_key";
+
+    @Mock
+    private PreferenceScreen mScreen;
+    @Mock
+    private TelephonyManager mTelephonyManager;
+    @Mock
+    private AudioManager mAudioManager;
+
+    private LifecycleOwner mLifecycleOwner;
+    private Lifecycle mLifecycle;
+    private Context mContext;
+    private VibrationRampingRingerTogglePreferenceController mController;
+    private SwitchPreference mPreference;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mLifecycleOwner = () -> mLifecycle;
+        mLifecycle = new Lifecycle(mLifecycleOwner);
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
+        when(mContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager);
+        mController = new VibrationRampingRingerTogglePreferenceController(mContext,
+                PREFERENCE_KEY);
+        mLifecycle.addObserver(mController);
+        mPreference = new SwitchPreference(mContext);
+        mPreference.setSummary("Test summary");
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+        showPreference();
+    }
+
+    @Test
+    public void verifyConstants() {
+        assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
+    }
+
+    @Test
+    public void getAvailabilityStatus_notVoiceCapable_returnUnsupportedOnDevice() {
+        when(mTelephonyManager.isVoiceCapable()).thenReturn(false);
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY,
+                VibrationRampingRingerTogglePreferenceController.DEVICE_CONFIG_KEY, "false", false);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_rampingRingerEnabled_returnUnsupportedOnDevice() {
+        when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY,
+                VibrationRampingRingerTogglePreferenceController.DEVICE_CONFIG_KEY, "true", false);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_voiceCapableAndRampingRingerDisabled_returnAvailable() {
+        when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY,
+                VibrationRampingRingerTogglePreferenceController.DEVICE_CONFIG_KEY, "false", false);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+    }
+
+    @Test
+    public void updateState_withRingDisabled_shouldReturnFalseForCheckedAndEnabled() {
+        updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
+        when(mAudioManager.isRampingRingerEnabled()).thenReturn(true);
+        mController.updateState(mPreference);
+
+        assertThat(mPreference.isEnabled()).isFalse();
+        assertThat(mPreference.isChecked()).isFalse();
+    }
+
+    @Test
+    public void updateState_withRingEnabled_shouldReturnTheSettingStateAndAlwaysEnabled() {
+        updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
+        when(mAudioManager.isRampingRingerEnabled()).thenReturn(true, false);
+
+        mController.updateState(mPreference);
+        assertThat(mPreference.isEnabled()).isTrue();
+        assertThat(mPreference.isChecked()).isTrue();
+
+        mController.updateState(mPreference);
+        assertThat(mPreference.isEnabled()).isTrue();
+        assertThat(mPreference.isChecked()).isFalse();
+    }
+
+    @Test
+    public void setChecked_withRingDisabled_ignoresUpdates() {
+        updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
+
+        mPreference.setChecked(true);
+        mPreference.setChecked(false);
+        verify(mAudioManager, never()).setRampingRingerEnabled(anyBoolean());
+    }
+
+    @Test
+    public void setChecked_withRingEnabled_updatesSetting() {
+        updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
+
+        mPreference.setChecked(true);
+        verify(mAudioManager).setRampingRingerEnabled(true);
+
+        mPreference.setChecked(false);
+        verify(mAudioManager).setRampingRingerEnabled(false);
+    }
+
+    private void updateSetting(String key, int value) {
+        Settings.System.putInt(mContext.getContentResolver(), key, value);
+    }
+
+    private void showPreference() {
+        mController.displayPreference(mScreen);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/sound/VibrateForCallsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/sound/VibrateForCallsPreferenceControllerTest.java
deleted file mode 100644
index 1f4ba96..0000000
--- a/tests/robotests/src/com/android/settings/sound/VibrateForCallsPreferenceControllerTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.sound;
-
-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 static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.provider.DeviceConfig;
-import android.provider.Settings;
-import android.telephony.TelephonyManager;
-
-import com.android.settings.R;
-import com.android.settings.testutils.shadow.ShadowDeviceConfig;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowDeviceConfig.class})
-public class VibrateForCallsPreferenceControllerTest {
-
-    private static final int OFF = 0;
-    private static final int ON = 1;
-    private Context mContext;
-    private ContentResolver mContentResolver;
-    @Mock
-    private TelephonyManager mTelephonyManager;
-    private VibrateForCallsPreferenceController mController;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContext = spy(RuntimeEnvironment.application);
-        mContentResolver = mContext.getContentResolver();
-        when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
-        mController = new VibrateForCallsPreferenceController(
-            mContext, VibrateForCallsPreferenceController.RAMPING_RINGER_ENABLED);
-    }
-
-    @Test
-    public void getAvailabilityStatus_notVoiceCapable_returnUnsupportedOnDevice() {
-        when(mTelephonyManager.isVoiceCapable()).thenReturn(false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY,
-                VibrateForCallsPreferenceController.RAMPING_RINGER_ENABLED, "false", false);
-
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
-    }
-
-    @Test
-    public void getAvailabilityStatus_rampingRingerEnabled_returnUnsupportedOnDevice() {
-        when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY,
-                VibrateForCallsPreferenceController.RAMPING_RINGER_ENABLED, "true", false);
-
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
-    }
-
-    @Test
-    public void getAvailabilityStatus_voiceCapableAndRampingRingerDisabled_returnAvailable() {
-        when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY,
-                VibrateForCallsPreferenceController.RAMPING_RINGER_ENABLED, "false", false);
-
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
-    }
-
-    @Test
-    public void getSummary_applyRampingRinger_rampingRingerSummary() {
-        Settings.System.putInt(mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, OFF);
-        Settings.System.putInt(mContentResolver, Settings.System.APPLY_RAMPING_RINGER, ON);
-
-        assertThat(mController.getSummary()).isEqualTo(
-                mContext.getText(R.string.vibrate_when_ringing_option_ramping_ringer));
-    }
-
-    @Test
-    public void getSummary_enableVibrateWhenRinging_alwaysVibrateSummary() {
-        Settings.System.putInt(mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, ON);
-        Settings.System.putInt(mContentResolver, Settings.System.APPLY_RAMPING_RINGER, OFF);
-
-        assertThat(mController.getSummary()).isEqualTo(
-                mContext.getText(R.string.vibrate_when_ringing_option_always_vibrate));
-    }
-
-    @Test
-    public void getSummary_notApplyRampingRingerDisableVibrateWhenRinging_neverVibrateSummary() {
-        Settings.System.putInt(mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, OFF);
-        Settings.System.putInt(mContentResolver, Settings.System.APPLY_RAMPING_RINGER, OFF);
-
-        assertThat(mController.getSummary()).isEqualTo(
-                mContext.getText(R.string.vibrate_when_ringing_option_never_vibrate));
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/sound/VibrateForCallsPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/sound/VibrateForCallsPreferenceFragmentTest.java
deleted file mode 100644
index 889e5a6..0000000
--- a/tests/robotests/src/com/android/settings/sound/VibrateForCallsPreferenceFragmentTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.sound;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.provider.Settings;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(RobolectricTestRunner.class)
-public class VibrateForCallsPreferenceFragmentTest {
-
-    private static final int OFF = 0;
-    private static final int ON = 1;
-    private Context mContext;
-    private ContentResolver mContentResolver;
-    private VibrateForCallsPreferenceFragment mFragment;
-
-    @Before
-    public void setUp() {
-        mContext = spy(RuntimeEnvironment.application);
-        mContentResolver = mContext.getContentResolver();
-        mFragment = spy(new VibrateForCallsPreferenceFragment());
-        doReturn(mContext).when(mFragment).getContext();
-        mFragment.onAttach(mContext);
-    }
-
-    @Test
-    public void getDefaultKey_applyRampingRinger_keyRampingRinger() {
-        Settings.System.putInt(mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, OFF);
-        Settings.System.putInt(mContentResolver, Settings.System.APPLY_RAMPING_RINGER, ON);
-
-        assertThat(mFragment.getDefaultKey()).isEqualTo(
-                VibrateForCallsPreferenceFragment.KEY_RAMPING_RINGER);
-    }
-
-    @Test
-    public void getDefaultKey_enableVibrateWhenRinging_keyAlwaysVibrate() {
-        Settings.System.putInt(mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, ON);
-        Settings.System.putInt(mContentResolver, Settings.System.APPLY_RAMPING_RINGER, OFF);
-
-        assertThat(mFragment.getDefaultKey()).isEqualTo(
-                VibrateForCallsPreferenceFragment.KEY_ALWAYS_VIBRATE);
-    }
-
-    @Test
-    public void getDefaultKey_notApplyRampingRingerDisableVibrateWhenRinging_keyNeverVibrate() {
-        Settings.System.putInt(mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, OFF);
-        Settings.System.putInt(mContentResolver, Settings.System.APPLY_RAMPING_RINGER, OFF);
-
-        assertThat(mFragment.getDefaultKey()).isEqualTo(
-                VibrateForCallsPreferenceFragment.KEY_NEVER_VIBRATE);
-    }
-
-    @Test
-    public void setDefaultKey_keyRampingRinger_applyRampingRingerDisableVibrateWhenRinging() {
-        mFragment.setDefaultKey(VibrateForCallsPreferenceFragment.KEY_RAMPING_RINGER);
-
-        assertThat(Settings.System.getInt(
-            mContentResolver, Settings.System.APPLY_RAMPING_RINGER, OFF)).isEqualTo(ON);
-        assertThat(Settings.System.getInt(
-            mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, OFF)).isEqualTo(OFF);
-    }
-
-    @Test
-    public void setDefaultKey_keyAlwaysVibrate_notApplyRampingRingerEnableVibrateWhenRinging() {
-        mFragment.setDefaultKey(VibrateForCallsPreferenceFragment.KEY_ALWAYS_VIBRATE);
-
-        assertThat(Settings.System.getInt(
-            mContentResolver, Settings.System.APPLY_RAMPING_RINGER, OFF)).isEqualTo(OFF);
-        assertThat(Settings.System.getInt(
-            mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, OFF)).isEqualTo(ON);
-    }
-
-    @Test
-    public void setDefaultKey_keyNeverVibrate_notApplyRampingRingerDisableVibrateWhenRinging() {
-        mFragment.setDefaultKey(VibrateForCallsPreferenceFragment.KEY_NEVER_VIBRATE);
-
-        assertThat(Settings.System.getInt(
-            mContentResolver, Settings.System.APPLY_RAMPING_RINGER, OFF)).isEqualTo(OFF);
-        assertThat(Settings.System.getInt(
-            mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, OFF)).isEqualTo(OFF);
-    }
-}
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 1d4f201..dc42515 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
@@ -49,6 +49,7 @@
     private final Map<String, List<EnforcingUser>> mRestrictionSources = new HashMap<>();
     private final List<UserInfo> mUserProfileInfos = new ArrayList<>();
     private final Set<Integer> mManagedProfiles = new HashSet<>();
+    private final Set<String> mEnabledTypes = new HashSet<>();
     private boolean mIsQuietModeEnabled = false;
     private int[] profileIdsForUser = new int[0];
     private boolean mUserSwitchEnabled;
@@ -105,6 +106,11 @@
         mGuestRestrictions.add(restriction);
     }
 
+    @Implementation
+    protected boolean hasUserRestriction(String restrictionKey) {
+        return hasUserRestriction(restrictionKey, UserHandle.of(UserHandle.myUserId()));
+    }
+
     public static ShadowUserManager getShadow() {
         return (ShadowUserManager) Shadow.extract(
                 RuntimeEnvironment.application.getSystemService(UserManager.class));
@@ -199,4 +205,17 @@
     public void setSwitchabilityStatus(@UserManager.UserSwitchabilityResult int newStatus) {
         mSwitchabilityStatus = newStatus;
     }
+
+    @Implementation
+    protected boolean isUserTypeEnabled(String userType) {
+        return mEnabledTypes.contains(userType);
+    }
+
+    public void setUserTypeEnabled(String type, boolean enabled) {
+        if (enabled) {
+            mEnabledTypes.add(type);
+        } else {
+            mEnabledTypes.remove(type);
+        }
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/users/UserCapabilitiesTest.java b/tests/robotests/src/com/android/settings/users/UserCapabilitiesTest.java
index 382ac5d..628c14e 100644
--- a/tests/robotests/src/com/android/settings/users/UserCapabilitiesTest.java
+++ b/tests/robotests/src/com/android/settings/users/UserCapabilitiesTest.java
@@ -18,12 +18,17 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import android.content.ComponentName;
 import android.content.Context;
 import android.os.UserHandle;
 import android.os.UserManager;
 
+import com.android.settings.R;
+import com.android.settings.testutils.shadow.SettingsShadowResources;
+import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
 import com.android.settings.testutils.shadow.ShadowUserManager;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -32,16 +37,24 @@
 import org.robolectric.annotation.Config;
 
 @RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowUserManager.class})
+@Config(shadows = {ShadowUserManager.class, ShadowDevicePolicyManager.class,
+        SettingsShadowResources.class})
 public class UserCapabilitiesTest {
 
     private Context mContext;
     private ShadowUserManager mUserManager;
+    private ShadowDevicePolicyManager mDpm;
 
     @Before
     public void setUp() {
         mContext = RuntimeEnvironment.application;
         mUserManager = ShadowUserManager.getShadow();
+        mDpm = ShadowDevicePolicyManager.getShadow();
+    }
+
+    @After
+    public void tearDown() {
+        SettingsShadowResources.reset();
     }
 
     @Test
@@ -85,4 +98,40 @@
 
         assertThat(userCapabilities.mUserSwitcherEnabled).isTrue();
     }
+
+    @Test
+    public void restrictedProfile_enabled() {
+        mUserManager.setUserTypeEnabled(UserManager.USER_TYPE_FULL_RESTRICTED, true);
+        mDpm.setDeviceOwner(null);
+        SettingsShadowResources.overrideResource(R.bool.config_offer_restricted_profiles, true);
+        final UserCapabilities userCapabilities = UserCapabilities.create(mContext);
+        assertThat(userCapabilities.mCanAddRestrictedProfile).isTrue();
+    }
+
+    @Test
+    public void restrictedProfile_configNotSet() {
+        mUserManager.setUserTypeEnabled(UserManager.USER_TYPE_FULL_RESTRICTED, true);
+        mDpm.setDeviceOwner(null);
+        SettingsShadowResources.overrideResource(R.bool.config_offer_restricted_profiles, false);
+        final UserCapabilities userCapabilities = UserCapabilities.create(mContext);
+        assertThat(userCapabilities.mCanAddRestrictedProfile).isFalse();
+    }
+
+    @Test
+    public void restrictedProfile_deviceIsManaged() {
+        mUserManager.setUserTypeEnabled(UserManager.USER_TYPE_FULL_RESTRICTED, true);
+        mDpm.setDeviceOwner(new ComponentName("test", "test"));
+        SettingsShadowResources.overrideResource(R.bool.config_offer_restricted_profiles, true);
+        final UserCapabilities userCapabilities = UserCapabilities.create(mContext);
+        assertThat(userCapabilities.mCanAddRestrictedProfile).isFalse();
+    }
+
+    @Test
+    public void restrictedProfile_typeNotEnabled() {
+        mUserManager.setUserTypeEnabled(UserManager.USER_TYPE_FULL_RESTRICTED, false);
+        mDpm.setDeviceOwner(null);
+        SettingsShadowResources.overrideResource(R.bool.config_offer_restricted_profiles, true);
+        final UserCapabilities userCapabilities = UserCapabilities.create(mContext);
+        assertThat(userCapabilities.mCanAddRestrictedProfile).isFalse();
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/wifi/AddWifiNetworkPreferenceTest.java b/tests/robotests/src/com/android/settings/wifi/AddWifiNetworkPreferenceTest.java
new file mode 100644
index 0000000..04ecdab
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/wifi/AddWifiNetworkPreferenceTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.wifi;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.UserManager;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class AddWifiNetworkPreferenceTest {
+
+    private Context mContext;
+    private AddWifiNetworkPreference mPreference;
+
+    @Mock
+    private UserManager mUserManager;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
+        mPreference = new AddWifiNetworkPreference(mContext);
+
+    }
+
+    @Test
+    public void updatePreferenceForRestriction_isAddWifiConfigAllowed_prefIsEnabled() {
+        mPreference.mIsAddWifiConfigAllow = true;
+
+        mPreference.updatePreferenceForRestriction();
+
+        assertThat(mPreference.isEnabled()).isTrue();
+        assertThat(mPreference.getSummary()).isNull();
+    }
+
+    @Test
+    public void updatePreferenceForRestriction_isAddWifiConfigNotAllowed_prefIsDisabled() {
+        mPreference.mIsAddWifiConfigAllow = false;
+
+        mPreference.updatePreferenceForRestriction();
+
+        assertThat(mPreference.isEnabled()).isFalse();
+        assertThat(mPreference.getSummary())
+                .isEqualTo(mContext.getString(R.string.not_allowed_by_ent));
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivityTest.java b/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivityTest.java
index 39408e2..6cd20fc 100644
--- a/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivityTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivityTest.java
@@ -47,6 +47,7 @@
 
         mActivity = Robolectric.buildActivity(AddAppNetworksActivity.class).create().get();
         mActivity.mActivityManager = mIActivityManager;
+        mActivity.mIsAddWifiConfigAllow = true;
     }
 
     @Test
@@ -77,6 +78,13 @@
         assertThat(mActivity.showAddNetworksFragment()).isTrue();
     }
 
+    @Test
+    public void showAddNetworksFragment_isAddWifiConfigNotAllow_returnFalse() {
+        mActivity.mIsAddWifiConfigAllow = false;
+
+        assertThat(mActivity.showAddNetworksFragment()).isFalse();
+    }
+
     private void fakeCallingPackage(@Nullable String packageName) {
         try {
             when(mIActivityManager.getLaunchedFromPackage(any())).thenReturn(packageName);