Merge "Hide the setting from the search when feature is disabled." into main
diff --git a/Android.bp b/Android.bp
index 5a1224c..97b235d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -76,6 +76,8 @@
         "android.hardware.dumpstate-V1.0-java",
         "android.hardware.dumpstate-V1.1-java",
         "android.nfc.flags-aconfig-java",
+        "android.view.accessibility.flags-aconfig-java",
+        "com_android_server_accessibility_flags_lib",
         "net-utils-framework-common",
         "notification_flags_lib",
         "securebox",
@@ -99,7 +101,6 @@
         "settings-logtags",
         "settings-telephony-protos-lite",
         "statslog-settings",
-        "com_android_server_accessibility_flags_lib",
     ],
 
     plugins: ["androidx.room_room-compiler-plugin"],
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index a08bda3..75c6fbb 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -4943,6 +4943,16 @@
         </activity>
 
         <activity
+            android:name="com.android.settings.connecteddevice.audiosharing.audiostreams.qrcode.QrCodeScanModeActivity"
+            android:permission="android.permission.BLUETOOTH_CONNECT"
+            android:exported="false">
+            <intent-filter>
+                <action android:name="android.settings.BLUETOOTH_LE_AUDIO_QR_CODE_SCANNER"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+            </intent-filter>
+        </activity>
+
+        <activity
             android:name=".spa.SpaActivity"
             android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize"
             android:knownActivityEmbeddingCerts="@array/config_known_host_certs"
diff --git a/color-check-baseline.xml b/color-check-baseline.xml
index 7a5e80d..5a0e98e 100644
--- a/color-check-baseline.xml
+++ b/color-check-baseline.xml
@@ -2,18 +2,6 @@
 <issues format="4">
 
     <issue
-        id="LintError"
-        severity="Error"
-        message="No `.class` files were found in project &quot;.&quot;, so none of the classfile based checks could be run. Does the project need to be built first?"
-        category="Lint"
-        priority="10"
-        summary="Lint Failure"
-        explanation="This issue type represents a problem running lint itself. Examples include failure to find bytecode for source files (which means certain detectors could not be run), parsing errors in lint configuration files, etc.&#xA;These errors are not errors in your own code, but they are shown to make it clear that some checks were not completed.">
-        <location
-            file="."/>
-    </issue>
-
-    <issue
         id="HardCodedColor"
         severity="Error"
         message="Avoid using hardcoded color"
@@ -661,12 +649,12 @@
         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/notification_importance_button_unselected&quot;/>"
-        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine1="            android:textColor=&quot;@color/power_anomaly_primary_button_text_color&quot;"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="res/drawable/button_border_unselected.xml"
-            line="21"
-            column="9"/>
+            file="res/layout/battery_tips_card.xml"
+            line="57"
+            column="13"/>
     </issue>
 
     <issue
@@ -677,12 +665,12 @@
         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/notification_importance_button_unselected&quot;/>"
-        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine1="            android:textColor=&quot;@color/power_anomaly_primary_button_text_color&quot;"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="res/drawable/button_border_unselected.xml"
-            line="21"
-            column="9"/>
+            file="res/layout/battery_tips_card.xml"
+            line="57"
+            column="13"/>
     </issue>
 
     <issue
@@ -693,8 +681,8 @@
         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;color name=&quot;switchbar_switch_track_tint&quot;>#82000000&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine1="    &lt;color name=&quot;homepage_accessibility_background&quot;>#783BE5&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values-night/colors.xml"
             line="19"
@@ -709,6 +697,22 @@
         priority="4"
         summary="Using hardcoded color"
         explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+        errorLine1="    &lt;color name=&quot;homepage_support_background&quot;>#3F5FBD&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values-night/colors.xml"
+            line="20"
+            column="5"/>
+    </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;color name=&quot;setup_wizard_wifi_color_dark&quot;>#89ffffff&lt;/color>"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -725,22 +729,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="    &lt;color name=&quot;homepage_accessibility_background&quot;>#783BE5&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values-night/colors.xml"
-            line="21"
-            column="5"/>
-    </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;color name=&quot;setup_wizard_wifi_color_light&quot;>#89000000&lt;/color>"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -757,11 +745,11 @@
         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;color name=&quot;homepage_support_background&quot;>#3F5FBD&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine1="    &lt;color name=&quot;notification_importance_button_unselected&quot;>#5F6368&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values-night/colors.xml"
-            line="22"
+            line="23"
             column="5"/>
     </issue>
 
@@ -805,22 +793,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="    &lt;color name=&quot;notification_importance_button_unselected&quot;>#5F6368&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values-night/colors.xml"
-            line="25"
-            column="5"/>
-    </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;color name=&quot;icon_accent&quot;>#ffabffec&lt;/color>"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -917,6 +889,22 @@
         priority="4"
         summary="Using hardcoded color"
         explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+        errorLine1="    &lt;color name=&quot;settings_dialog_colorError&quot;>#f28b82&lt;/color> &lt;!-- Red 300 -->"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values-night/colors.xml"
+            line="38"
+            column="5"/>
+    </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;color name=&quot;timestamp_text_outgoing&quot;>#99323232&lt;/color>"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -949,10 +937,10 @@
         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;color name=&quot;settings_dialog_colorError&quot;>#f28b82&lt;/color> &lt;!-- Red 300 -->"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine1="    &lt;color name=&quot;message_bubble_incoming&quot;>#52534D&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="res/values-night/colors.xml"
+            file="res/values/colors.xml"
             line="40"
             column="5"/>
     </issue>
@@ -965,11 +953,11 @@
         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;color name=&quot;message_bubble_incoming&quot;>#52534D&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine1="    &lt;color name=&quot;biometric_enroll_intro_color_bar&quot;>#5bb974&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="res/values/colors.xml"
-            line="40"
+            file="res/values-night/colors.xml"
+            line="41"
             column="5"/>
     </issue>
 
@@ -997,6 +985,22 @@
         priority="4"
         summary="Using hardcoded color"
         explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+        errorLine1="    &lt;color name=&quot;biometric_enroll_intro_color_icon&quot;>#669df6&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values-night/colors.xml"
+            line="42"
+            column="5"/>
+    </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;color name=&quot;message_icon_background_incoming&quot;>#E6F451&lt;/color>"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -1013,8 +1017,8 @@
         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;color name=&quot;biometric_enroll_intro_color_bar&quot;>#5bb974&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine1="    &lt;color name=&quot;biometric_enroll_intro_color_outline&quot;>#5e5e5e&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values-night/colors.xml"
             line="43"
@@ -1045,8 +1049,8 @@
         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;color name=&quot;biometric_enroll_intro_color_icon&quot;>#669df6&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine1="    &lt;color name=&quot;fingerprint_enrollment_finish_color_outline&quot;>#669df6&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values-night/colors.xml"
             line="44"
@@ -1077,38 +1081,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="    &lt;color name=&quot;biometric_enroll_intro_color_outline&quot;>#5e5e5e&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values-night/colors.xml"
-            line="45"
-            column="5"/>
-    </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;color name=&quot;fingerprint_enrollment_finish_color_outline&quot;>#669df6&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values-night/colors.xml"
-            line="46"
-            column="5"/>
-    </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;color name=&quot;usage_graph_dots&quot;>#B0BEC5&lt;/color>"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -1129,6 +1101,38 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values-night/colors.xml"
+            line="47"
+            column="5"/>
+    </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;color name=&quot;sfps_enrollment_fp_error_color&quot;>#fad2cf&lt;/color> &lt;!-- Red 100 -->"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values-night/colors.xml"
+            line="48"
+            column="5"/>
+    </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;color name=&quot;sfps_enrollment_progress_bar_bg_color&quot;>#3C4043&lt;/color> &lt;!-- Gray 800 -->"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values-night/colors.xml"
             line="49"
             column="5"/>
     </issue>
@@ -1157,8 +1161,8 @@
         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;color name=&quot;sfps_enrollment_fp_error_color&quot;>#fad2cf&lt;/color> &lt;!-- Red 100 -->"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine1="    &lt;color name=&quot;sfps_enrollment_progress_bar_fill_color&quot;>#669df6&lt;/color> &lt;!-- Blue 400 -->"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values-night/colors.xml"
             line="50"
@@ -1173,8 +1177,8 @@
         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;color name=&quot;sfps_enrollment_progress_bar_bg_color&quot;>#3C4043&lt;/color> &lt;!-- Gray 800 -->"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine1="    &lt;color name=&quot;sfps_enrollment_progress_bar_error_color&quot;>#ee675c&lt;/color> &lt;!-- Red 400 -->"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values-night/colors.xml"
             line="51"
@@ -1189,22 +1193,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="    &lt;color name=&quot;sfps_enrollment_progress_bar_fill_color&quot;>#669df6&lt;/color> &lt;!-- Blue 400 -->"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values-night/colors.xml"
-            line="52"
-            column="5"/>
-    </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;color name=&quot;shortcut_background&quot;>#fff5f5f5&lt;/color>"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -1221,22 +1209,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="    &lt;color name=&quot;sfps_enrollment_progress_bar_error_color&quot;>#ee675c&lt;/color> &lt;!-- Red 400 -->"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values-night/colors.xml"
-            line="53"
-            column="5"/>
-    </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;color name=&quot;homepage_network_background&quot;>#2196F3&lt;/color>"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -1317,6 +1289,22 @@
         priority="4"
         summary="Using hardcoded color"
         explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+        errorLine1="    &lt;color name=&quot;power_anomaly_app_warning_hint_color&quot;>#FDD663&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values-night/colors.xml"
+            line="60"
+            column="5"/>
+    </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;color name=&quot;homepage_sound_background&quot;>#01B1AF&lt;/color>"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -1333,6 +1321,22 @@
         priority="4"
         summary="Using hardcoded color"
         explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+        errorLine1="    &lt;color name=&quot;power_anomaly_primary_button_text_color&quot;>#2E3300&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values-night/colors.xml"
+            line="61"
+            column="5"/>
+    </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;color name=&quot;homepage_storage_background&quot;>#C14CE6&lt;/color>"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -1365,22 +1369,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="    &lt;color name=&quot;udfps_enroll_icon&quot;>#7DA7F1&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values-night/colors.xml"
-            line="63"
-            column="5"/>
-    </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;color name=&quot;homepage_accounts_background&quot;>#F15B8D&lt;/color>"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -1397,8 +1385,8 @@
         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;color name=&quot;udfps_moving_target_fill&quot;>#475670&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine1="    &lt;color name=&quot;udfps_enroll_icon&quot;>#7DA7F1&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values-night/colors.xml"
             line="64"
@@ -1429,10 +1417,10 @@
         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;color name=&quot;homepage_system_background&quot;>#9E9E9E&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine1="    &lt;color name=&quot;udfps_moving_target_fill&quot;>#475670&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="res/values/colors.xml"
+            file="res/values-night/colors.xml"
             line="65"
             column="5"/>
     </issue>
@@ -1445,11 +1433,11 @@
         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;color name=&quot;udfps_moving_target_fill_error&quot;>#80475670&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine1="    &lt;color name=&quot;homepage_system_background&quot;>#9E9E9E&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="res/values-night/colors.xml"
-            line="66"
+            file="res/values/colors.xml"
+            line="65"
             column="5"/>
     </issue>
 
@@ -1477,8 +1465,8 @@
         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;color name=&quot;udfps_enroll_progress&quot;>#7DA7F1&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine1="    &lt;color name=&quot;udfps_moving_target_fill_error&quot;>#80475670&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values-night/colors.xml"
             line="67"
@@ -1509,8 +1497,8 @@
         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;color name=&quot;udfps_enroll_progress_help&quot;>#607DA7F1&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine1="    &lt;color name=&quot;udfps_enroll_progress&quot;>#7DA7F1&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values-night/colors.xml"
             line="68"
@@ -1541,8 +1529,8 @@
         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;color name=&quot;udfps_enroll_progress_help_with_talkback&quot;>#FFEE675C&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine1="    &lt;color name=&quot;udfps_enroll_progress_help&quot;>#607DA7F1&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values-night/colors.xml"
             line="69"
@@ -1573,43 +1561,27 @@
         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;color name=&quot;udfps_enroll_progress_help_with_talkback&quot;>#FFEE675C&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values-night/colors.xml"
+            line="70"
+            column="5"/>
+    </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;color name=&quot;screen_flash_color_button_outer_circle_stroke_color&quot;>#FFFFFF&lt;/color>"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values-night/colors.xml"
-            line="73"
-            column="5"/>
-    </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;color name=&quot;switch_bar_state_disabled_color&quot;>#1FE3E3E3&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values-night/colors.xml"
-            line="76"
-            column="5"/>
-    </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;color name=&quot;switchbar_switch_track_tint&quot;>#BFFFFFFF&lt;/color>"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values/colors.xml"
-            line="76"
+            line="74"
             column="5"/>
     </issue>
 
@@ -1625,7 +1597,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="79"
+            line="75"
             column="5"/>
     </issue>
 
@@ -1641,7 +1613,23 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="80"
+            line="76"
+            column="5"/>
+    </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;color name=&quot;switch_bar_state_disabled_color&quot;>#1FE3E3E3&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values-night/colors.xml"
+            line="77"
             column="5"/>
     </issue>
 
@@ -1657,7 +1645,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="83"
+            line="79"
             column="5"/>
     </issue>
 
@@ -1673,7 +1661,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="84"
+            line="80"
             column="5"/>
     </issue>
 
@@ -1689,7 +1677,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="85"
+            line="81"
             column="5"/>
     </issue>
 
@@ -1705,7 +1693,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="86"
+            line="82"
             column="5"/>
     </issue>
 
@@ -1721,7 +1709,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="87"
+            line="83"
             column="5"/>
     </issue>
 
@@ -1737,7 +1725,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="90"
+            line="86"
             column="5"/>
     </issue>
 
@@ -1753,7 +1741,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="91"
+            line="87"
             column="5"/>
     </issue>
 
@@ -1769,7 +1757,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="92"
+            line="88"
             column="5"/>
     </issue>
 
@@ -1785,7 +1773,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="95"
+            line="91"
             column="5"/>
     </issue>
 
@@ -1801,7 +1789,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="103"
+            line="99"
             column="5"/>
     </issue>
 
@@ -1817,7 +1805,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="105"
+            line="101"
             column="5"/>
     </issue>
 
@@ -1833,7 +1821,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="109"
+            line="105"
             column="5"/>
     </issue>
 
@@ -1849,7 +1837,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="110"
+            line="106"
             column="5"/>
     </issue>
 
@@ -1865,7 +1853,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="111"
+            line="107"
             column="5"/>
     </issue>
 
@@ -1881,7 +1869,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="112"
+            line="108"
             column="5"/>
     </issue>
 
@@ -1897,7 +1885,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="113"
+            line="109"
             column="5"/>
     </issue>
 
@@ -1913,7 +1901,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="114"
+            line="110"
             column="5"/>
     </issue>
 
@@ -1929,7 +1917,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="115"
+            line="111"
             column="5"/>
     </issue>
 
@@ -1945,7 +1933,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="116"
+            line="112"
             column="5"/>
     </issue>
 
@@ -1961,7 +1949,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="119"
+            line="115"
             column="5"/>
     </issue>
 
@@ -1977,7 +1965,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="120"
+            line="116"
             column="5"/>
     </issue>
 
@@ -1993,7 +1981,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="121"
+            line="117"
             column="5"/>
     </issue>
 
@@ -2009,7 +1997,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="122"
+            line="118"
             column="5"/>
     </issue>
 
@@ -2025,7 +2013,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="123"
+            line="119"
             column="5"/>
     </issue>
 
@@ -2041,7 +2029,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="124"
+            line="120"
             column="5"/>
     </issue>
 
@@ -2057,7 +2045,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="125"
+            line="121"
             column="5"/>
     </issue>
 
@@ -2073,7 +2061,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="126"
+            line="122"
             column="5"/>
     </issue>
 
@@ -2089,7 +2077,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="129"
+            line="125"
             column="5"/>
     </issue>
 
@@ -2105,7 +2093,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="130"
+            line="126"
             column="5"/>
     </issue>
 
@@ -2121,7 +2109,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="131"
+            line="127"
             column="5"/>
     </issue>
 
@@ -2137,7 +2125,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="132"
+            line="128"
             column="5"/>
     </issue>
 
@@ -2153,7 +2141,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="133"
+            line="129"
             column="5"/>
     </issue>
 
@@ -2169,7 +2157,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="134"
+            line="130"
             column="5"/>
     </issue>
 
@@ -2185,7 +2173,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="137"
+            line="133"
             column="5"/>
     </issue>
 
@@ -2201,7 +2189,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="138"
+            line="134"
             column="5"/>
     </issue>
 
@@ -2217,7 +2205,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="139"
+            line="135"
             column="5"/>
     </issue>
 
@@ -2233,7 +2221,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="140"
+            line="136"
             column="5"/>
     </issue>
 
@@ -2249,7 +2237,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="141"
+            line="137"
             column="5"/>
     </issue>
 
@@ -2265,7 +2253,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="142"
+            line="138"
             column="5"/>
     </issue>
 
@@ -2281,7 +2269,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="145"
+            line="141"
             column="5"/>
     </issue>
 
@@ -2297,7 +2285,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="146"
+            line="142"
             column="5"/>
     </issue>
 
@@ -2313,7 +2301,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="147"
+            line="143"
             column="5"/>
     </issue>
 
@@ -2329,7 +2317,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="148"
+            line="144"
             column="5"/>
     </issue>
 
@@ -2345,7 +2333,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="150"
+            line="146"
             column="5"/>
     </issue>
 
@@ -2361,7 +2349,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="152"
+            line="148"
             column="5"/>
     </issue>
 
@@ -2377,7 +2365,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="155"
+            line="151"
             column="5"/>
     </issue>
 
@@ -2393,7 +2381,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="158"
+            line="154"
             column="5"/>
     </issue>
 
@@ -2409,7 +2397,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="159"
+            line="155"
             column="5"/>
     </issue>
 
@@ -2425,7 +2413,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="160"
+            line="156"
             column="5"/>
     </issue>
 
@@ -2441,7 +2429,7 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="161"
+            line="157"
             column="5"/>
     </issue>
 
@@ -2457,7 +2445,39 @@
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/values/colors.xml"
-            line="162"
+            line="158"
+            column="5"/>
+    </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;color name=&quot;power_anomaly_app_warning_hint_color&quot;>#D56E0C&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values/colors.xml"
+            line="173"
+            column="5"/>
+    </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;color name=&quot;power_anomaly_primary_button_text_color&quot;>#FFFFFF&lt;/color>"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="res/values/colors.xml"
+            line="174"
             column="5"/>
     </issue>
 
@@ -4581,12 +4601,12 @@
         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:tint=&quot;#4F8438&quot;"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine1="                android:tint=&quot;#4F8438&quot;"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="res/layout/locale_dialog.xml"
-            line="36"
-            column="13"/>
+            line="45"
+            column="17"/>
     </issue>
 
     <issue
@@ -6105,7 +6125,7 @@
         errorLine2="                                          ^">
         <location
             file="res/values/styles.xml"
-            line="930"
+            line="944"
             column="43"/>
     </issue>
 
@@ -6121,7 +6141,7 @@
         errorLine2="                                          ^">
         <location
             file="res/values/styles.xml"
-            line="930"
+            line="944"
             column="43"/>
     </issue>
 
@@ -6137,7 +6157,7 @@
         errorLine2="                                                ^">
         <location
             file="res/values/styles.xml"
-            line="931"
+            line="945"
             column="49"/>
     </issue>
 
@@ -6153,7 +6173,7 @@
         errorLine2="                                                ^">
         <location
             file="res/values/styles.xml"
-            line="931"
+            line="945"
             column="49"/>
     </issue>
 
@@ -6169,7 +6189,7 @@
         errorLine2="                                                     ^">
         <location
             file="res/values/styles.xml"
-            line="932"
+            line="946"
             column="54"/>
     </issue>
 
@@ -6185,7 +6205,7 @@
         errorLine2="                                                     ^">
         <location
             file="res/values/styles.xml"
-            line="932"
+            line="946"
             column="54"/>
     </issue>
 
@@ -6201,7 +6221,7 @@
         errorLine2="                                              ^">
         <location
             file="res/values/styles.xml"
-            line="933"
+            line="947"
             column="47"/>
     </issue>
 
@@ -6217,7 +6237,7 @@
         errorLine2="                                              ^">
         <location
             file="res/values/styles.xml"
-            line="933"
+            line="947"
             column="47"/>
     </issue>
 
@@ -6233,7 +6253,7 @@
         errorLine2="                                                  ^">
         <location
             file="res/values/styles.xml"
-            line="934"
+            line="948"
             column="51"/>
     </issue>
 
@@ -6249,7 +6269,7 @@
         errorLine2="                                                  ^">
         <location
             file="res/values/styles.xml"
-            line="934"
+            line="948"
             column="51"/>
     </issue>
 
@@ -6265,7 +6285,7 @@
         errorLine2="                                                              ^">
         <location
             file="res/values/styles.xml"
-            line="935"
+            line="949"
             column="63"/>
     </issue>
 
@@ -6281,7 +6301,7 @@
         errorLine2="                                                              ^">
         <location
             file="res/values/styles.xml"
-            line="935"
+            line="949"
             column="63"/>
     </issue>
 
@@ -6357,43 +6377,11 @@
         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;item name=&quot;android:trackTint&quot;>@color/switchbar_switch_track_tint&lt;/item>"
-        errorLine2="                                       ^">
-        <location
-            file="res/values/themes.xml"
-            line="115"
-            column="40"/>
-    </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;item name=&quot;android:trackTint&quot;>@color/switchbar_switch_track_tint&lt;/item>"
-        errorLine2="                                       ^">
-        <location
-            file="res/values/themes.xml"
-            line="115"
-            column="40"/>
-    </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;item name=&quot;android:colorError&quot;>@color/settings_dialog_colorError&lt;/item>"
         errorLine2="                                        ^">
         <location
             file="res/values/themes.xml"
-            line="127"
+            line="119"
             column="41"/>
     </issue>
 
@@ -6409,7 +6397,7 @@
         errorLine2="                                        ^">
         <location
             file="res/values/themes.xml"
-            line="127"
+            line="119"
             column="41"/>
     </issue>
 
@@ -6425,7 +6413,7 @@
         errorLine2="                                            ^">
         <location
             file="res/values/themes.xml"
-            line="174"
+            line="168"
             column="45"/>
     </issue>
 
@@ -6441,7 +6429,7 @@
         errorLine2="                                                ^">
         <location
             file="res/values/themes.xml"
-            line="175"
+            line="169"
             column="49"/>
     </issue>
 
@@ -6457,7 +6445,7 @@
         errorLine2="                                            ^">
         <location
             file="res/values/themes.xml"
-            line="183"
+            line="177"
             column="45"/>
     </issue>
 
@@ -6473,7 +6461,7 @@
         errorLine2="                                                ^">
         <location
             file="res/values/themes.xml"
-            line="184"
+            line="178"
             column="49"/>
     </issue>
 
diff --git a/res/color/color_battery_anomaly_yellow_selector.xml b/res/color/color_battery_anomaly_app_warning_selector.xml
similarity index 90%
rename from res/color/color_battery_anomaly_yellow_selector.xml
rename to res/color/color_battery_anomaly_app_warning_selector.xml
index 0dd79c2..4ad78e6 100644
--- a/res/color/color_battery_anomaly_yellow_selector.xml
+++ b/res/color/color_battery_anomaly_app_warning_selector.xml
@@ -14,5 +14,5 @@
      limitations under the License.
 -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="@color/palette_list_color_yellow"/>
+    <item android:color="@color/power_anomaly_app_warning_hint_color"/>
 </selector>
diff --git a/res/drawable/ic_battery_tips_lightbulb.xml b/res/drawable/ic_battery_tips_lightbulb.xml
index 6fffefc..19b6ab8 100644
--- a/res/drawable/ic_battery_tips_lightbulb.xml
+++ b/res/drawable/ic_battery_tips_lightbulb.xml
@@ -17,9 +17,9 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:width="32dp"
     android:height="32dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
+    android:viewportWidth="960"
+    android:viewportHeight="960">
     <path
         android:fillColor="@color/color_accent_selector"
-        android:pathData="M7,20h4c0,1.1 -0.9,2 -2,2S7,21.1 7,20zM5,19h8v-2H5V19zM16.5,9.5c0,3.82 -2.66,5.86 -3.77,6.5H5.27C4.16,15.36 1.5,13.32 1.5,9.5C1.5,5.36 4.86,2 9,2S16.5,5.36 16.5,9.5zM14.5,9.5C14.5,6.47 12.03,4 9,4S3.5,6.47 3.5,9.5c0,2.47 1.49,3.89 2.35,4.5h6.3C13.01,13.39 14.5,11.97 14.5,9.5zM21.37,7.37L20,8l1.37,0.63L22,10l0.63,-1.37L24,8l-1.37,-0.63L22,6L21.37,7.37zM19,6l0.94,-2.06L22,3l-2.06,-0.94L19,0l-0.94,2.06L16,3l2.06,0.94L19,6z"/>
+        android:pathData="M176,680Q114,643 77,580Q40,517 40,440Q40,323 121.5,241.5Q203,160 320,160Q437,160 518.5,241.5Q600,323 600,440Q600,517 563,580Q526,643 464,680L176,680ZM200,600L440,600Q478,571 499,529.5Q520,488 520,440Q520,357 461.5,298.5Q403,240 320,240Q237,240 178.5,298.5Q120,357 120,440Q120,488 141,529.5Q162,571 200,600ZM176,800L176,720L464,720L464,800L176,800ZM320,920Q287,920 263.5,896.5Q240,873 240,840L400,840Q400,873 376.5,896.5Q353,920 320,920ZM740,401Q740,326 687,273Q634,220 559,220Q634,220 687,167.5Q740,115 740,40Q740,115 792.5,167.5Q845,220 920,220Q845,220 792.5,273Q740,326 740,401ZM320,600Q320,600 320,600Q320,600 320,600Q320,600 320,600Q320,600 320,600Q320,600 320,600Q320,600 320,600Q320,600 320,600Q320,600 320,600L320,600Z"/>
 </vector>
\ No newline at end of file
diff --git a/res/drawable/ic_battery_tips_warning_icon.xml b/res/drawable/ic_battery_tips_warning_icon.xml
index c5df8a8..0dcfa6d 100644
--- a/res/drawable/ic_battery_tips_warning_icon.xml
+++ b/res/drawable/ic_battery_tips_warning_icon.xml
@@ -17,9 +17,9 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:width="32dp"
     android:height="32dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
+    android:viewportWidth="960"
+    android:viewportHeight="960">
     <path
-        android:fillColor="@color/color_battery_anomaly_yellow_selector"
-        android:pathData="M1,21h22L12,2 1,21zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z"/>
+        android:fillColor="@color/color_battery_anomaly_app_warning_selector"
+        android:pathData="M40,840L480,80L920,840L40,840ZM178,760L782,760L480,240L178,760ZM480,720Q497,720 508.5,708.5Q520,697 520,680Q520,663 508.5,651.5Q497,640 480,640Q463,640 451.5,651.5Q440,663 440,680Q440,697 451.5,708.5Q463,720 480,720ZM440,600L520,600L520,400L440,400L440,600ZM480,500L480,500L480,500L480,500Z"/>
 </vector>
\ No newline at end of file
diff --git a/res/layout-v34/settingslib_main_switch_bar.xml b/res/layout-v34/settingslib_main_switch_bar.xml
new file mode 100644
index 0000000..3a44d2a
--- /dev/null
+++ b/res/layout-v34/settingslib_main_switch_bar.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2023 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_height="wrap_content"
+    android:layout_width="match_parent"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingTop="@dimen/settingslib_switchbar_margin"
+    android:paddingBottom="@dimen/settingslib_switchbar_margin"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:id="@+id/frame"
+        android:minHeight="@dimen/settingslib_min_switch_bar_height"
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent"
+        android:paddingStart="@dimen/settingslib_switchbar_padding_left"
+        android:paddingEnd="@dimen/settingslib_switchbar_padding_right"
+        android:background="@drawable/settingslib_switch_bar_bg">
+
+        <TextView
+            android:id="@+id/switch_text"
+            android:layout_height="wrap_content"
+            android:layout_width="0dp"
+            android:layout_weight="1"
+            android:layout_marginEnd="@dimen/settingslib_switch_title_margin"
+            android:layout_marginVertical="@dimen/settingslib_switch_title_margin"
+            android:layout_gravity="center_vertical"
+            android:ellipsize="end"
+            android:textAppearance="?android:attr/textAppearanceListItem"
+            android:hyphenationFrequency="normalFast"
+            android:lineBreakWordStyle="phrase"
+            style="@style/MainSwitchText.Settingslib" />
+
+        <com.google.android.material.materialswitch.MaterialSwitch
+            android:id="@android:id/switch_widget"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:background="@null"
+            android:clickable="false"
+            android:focusable="false"
+            android:theme="@style/Theme.Material3.DynamicColors.DayNight" />
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/res/layout/battery_tips_card.xml b/res/layout/battery_tips_card.xml
index c9a00bc..1a121ba 100644
--- a/res/layout/battery_tips_card.xml
+++ b/res/layout/battery_tips_card.xml
@@ -4,109 +4,58 @@
     android:id="@+id/battery_tips_card"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:layout_marginStart="?android:attr/listPreferredItemPaddingStart"
+    android:layout_marginEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:background="@drawable/battery_tips_all_rounded_bg_ripple"
     android:orientation="vertical"
-    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
-    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
+    android:padding="20dp">
 
-    <LinearLayout
-        android:id="@+id/tips_card"
+    <ImageView
+        android:id="@+id/icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical|start"
+        android:contentDescription="@string/battery_usage_anomaly_content_description"
+        android:src="@drawable/ic_battery_tips_lightbulb" />
+
+    <TextView
+        android:id="@+id/title"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:background="@drawable/battery_tips_all_rounded_bg_ripple"
-        android:orientation="vertical"
-        android:padding="24dp">
-
-        <ImageView
-            android:id="@+id/icon"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical|start"
-            android:src="@drawable/ic_battery_tips_lightbulb" />
-
-        <TextView
-            android:id="@+id/title"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="8dp"
-            android:textAlignment="viewStart"
-            android:textAppearance="?android:attr/textAppearanceLarge"
-            android:textColor="?android:attr/textColorPrimary" />
-
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="horizontal"
-            android:layout_marginTop="8dp"
-            android:gravity="end">
-
-            <com.google.android.material.button.MaterialButton
-                android:id="@+id/dismiss_button"
-                style="@style/Widget.Material3.Button.TextButton"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="end|center_vertical"
-                android:paddingHorizontal="16dp"
-                android:layout_marginEnd="8dp"
-                android:text="@string/battery_tips_card_dismiss_button"
-                android:textAppearance="?android:attr/textAppearanceSmall"
-                android:textColor="?android:attr/textColorPrimary" />
-
-            <com.google.android.material.button.MaterialButton
-                android:id="@+id/main_button"
-                style="@style/Widget.Material3.Button.OutlinedButton"
-                android:paddingHorizontal="16dp"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="end|center_vertical"
-                android:text="@string/battery_tips_card_action_button"
-                android:textAppearance="?android:attr/textAppearanceSmall"
-                android:textColor="?android:attr/textColorPrimary"
-                app:strokeColor="@color/color_accent_selector"
-                app:strokeWidth="1dp" />
-        </LinearLayout>
-    </LinearLayout>
-
-    <Space
-        android:layout_width="0dp"
-        android:layout_height="1dp"/>
+        android:layout_marginTop="8dp"
+        android:textAlignment="viewStart"
+        android:textAppearance="@style/TextAppearance.Material3.TitleMedium"
+        android:textColor="?android:attr/textColorPrimary" />
 
     <LinearLayout
-        android:id="@+id/feedback_card"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:background="@drawable/battery_tips_half_rounded_bottom_bg"
-        android:gravity="center_vertical|start"
-        android:orientation="horizontal"
-        android:paddingHorizontal="24dp"
-        android:paddingVertical="16dp"
-        android:visibility="gone">
+        android:layout_marginTop="8dp"
+        android:gravity="end"
+        android:orientation="horizontal">
 
-        <TextView
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="0dp"
-            android:layout_marginEnd="20dp"
-            android:layout_weight="1"
-            android:text="@string/battery_tips_card_feedback_info"
-            android:textAlignment="viewStart"
-            android:textColor="?android:attr/textColorPrimary"
-            android:textStyle="bold"/>
-
-        <ImageButton
-            android:id="@+id/thumb_up"
-            style="@style/Banner.Dismiss.SettingsLib"
+        <com.google.android.material.button.MaterialButton
+            android:id="@+id/dismiss_button"
+            style="@style/Widget.Material3.Button.TextButton"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical|end"
-            android:layout_marginEnd="20dp"
-            android:src="@drawable/ic_battery_tips_thumb_up" />
+            android:layout_gravity="end|center_vertical"
+            android:layout_marginEnd="8dp"
+            android:paddingHorizontal="16dp"
+            android:text="@string/battery_tips_card_dismiss_button"
+            android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle2"
+            android:textColor="@color/color_accent_selector" />
 
-        <ImageButton
-            android:id="@+id/thumb_down"
-            style="@style/Banner.Dismiss.SettingsLib"
+        <com.google.android.material.button.MaterialButton
+            android:id="@+id/main_button"
+            style="@style/Widget.Material3.Button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical|end"
-            android:src="@drawable/ic_battery_tips_thumb_down" />
+            android:layout_gravity="end|center_vertical"
+            android:paddingHorizontal="16dp"
+            android:text="@string/battery_tips_card_action_button"
+            android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle2"
+            android:textColor="@color/power_anomaly_primary_button_text_color"
+            app:backgroundTint="@color/color_accent_selector" />
     </LinearLayout>
 </LinearLayout>
\ No newline at end of file
diff --git a/res/layout/dialog_audio_sharing_disconnect.xml b/res/layout/dialog_audio_sharing_disconnect.xml
new file mode 100644
index 0000000..09bac40
--- /dev/null
+++ b/res/layout/dialog_audio_sharing_disconnect.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:padding="24dp"
+    android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/share_audio_disconnect_description"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textAlignment="center"
+        android:layout_gravity="center"/>
+
+    <com.android.internal.widget.RecyclerView
+        android:visibility="visible"
+        android:id="@+id/device_btn_list"
+        android:nestedScrollingEnabled="false"
+        android:overScrollMode="never"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"/>
+
+    <Button
+        android:id="@+id/cancel_btn"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:text="@string/cancel"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/dialog_audio_sharing_join.xml b/res/layout/dialog_audio_sharing_join.xml
new file mode 100644
index 0000000..42d964a
--- /dev/null
+++ b/res/layout/dialog_audio_sharing_join.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:padding="24dp"
+    android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/share_audio_subtitle1"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textAlignment="center"
+        android:layout_gravity="center"/>
+
+    <TextView
+        android:id="@+id/share_audio_subtitle2"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textAlignment="center"
+        android:layout_gravity="center"/>
+
+    <Button
+        android:id="@+id/share_btn"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:text=""/>
+
+    <Button
+        android:id="@+id/cancel_btn"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:text="@string/cancel"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml
index b83b2fa..9334d19 100644
--- a/res/values-night/colors.xml
+++ b/res/values-night/colors.xml
@@ -56,6 +56,9 @@
     <!-- Icon tint color for battery usage system icon -->
     <color name="battery_usage_system_icon_color">@android:color/white</color>
 
+    <!-- Power anomaly color for icons, button and text -->
+    <color name="power_anomaly_app_warning_hint_color">#FDD663</color>
+    <color name="power_anomaly_primary_button_text_color">#2E3300</color>
 
     <!-- UDFPS colors -->
     <color name="udfps_enroll_icon">#7DA7F1</color>
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 484af0a..7283be2 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -1417,7 +1417,7 @@
 
     <string-array name="battery_tips_card_colors" translatable="false">
         <item>color_accent_selector</item>
-        <item>color_battery_anomaly_yellow_selector</item>
+        <item>color_battery_anomaly_app_warning_selector</item>
     </string-array>
 
     <!-- The following 4 arrays are for power anomaly tips card. Please keep them the same size. -->
diff --git a/res/values/colors.xml b/res/values/colors.xml
index ae97945..f76f46e 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -169,6 +169,10 @@
     <!-- Icon tint color for battery usage system icon -->
     <color name="battery_usage_system_icon_color">?android:attr/textColorPrimary</color>
 
+    <!-- Power anomaly color for icons, button and text -->
+    <color name="power_anomaly_app_warning_hint_color">#D56E0C</color>
+    <color name="power_anomaly_primary_button_text_color">#FFFFFF</color>
+
     <!-- UDFPS colors -->
     <color name="udfps_enroll_icon">#699FF3</color>
     <color name="udfps_moving_target_fill">#C2D7F7</color>
diff --git a/res/values/config.xml b/res/values/config.xml
index f50e918..7af29c8 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -761,6 +761,9 @@
         <item></item>
     </string-array>
 
+    <!-- Whether to display the "Enable wireless display" menu -->
+    <bool name="config_show_wifi_display_enable_menu">true</bool>
+
     <!-- List of packages that should be hidden for MVNO. Do not translate -->
     <string-array name="datausage_hiding_carrier_service_package_names" translatable="false"/>
 
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 718d4ae..fc202a5 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -389,7 +389,7 @@
     <dimen name="chartview_divider_height">4dp</dimen>
     <dimen name="chartview_transom_width">4dp</dimen>
     <dimen name="chartview_transom_radius">4dp</dimen>
-    <dimen name="chartview_transom_icon_size">12dp</dimen>
+    <dimen name="chartview_transom_icon_size">18dp</dimen>
     <dimen name="chartview_transom_padding_top">2dp</dimen>
     <dimen name="chartview_transom_layout_height">12dp</dimen>
     <dimen name="chartview_layout_height">182dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 55269e5..7406295 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -296,13 +296,15 @@
     <string name="calls_and_alarms_device_title">Calls and alarms</string>
 
     <!-- Title for audio streams preference category [CHAR LIMIT=none]-->
-    <string name="audio_sharing_streams_category_title">Connect to a LE audio stream</string>
+    <string name="audio_streams_category_title">Connect to a LE audio stream</string>
     <!-- Title for audio streams preference [CHAR LIMIT=none]-->
-    <string name="audio_sharing_streams_pref_title">Nearby audio streams</string>
+    <string name="audio_streams_pref_title">Nearby audio streams</string>
     <!-- Title for audio streams page [CHAR LIMIT=none]-->
-    <string name="audio_sharing_streams_title">Audio streams</string>
+    <string name="audio_streams_title">Audio streams</string>
     <!-- Summary for QR code scanning in audio streams page [CHAR LIMIT=none]-->
-    <string name="audio_sharing_streams_qr_code_summary">Connect to an audio stream using QR code</string>
+    <string name="audio_streams_qr_code_summary">Connect to an audio stream using QR code</string>
+    <!--Text that appears when scanning for nearby audio streams is finished and no streams were found [CHAR LIMIT=40]-->
+    <string name="audio_streams_empty">No nearby audio streams were found.</string>
 
     <!-- Date & time settings screen title -->
     <string name="date_and_time">Date &amp; time</string>
@@ -1206,8 +1208,22 @@
     <string name="private_space_title">Private Space</string>
     <!-- Summary for the Private Space page. [CHAR LIMIT=NONE] -->
     <string name="private_space_summary">Hide apps in a private folder</string>
+    <!-- Description for the Private Space page. [CHAR LIMIT=NONE] -->
+    <string name="private_space_description">Hide apps in a private folder that only you can access</string>
     <!-- Title for the Private Space one lock preference. [CHAR LIMIT=60] -->
-    <string name="private_space_one_lock_title">Unlock using screen lock</string>
+    <string name="private_space_lock_title">Private Space lock</string>
+    <!-- Description for the Private Space one lock preference page. [CHAR LIMIT=NONE] -->
+    <string name="private_space_one_lock_summary">You can unlock Private Space the same way you unlock your device, or choose a different lock</string>
+    <!-- Title for the Private Space one lock preference. [CHAR LIMIT=60] -->
+    <string name="private_space_screen_lock_title">Use device screen lock</string>
+    <!-- Title for the Face and Fingerprint preference. [CHAR LIMIT=60] -->
+    <string name="private_space_biometric_title">Face &amp; Fingerprint Unlock</string>
+    <!-- Summary for the Face and Fingerprint preference when no biometric is set. [CHAR LIMIT=60] -->
+    <string name="private_space_biometric_summary">Tap to set up</string>
+    <!-- Summary for one lock when device screen lock is used as private profile lock. [CHAR LIMIT=60] -->
+    <string name="private_space_screen_lock_summary">Same as device screen lock</string>
+    <!-- Dialog message to choose a new lock for Private Space. [CHAR LIMIT=50] -->
+    <string name="private_space_new_lock_title">Choose a new lock for Private Space?</string>
     <!-- Title for the preference to hide Private Space. [CHAR LIMIT=60] -->
     <string name="private_space_hide_title">Hide when locked</string>
     <!-- Title for the hide Private Space setting. [CHAR LIMIT=60] -->
@@ -1228,16 +1244,8 @@
     <string name="privatespace_hide_on_summary">On</string>
     <!-- System category for the Private Space page. [CHAR LIMIT=30] -->
     <string name="private_space_category_system">System</string>
-    <!-- Title for the preference to create Private Space. [CHAR LIMIT=60] -->
-    <string name="private_space_create_title">Create Private Space</string>
     <!-- Title for the preference to delete Private Space. [CHAR LIMIT=60] -->
     <string name="private_space_delete_title">Delete Private Space</string>
-    <!-- Toast to show when the private space was created. [CHAR LIMIT=NONE] -->
-    <string name="private_space_created">Private Space successfully created</string>
-    <!-- Toast to show when the private space already exists. [CHAR LIMIT=NONE] -->
-    <string name="private_space_already_exists">Private Space already exists</string>
-    <!-- Toast to show when the private space could not be created. [CHAR LIMIT=NONE] -->
-    <string name="private_space_create_failed">Private Space could not be created</string>
     <!-- Toast to show when the private space was deleted. [CHAR LIMIT=NONE] -->
     <string name="private_space_deleted">Private Space successfully deleted</string>
     <!-- Toast to show when the private space could not be deleted. [CHAR LIMIT=NONE] -->
@@ -10020,6 +10028,9 @@
     <!-- Summary of apps anomaly for higher than usual in foreground [CHAR LIMIT=NONE] -->
     <string name="battery_tips_apps_summary_higher_than_usual_in_foreground"><xliff:g id="app_label" example="Pokemon Go">%1$s</xliff:g> used more battery than usual while in the foreground</string>
 
+    <!-- Content description of the icon in power anomaly banner [CHAR LIMIT=NONE] -->
+    <string name="battery_usage_anomaly_content_description">Battery usage anomaly</string>
+
     <!-- Label of hint for apps anomaly in battery usage [CHAR LIMIT=NONE] -->
     <string name="battery_app_item_hint">High battery usage</string>
 
diff --git a/res/xml/bluetooth_audio_sharing.xml b/res/xml/bluetooth_audio_sharing.xml
index ca7137a..681c768 100644
--- a/res/xml/bluetooth_audio_sharing.xml
+++ b/res/xml/bluetooth_audio_sharing.xml
@@ -34,13 +34,13 @@
 
     <PreferenceCategory
         android:key="audio_streams_settings_category"
-        android:title="@string/audio_sharing_streams_category_title"
-        settings:controller="com.android.settings.connecteddevice.audiosharing.AudioStreamsCategoryController" >
+        android:title="@string/audio_streams_category_title"
+        settings:controller="com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsCategoryController">
 
         <Preference
             android:key="audio_streams_settings"
-            android:fragment="com.android.settings.connecteddevice.audiosharing.AudioStreamsDashboardFragment"
-            android:title="@string/audio_sharing_streams_pref_title"
+            android:fragment="com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsDashboardFragment"
+            android:title="@string/audio_streams_pref_title"
             android:icon="@drawable/ic_chevron_right_24dp" />
 
     </PreferenceCategory>
diff --git a/res/xml/bluetooth_audio_streams.xml b/res/xml/bluetooth_audio_streams.xml
index 9d05a06..ce7374b 100644
--- a/res/xml/bluetooth_audio_streams.xml
+++ b/res/xml/bluetooth_audio_streams.xml
@@ -17,12 +17,17 @@
 
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:title="@string/audio_sharing_streams_title">
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    android:title="@string/audio_streams_title">
 
     <Preference
         android:key="audio_streams_scan_qr_code"
         android:title="@string/bluetooth_find_broadcast_button_scan"
         android:icon="@drawable/ic_add_24dp"
-        android:summary="@string/audio_sharing_streams_qr_code_summary"/>
+        android:summary="@string/audio_streams_qr_code_summary" />
+
+    <com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsProgressCategoryPreference
+        android:key="audio_streams_nearby_category"
+        android:title="@string/audio_streams_pref_title" />
 
 </PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/bluetooth_audio_streams_qr_code.xml b/res/xml/bluetooth_audio_streams_qr_code.xml
new file mode 100644
index 0000000..c750963
--- /dev/null
+++ b/res/xml/bluetooth_audio_streams_qr_code.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:clipToPadding="false"
+        android:paddingLeft="25dp"
+        android:paddingRight="25dp"
+        android:gravity="center_horizontal"
+        android:orientation="vertical">
+
+        <TextView
+            android:id="@android:id/summary"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="start"
+            android:textSize="15sp"
+            android:textColor="?android:attr/textColorPrimary"
+            android:text="Scan this QR code with another device connected to LE audio headphones to start sharing audio"/>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:orientation="vertical"
+            android:paddingTop="70dp">
+
+            <ImageView
+                android:id="@+id/qrcode_view"
+                android:layout_width="@dimen/qrcode_size"
+                android:layout_height="@dimen/qrcode_size"
+                android:src="@android:color/transparent"/>
+        </LinearLayout>
+
+    </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/xml/private_space_settings.xml b/res/xml/private_space_settings.xml
index 33243e1..48835fc 100644
--- a/res/xml/private_space_settings.xml
+++ b/res/xml/private_space_settings.xml
@@ -22,13 +22,25 @@
     android:title="@string/private_space_title"
     settings:searchable="false">
 
+    <com.android.settingslib.widget.IllustrationPreference
+        android:key="privatespace_hide_video"
+        settings:searchable="false"
+        settings:lottie_rawRes="@drawable/privatespace_placeholder_image"/>
+
+    <Preference
+        android:key="private_space_description"
+        android:summary="@string/private_space_description"
+        android:selectable="false"
+        settings:searchable="false" />
+
     <PreferenceCategory
         android:title="@string/security_header">
 
-        <SwitchPreferenceCompat
+        <Preference
             android:key="private_space_use_one_lock"
-            android:title="@string/private_space_one_lock_title"
-            settings:controller="com.android.settings.privatespace.UseOneLockController"
+            android:title="@string/private_space_lock_title"
+            android:fragment="com.android.settings.privatespace.onelock.UseOneLockSettingsFragment"
+            settings:controller="com.android.settings.privatespace.onelock.UseOneLockController"
             settings:searchable="false" />
 
         <Preference
@@ -44,12 +56,6 @@
         android:title="@string/private_space_category_system">
 
         <Preference
-            android:key="private_space_create"
-            android:title="@string/private_space_create_title"
-            settings:controller="com.android.settings.privatespace.CreatePrivateSpaceController"
-            settings:searchable="false" />
-
-        <Preference
             android:key="private_space_delete"
             android:title="@string/private_space_delete_title"
             settings:controller="com.android.settings.privatespace.DeletePrivateSpaceController"
@@ -57,4 +63,4 @@
 
     </PreferenceCategory>
 
-</PreferenceScreen>
\ No newline at end of file
+</PreferenceScreen>
diff --git a/res/xml/privatespace_one_lock.xml b/res/xml/privatespace_one_lock.xml
new file mode 100644
index 0000000..e078c17
--- /dev/null
+++ b/res/xml/privatespace_one_lock.xml
@@ -0,0 +1,44 @@
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    android:title="@string/private_space_lock_title"
+    settings:searchable="false" >
+
+    <com.android.settingslib.widget.TopIntroPreference
+        android:title="@string/private_space_one_lock_summary"
+        settings:searchable="false" />
+
+    <com.android.settingslib.widget.MainSwitchPreference
+        android:key="private_lock_unification"
+        android:title="@string/private_space_screen_lock_title"
+        settings:searchable="false" />
+
+    <Preference
+        android:key="change_private_space_lock"
+        android:title="@string/private_space_lock_title"
+        android:summary="@string/unlock_set_unlock_mode_pattern"
+        settings:searchable="false" />
+
+    <Preference
+        android:key="private_space_biometrics"
+        android:title="@string/private_space_biometric_title"
+        android:summary="@string/private_space_biometric_summary"
+        android:fragment="com.android.settings.privatespace.onelock.FaceFingerprintUnlockFragment"
+        settings:searchable="false" />
+
+</PreferenceScreen>
diff --git a/res/xml/wifi_network_details_fragment2.xml b/res/xml/wifi_network_details_fragment2.xml
index 56e7b04..daff20f 100644
--- a/res/xml/wifi_network_details_fragment2.xml
+++ b/res/xml/wifi_network_details_fragment2.xml
@@ -169,15 +169,11 @@
                 settings:enableCopying="true"/>
     </PreferenceCategory>
 
-    <!-- IPv6 Details -->
-    <PreferenceCategory
-            android:key="ipv6_category"
-            android:title="@string/wifi_details_ipv6_address_header"
-            android:selectable="false">
-        <Preference
-                android:key="ipv6_addresses"
-                android:selectable="false"
-                settings:enableCopying="true"/>
-    </PreferenceCategory>
+    <!-- IPv6 address -->
+    <Preference
+        android:title="@string/wifi_details_ipv6_address_header"
+        android:key="ipv6_addresses"
+        android:selectable="false"
+        settings:enableCopying="true"/>
 
 </PreferenceScreen>
diff --git a/src/com/android/settings/accessibility/AccessibilityDetailsSettingsFragment.java b/src/com/android/settings/accessibility/AccessibilityDetailsSettingsFragment.java
index 3e3674c..0dbf05e 100644
--- a/src/com/android/settings/accessibility/AccessibilityDetailsSettingsFragment.java
+++ b/src/com/android/settings/accessibility/AccessibilityDetailsSettingsFragment.java
@@ -32,7 +32,6 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.text.TextUtils;
-import android.util.FeatureFlagUtils;
 import android.util.Log;
 import android.view.accessibility.AccessibilityManager;
 
@@ -112,9 +111,7 @@
             return new LaunchFragmentArguments(destination, /* arguments= */ null);
         }
 
-        if (ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.equals(componentName)
-                && FeatureFlagUtils.isEnabled(getContext(),
-                FeatureFlagUtils.SETTINGS_ACCESSIBILITY_HEARING_AID_PAGE)) {
+        if (ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.equals(componentName)) {
             final String destination = AccessibilityHearingAidsFragment.class.getName();
             return new LaunchFragmentArguments(destination, /* arguments= */ null);
         }
diff --git a/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceController.java b/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceController.java
index 3aad141..fab6e47 100644
--- a/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceController.java
+++ b/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceController.java
@@ -25,9 +25,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.os.Bundle;
 import android.text.TextUtils;
-import android.util.FeatureFlagUtils;
 
 import androidx.annotation.VisibleForTesting;
 import androidx.fragment.app.FragmentManager;
@@ -35,7 +33,6 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.bluetooth.BluetoothDeviceDetailsFragment;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.core.SubSettingLauncher;
 import com.android.settingslib.bluetooth.BluetoothCallback;
@@ -116,17 +113,7 @@
     @Override
     public boolean handlePreferenceTreeClick(Preference preference) {
         if (TextUtils.equals(preference.getKey(), getPreferenceKey())) {
-            final CachedBluetoothDevice device = mHelper.getConnectedHearingAidDevice();
-            if (FeatureFlagUtils.isEnabled(mContext,
-                    FeatureFlagUtils.SETTINGS_ACCESSIBILITY_HEARING_AID_PAGE)) {
-                launchHearingAidPage();
-                return true;
-            }
-            if (device == null) {
-                launchHearingAidInstructionDialog();
-            } else {
-                launchBluetoothDeviceDetailSetting(device);
-            }
+            launchHearingAidPage();
             return true;
         }
         return false;
@@ -215,29 +202,6 @@
         mHearingAidPreference = preference;
     }
 
-    @VisibleForTesting
-    void launchBluetoothDeviceDetailSetting(final CachedBluetoothDevice device) {
-        if (device == null) {
-            return;
-        }
-        final Bundle args = new Bundle();
-        args.putString(BluetoothDeviceDetailsFragment.KEY_DEVICE_ADDRESS,
-                device.getDevice().getAddress());
-
-        new SubSettingLauncher(mContext)
-                .setDestination(BluetoothDeviceDetailsFragment.class.getName())
-                .setArguments(args)
-                .setTitleRes(R.string.device_details_title)
-                .setSourceMetricsCategory(getMetricsCategory())
-                .launch();
-    }
-
-    @VisibleForTesting
-    void launchHearingAidInstructionDialog() {
-        HearingAidDialogFragment fragment = HearingAidDialogFragment.newInstance();
-        fragment.show(mFragmentManager, HearingAidDialogFragment.class.toString());
-    }
-
     private void launchHearingAidPage() {
         new SubSettingLauncher(mContext)
                 .setDestination(AccessibilityHearingAidsFragment.class.getName())
diff --git a/src/com/android/settings/accessibility/AccessibilityServiceWarning.java b/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
index e8ed85c..9022ebf 100644
--- a/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
+++ b/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
@@ -67,7 +67,11 @@
         void uninstallPackage();
     }
 
-    /** Returns a {@link Dialog} to be shown to confirm that they want to enable a service. */
+    /**
+     * Returns a {@link Dialog} to be shown to confirm that they want to enable a service.
+     * @deprecated Use {@link com.android.internal.accessibility.dialog.AccessibilityServiceWarning}
+     */
+    @Deprecated
     public static Dialog createCapabilitiesDialog(@NonNull Context context,
             @NonNull AccessibilityServiceInfo info, @NonNull View.OnClickListener listener,
             @NonNull UninstallActionPerformer performer) {
diff --git a/src/com/android/settings/accessibility/InvisibleToggleAccessibilityServicePreferenceFragment.java b/src/com/android/settings/accessibility/InvisibleToggleAccessibilityServicePreferenceFragment.java
index 0c1876f..1ecb94a 100644
--- a/src/com/android/settings/accessibility/InvisibleToggleAccessibilityServicePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/InvisibleToggleAccessibilityServicePreferenceFragment.java
@@ -64,9 +64,24 @@
     @Override
     void onDialogButtonFromShortcutToggleClicked(View view) {
         super.onDialogButtonFromShortcutToggleClicked(view);
-        if (view.getId() == R.id.permission_enable_allow_button) {
-            AccessibilityUtils.setAccessibilityServiceState(getContext(), mComponentName,
-                    true);
+        if (!android.view.accessibility.Flags.deduplicateAccessibilityWarningDialog()) {
+            if (view.getId() == R.id.permission_enable_allow_button) {
+                AccessibilityUtils.setAccessibilityServiceState(getContext(), mComponentName,
+                        true);
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * Enables accessibility service when user clicks permission allow button.
+     */
+    @Override
+    void onAllowButtonFromShortcutToggleClicked() {
+        super.onAllowButtonFromShortcutToggleClicked();
+        if (android.view.accessibility.Flags.deduplicateAccessibilityWarningDialog()) {
+            AccessibilityUtils.setAccessibilityServiceState(getContext(), mComponentName, true);
         }
     }
 
diff --git a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
index 6847a6d..213f108 100644
--- a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
@@ -157,28 +157,55 @@
                 if (info == null) {
                     return null;
                 }
-                mWarningDialog = AccessibilityServiceWarning
-                        .createCapabilitiesDialog(getPrefContext(), info,
-                                this::onDialogButtonFromEnableToggleClicked,
-                                this::onDialogButtonFromUninstallClicked);
+                if (android.view.accessibility.Flags.deduplicateAccessibilityWarningDialog()) {
+                    mWarningDialog =
+                            com.android.internal.accessibility.dialog.AccessibilityServiceWarning
+                                    .createAccessibilityServiceWarningDialog(getPrefContext(), info,
+                                            v -> onAllowButtonFromEnableToggleClicked(),
+                                            v -> onDenyButtonFromEnableToggleClicked(),
+                                            v -> onDialogButtonFromUninstallClicked());
+                } else {
+                    mWarningDialog = AccessibilityServiceWarning
+                            .createCapabilitiesDialog(getPrefContext(), info,
+                                    this::onDialogButtonFromEnableToggleClicked,
+                                    this::onDialogButtonFromUninstallClicked);
+                }
                 return mWarningDialog;
             case DialogEnums.ENABLE_WARNING_FROM_SHORTCUT_TOGGLE:
                 if (info == null) {
                     return null;
                 }
-                mWarningDialog = AccessibilityServiceWarning
-                        .createCapabilitiesDialog(getPrefContext(), info,
-                                this::onDialogButtonFromShortcutToggleClicked,
-                                this::onDialogButtonFromUninstallClicked);
+                if (android.view.accessibility.Flags.deduplicateAccessibilityWarningDialog()) {
+                    mWarningDialog =
+                            com.android.internal.accessibility.dialog.AccessibilityServiceWarning
+                                    .createAccessibilityServiceWarningDialog(getPrefContext(), info,
+                                            v -> onAllowButtonFromShortcutToggleClicked(),
+                                            v -> onDenyButtonFromShortcutToggleClicked(),
+                                            v -> onDialogButtonFromUninstallClicked());
+                } else {
+                    mWarningDialog = AccessibilityServiceWarning
+                            .createCapabilitiesDialog(getPrefContext(), info,
+                                    this::onDialogButtonFromShortcutToggleClicked,
+                                    this::onDialogButtonFromUninstallClicked);
+                }
                 return mWarningDialog;
             case DialogEnums.ENABLE_WARNING_FROM_SHORTCUT:
                 if (info == null) {
                     return null;
                 }
-                mWarningDialog = AccessibilityServiceWarning
-                        .createCapabilitiesDialog(getPrefContext(), info,
-                                this::onDialogButtonFromShortcutClicked,
-                                this::onDialogButtonFromUninstallClicked);
+                if (android.view.accessibility.Flags.deduplicateAccessibilityWarningDialog()) {
+                    mWarningDialog =
+                            com.android.internal.accessibility.dialog.AccessibilityServiceWarning
+                                    .createAccessibilityServiceWarningDialog(getPrefContext(), info,
+                                            v -> onAllowButtonFromShortcutClicked(),
+                                            v -> onDenyButtonFromShortcutClicked(),
+                                            v -> onDialogButtonFromUninstallClicked());
+                } else {
+                    mWarningDialog = AccessibilityServiceWarning
+                            .createCapabilitiesDialog(getPrefContext(), info,
+                                    this::onDialogButtonFromShortcutClicked,
+                                    this::onDialogButtonFromUninstallClicked);
+                }
                 return mWarningDialog;
             case DialogEnums.DISABLE_WARNING_FROM_TOGGLE:
                 if (info == null) {
@@ -459,7 +486,7 @@
         }
     }
 
-    private void onAllowButtonFromShortcutToggleClicked() {
+    void onAllowButtonFromShortcutToggleClicked() {
         mShortcutPreference.setChecked(true);
 
         final int shortcutTypes = retrieveUserShortcutType(getPrefContext(),
diff --git a/src/com/android/settings/accounts/AccountPreferenceController.java b/src/com/android/settings/accounts/AccountPreferenceController.java
index 33b3888..c5a8169 100644
--- a/src/com/android/settings/accounts/AccountPreferenceController.java
+++ b/src/com/android/settings/accounts/AccountPreferenceController.java
@@ -100,7 +100,6 @@
     private SparseArray<ProfileData> mProfiles = new SparseArray<ProfileData>();
     private ManagedProfileBroadcastReceiver mManagedProfileBroadcastReceiver =
             new ManagedProfileBroadcastReceiver();
-    private Preference mProfileNotAvailablePreference;
     private String[] mAuthorities;
     private int mAuthoritiesCount = 0;
     private DashboardFragment mFragment;
@@ -531,18 +530,19 @@
         } else {
             profileData.preferenceGroup.removeAll();
             // Put a label instead of the accounts list
-            if (mProfileNotAvailablePreference == null) {
-                mProfileNotAvailablePreference =
-                        new Preference(mFragment.getPreferenceManager().getContext());
-            }
-            mProfileNotAvailablePreference.setEnabled(false);
-            mProfileNotAvailablePreference.setIcon(R.drawable.empty_icon);
-            mProfileNotAvailablePreference.setTitle(null);
-            mProfileNotAvailablePreference.setSummary(
-                    mDpm.getResources().getString(
-                            WORK_PROFILE_NOT_AVAILABLE, () -> mContext.getString(
-                    R.string.managed_profile_not_available_label)));
-            profileData.preferenceGroup.addPreference(mProfileNotAvailablePreference);
+            final Preference profileNotAvailablePreference =
+                    new Preference(mFragment.getPreferenceManager().getContext());
+            profileNotAvailablePreference.setEnabled(false);
+            profileNotAvailablePreference.setIcon(R.drawable.empty_icon);
+            profileNotAvailablePreference.setTitle(null);
+            profileNotAvailablePreference.setSummary(
+                    mDpm.getResources()
+                            .getString(
+                                    WORK_PROFILE_NOT_AVAILABLE,
+                                    () ->
+                                            mContext.getString(
+                                                    R.string.managed_profile_not_available_label)));
+            profileData.preferenceGroup.addPreference(profileNotAvailablePreference);
         }
         if (profileData.removeWorkProfilePreference != null) {
             profileData.preferenceGroup.addPreference(profileData.removeWorkProfilePreference);
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceControlsController.java b/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceControlsController.java
index c4a4221..18ad210 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceControlsController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceControlsController.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.text.TextUtils;
-import android.util.FeatureFlagUtils;
 
 import androidx.preference.Preference;
 import androidx.preference.PreferenceCategory;
@@ -51,8 +50,7 @@
 
     @Override
     public boolean isAvailable() {
-        return mCachedDevice.isHearingAidDevice() && FeatureFlagUtils.isEnabled(mContext,
-                FeatureFlagUtils.SETTINGS_ACCESSIBILITY_HEARING_AID_PAGE);
+        return mCachedDevice.isHearingAidDevice();
     }
 
     @Override
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
index 73857f2..a3dace6 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
@@ -126,9 +126,12 @@
         pref.setOnPreferenceClickListener(this);
         pref.setOrder(profile.getOrdinal());
 
-        if (profile instanceof LeAudioProfile && !isModelNameInAllowList(
+        boolean isLeEnabledByDefault =
+                SystemProperties.getBoolean(LE_AUDIO_CONNECTION_BY_DEFAULT_PROPERTY, true);
+
+        if (profile instanceof LeAudioProfile && (!isLeEnabledByDefault || !isModelNameInAllowList(
                 BluetoothUtils.getStringMetaData(mCachedDevice.getDevice(),
-                        METADATA_MODEL_NAME))) {
+                        METADATA_MODEL_NAME)))) {
             pref.setSummary(R.string.device_details_leaudio_toggle_summary);
         }
         return pref;
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java
index d4803c6..b0f8b8f 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java
@@ -16,10 +16,14 @@
 
 package com.android.settings.connecteddevice.audiosharing;
 
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothCsipSetCoordinator;
 import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothLeBroadcast;
 import android.bluetooth.BluetoothLeBroadcastAssistant;
 import android.bluetooth.BluetoothLeBroadcastMetadata;
 import android.bluetooth.BluetoothLeBroadcastReceiveState;
+import android.bluetooth.BluetoothProfile;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.util.Log;
@@ -38,9 +42,19 @@
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.flags.Flags;
 import com.android.settingslib.bluetooth.BluetoothCallback;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
+import com.android.settingslib.bluetooth.LeAudioProfile;
+import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 
+import com.google.common.collect.ImmutableList;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
 
@@ -53,11 +67,74 @@
             "connected_device_audio_sharing_settings";
 
     private final LocalBluetoothManager mLocalBtManager;
+    private final LocalBluetoothLeBroadcast mBroadcast;
     private final LocalBluetoothLeBroadcastAssistant mAssistant;
     private final Executor mExecutor;
     private PreferenceGroup mPreferenceGroup;
     private Preference mAudioSharingSettingsPreference;
     private BluetoothDeviceUpdater mBluetoothDeviceUpdater;
+    private DashboardFragment mFragment;
+    private List<BluetoothDevice> mTargetSinks = new ArrayList<>();
+
+    private final BluetoothLeBroadcast.Callback mBroadcastCallback =
+            new BluetoothLeBroadcast.Callback() {
+                @Override
+                public void onBroadcastStarted(int reason, int broadcastId) {
+                    Log.d(
+                            TAG,
+                            "onBroadcastStarted(), reason = "
+                                    + reason
+                                    + ", broadcastId = "
+                                    + broadcastId);
+                }
+
+                @Override
+                public void onBroadcastStartFailed(int reason) {
+                    Log.d(TAG, "onBroadcastStartFailed(), reason = " + reason);
+                    // TODO: handle broadcast start fail
+                }
+
+                @Override
+                public void onBroadcastMetadataChanged(
+                        int broadcastId, @NonNull BluetoothLeBroadcastMetadata metadata) {
+                    Log.d(
+                            TAG,
+                            "onBroadcastMetadataChanged(), broadcastId = "
+                                    + broadcastId
+                                    + ", metadata = "
+                                    + metadata);
+                    addSourceToTargetDevices(mTargetSinks);
+                    mTargetSinks = new ArrayList<>();
+                }
+
+                @Override
+                public void onBroadcastStopped(int reason, int broadcastId) {
+                    Log.d(
+                            TAG,
+                            "onBroadcastStopped(), reason = "
+                                    + reason
+                                    + ", broadcastId = "
+                                    + broadcastId);
+                }
+
+                @Override
+                public void onBroadcastStopFailed(int reason) {
+                    Log.d(TAG, "onBroadcastStopFailed(), reason = " + reason);
+                    // TODO: handle broadcast stop fail
+                }
+
+                @Override
+                public void onBroadcastUpdated(int reason, int broadcastId) {}
+
+                @Override
+                public void onBroadcastUpdateFailed(int reason, int broadcastId) {}
+
+                @Override
+                public void onPlaybackStarted(int reason, int broadcastId) {}
+
+                @Override
+                public void onPlaybackStopped(int reason, int broadcastId) {}
+            };
 
     private BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback =
             new BluetoothLeBroadcastAssistant.Callback() {
@@ -149,6 +226,7 @@
     public AudioSharingDevicePreferenceController(Context context) {
         super(context, KEY);
         mLocalBtManager = Utils.getLocalBtManager(mContext);
+        mBroadcast = mLocalBtManager.getProfileManager().getLeAudioBroadcastProfile();
         mAssistant = mLocalBtManager.getProfileManager().getLeAudioBroadcastAssistantProfile();
         mExecutor = Executors.newSingleThreadExecutor();
     }
@@ -156,18 +234,19 @@
     @Override
     public void onStart(@NonNull LifecycleOwner owner) {
         if (mLocalBtManager == null) {
-            Log.e(TAG, "onStart() Bluetooth is not supported on this device");
+            Log.d(TAG, "onStart() Bluetooth is not supported on this device");
             return;
         }
-        if (mAssistant == null) {
-            Log.e(TAG, "onStart() Broadcast assistant is not supported on this device");
+        if (mBroadcast == null || mAssistant == null) {
+            Log.d(TAG, "onStart() Broadcast or assistant is not supported on this device");
             return;
         }
         if (mBluetoothDeviceUpdater == null) {
-            Log.e(TAG, "onStart() Bluetooth device updater is not initialized");
+            Log.d(TAG, "onStart() Bluetooth device updater is not initialized");
             return;
         }
         mLocalBtManager.getEventManager().registerCallback(this);
+        mBroadcast.registerServiceCallBack(mExecutor, mBroadcastCallback);
         mAssistant.registerServiceCallBack(mExecutor, mBroadcastAssistantCallback);
         mBluetoothDeviceUpdater.registerCallback();
         mBluetoothDeviceUpdater.refreshPreference();
@@ -176,23 +255,26 @@
     @Override
     public void onStop(@NonNull LifecycleOwner owner) {
         if (mLocalBtManager == null) {
-            Log.e(TAG, "onStop() Bluetooth is not supported on this device");
+            Log.d(TAG, "onStop() Bluetooth is not supported on this device");
             return;
         }
-        if (mAssistant == null) {
-            Log.e(TAG, "onStop() Broadcast assistant is not supported on this device");
+        if (mBroadcast == null || mAssistant == null) {
+            Log.d(TAG, "onStop() Broadcast or assistant is not supported on this device");
             return;
         }
         if (mBluetoothDeviceUpdater == null) {
-            Log.e(TAG, "onStop() Bluetooth device updater is not initialized");
+            Log.d(TAG, "onStop() Bluetooth device updater is not initialized");
             return;
         }
         mLocalBtManager.getEventManager().unregisterCallback(this);
         // TODO: verify the reason for failing to unregister
         try {
+            mBroadcast.unregisterServiceCallBack(mBroadcastCallback);
             mAssistant.unregisterServiceCallBack(mBroadcastAssistantCallback);
         } catch (IllegalArgumentException e) {
-            Log.e(TAG, "Fail to unregister assistant callback due to " + e.getMessage());
+            Log.e(
+                    TAG,
+                    "Fail to unregister broadcast or assistant callback due to " + e.getMessage());
         }
         mBluetoothDeviceUpdater.unregisterCallback();
     }
@@ -244,17 +326,239 @@
         }
     }
 
+    @Override
+    public void onProfileConnectionStateChanged(
+            @NonNull CachedBluetoothDevice cachedDevice,
+            @ConnectionState int state,
+            int bluetoothProfile) {
+        if (state != BluetoothAdapter.STATE_CONNECTED || !cachedDevice.getDevice().isConnected()) {
+            Log.d(TAG, "Ignore onProfileConnectionStateChanged, not connected state");
+            return;
+        }
+        if (mFragment == null) {
+            Log.d(TAG, "Ignore onProfileConnectionStateChanged, no host fragment");
+            return;
+        }
+        if (mAssistant == null && mBroadcast == null) {
+            Log.d(
+                    TAG,
+                    "Ignore onProfileConnectionStateChanged, no broadcast or assistant supported");
+            return;
+        }
+        boolean isLeAudioSupported = isLeAudioSupported(cachedDevice);
+        // For eligible (LE audio) remote device, we only check its connected LE audio profile.
+        if (isLeAudioSupported && bluetoothProfile != BluetoothProfile.LE_AUDIO) {
+            Log.d(
+                    TAG,
+                    "Ignore onProfileConnectionStateChanged, not the le profile for le audio"
+                            + " device");
+            return;
+        }
+        boolean isFirstConnectedProfile = isFirstConnectedProfile(cachedDevice, bluetoothProfile);
+        // For ineligible (non LE audio) remote device, we only check its first connected profile.
+        if (!isLeAudioSupported && !isFirstConnectedProfile) {
+            Log.d(
+                    TAG,
+                    "Ignore onProfileConnectionStateChanged, not the first connected profile for"
+                            + " non le audio device");
+            return;
+        }
+        if (!isLeAudioSupported) {
+            // Handle connected ineligible (non LE audio) remote device
+            if (isBroadcasting()) {
+                // Show stop audio sharing dialog when an ineligible (non LE audio) remote device
+                // connected during a sharing session.
+                AudioSharingStopDialogFragment.show(
+                        mFragment,
+                        cachedDevice.getName(),
+                        () -> {
+                            mBroadcast.stopBroadcast(mBroadcast.getLatestBroadcastId());
+                        });
+            }
+            // Do nothing for ineligible (non LE audio) remote device when no sharing session.
+        } else {
+            Map<Integer, List<CachedBluetoothDevice>> groupedDevices =
+                    fetchConnectedDevicesByGroupId();
+            // Handle connected eligible (LE audio) remote device
+            if (isBroadcasting()) {
+                // Show audio sharing switch or join dialog according to device count in the sharing
+                // session.
+                ArrayList<AudioSharingDeviceItem> deviceItemsInSharingSession =
+                        buildDeviceItemsInSharingSession(groupedDevices);
+                // Show audio sharing switch dialog when the third eligible (LE audio) remote device
+                // connected during a sharing session.
+                if (deviceItemsInSharingSession.size() >= 2) {
+                    AudioSharingDisconnectDialogFragment.show(
+                            mFragment,
+                            deviceItemsInSharingSession,
+                            cachedDevice.getName(),
+                            (AudioSharingDeviceItem item) -> {
+                                // Remove all sources from the device user clicked
+                                for (CachedBluetoothDevice device :
+                                        groupedDevices.get(item.getGroupId())) {
+                                    for (BluetoothLeBroadcastReceiveState source :
+                                            mAssistant.getAllSources(device.getDevice())) {
+                                        mAssistant.removeSource(
+                                                device.getDevice(), source.getSourceId());
+                                    }
+                                }
+                                // Add current broadcast to the latest connected device
+                                mAssistant.addSource(
+                                        cachedDevice.getDevice(),
+                                        mBroadcast.getLatestBluetoothLeBroadcastMetadata(),
+                                        /* isGroupOp= */ true);
+                            });
+                } else {
+                    // Show audio sharing join dialog when the first or second eligible (LE audio)
+                    // remote device connected during a sharing session.
+                    AudioSharingJoinDialogFragment.show(
+                            mFragment,
+                            deviceItemsInSharingSession,
+                            cachedDevice.getName(),
+                            () -> {
+                                // Add current broadcast to the latest connected device
+                                mAssistant.addSource(
+                                        cachedDevice.getDevice(),
+                                        mBroadcast.getLatestBluetoothLeBroadcastMetadata(),
+                                        /* isGroupOp= */ true);
+                            });
+                }
+            } else {
+                ArrayList<AudioSharingDeviceItem> deviceItems = new ArrayList<>();
+                for (List<CachedBluetoothDevice> devices : groupedDevices.values()) {
+                    // Use random device in the group within the sharing session to
+                    // represent the group.
+                    CachedBluetoothDevice device = devices.get(0);
+                    if (device.getGroupId() == cachedDevice.getGroupId()) {
+                        continue;
+                    }
+                    deviceItems.add(
+                            new AudioSharingDeviceItem(device.getName(), device.getGroupId()));
+                }
+                // Show audio sharing join dialog when the second eligible (LE audio) remote device
+                // connect and no sharing session.
+                if (deviceItems.size() == 1) {
+                    AudioSharingJoinDialogFragment.show(
+                            mFragment,
+                            deviceItems,
+                            cachedDevice.getName(),
+                            () -> {
+                                mTargetSinks = new ArrayList<>();
+                                for (List<CachedBluetoothDevice> devices :
+                                        groupedDevices.values()) {
+                                    for (CachedBluetoothDevice device : devices) {
+                                        mTargetSinks.add(device.getDevice());
+                                    }
+                                }
+                                mBroadcast.startBroadcast("test", null);
+                            });
+                }
+            }
+        }
+    }
+
     /**
      * Initialize the controller.
      *
      * @param fragment The fragment to provide the context and metrics category for {@link
-     *     AudioSharingBluetoothDeviceUpdater}.
+     *     AudioSharingBluetoothDeviceUpdater} and provide the host for dialogs.
      */
     public void init(DashboardFragment fragment) {
+        mFragment = fragment;
         mBluetoothDeviceUpdater =
                 new AudioSharingBluetoothDeviceUpdater(
                         fragment.getContext(),
                         AudioSharingDevicePreferenceController.this,
                         fragment.getMetricsCategory());
     }
+
+    private boolean isLeAudioSupported(CachedBluetoothDevice cachedDevice) {
+        return cachedDevice.getProfiles().stream()
+                .anyMatch(
+                        profile ->
+                                profile instanceof LeAudioProfile
+                                        && profile.isEnabled(cachedDevice.getDevice()));
+    }
+
+    private boolean isFirstConnectedProfile(
+            CachedBluetoothDevice cachedDevice, int bluetoothProfile) {
+        return cachedDevice.getProfiles().stream()
+                .noneMatch(
+                        profile ->
+                                profile.getProfileId() != bluetoothProfile
+                                        && profile.getConnectionStatus(cachedDevice.getDevice())
+                                                == BluetoothProfile.STATE_CONNECTED);
+    }
+
+    private boolean isBroadcasting() {
+        return mBroadcast != null && mBroadcast.isEnabled(null);
+    }
+
+    private Map<Integer, List<CachedBluetoothDevice>> fetchConnectedDevicesByGroupId() {
+        // TODO: filter out devices with le audio disabled.
+        List<BluetoothDevice> connectedDevices =
+                mAssistant == null ? ImmutableList.of() : mAssistant.getConnectedDevices();
+        Map<Integer, List<CachedBluetoothDevice>> groupedDevices = new HashMap<>();
+        CachedBluetoothDeviceManager cacheManager = mLocalBtManager.getCachedDeviceManager();
+        for (BluetoothDevice device : connectedDevices) {
+            CachedBluetoothDevice cachedDevice = cacheManager.findDevice(device);
+            if (cachedDevice == null) {
+                Log.d(TAG, "Skip device due to not being cached: " + device.getAnonymizedAddress());
+                continue;
+            }
+            int groupId = cachedDevice.getGroupId();
+            if (groupId == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
+                Log.d(
+                        TAG,
+                        "Skip device due to no valid group id: " + device.getAnonymizedAddress());
+                continue;
+            }
+            if (!groupedDevices.containsKey(groupId)) {
+                groupedDevices.put(groupId, new ArrayList<>());
+            }
+            groupedDevices.get(groupId).add(cachedDevice);
+        }
+        return groupedDevices;
+    }
+
+    private ArrayList<AudioSharingDeviceItem> buildDeviceItemsInSharingSession(
+            Map<Integer, List<CachedBluetoothDevice>> groupedDevices) {
+        ArrayList<AudioSharingDeviceItem> deviceItems = new ArrayList<>();
+        for (List<CachedBluetoothDevice> devices : groupedDevices.values()) {
+            for (CachedBluetoothDevice device : devices) {
+                List<BluetoothLeBroadcastReceiveState> sourceList =
+                        mAssistant.getAllSources(device.getDevice());
+                if (!sourceList.isEmpty()) {
+                    // Use random device in the group within the sharing session to
+                    // represent the group.
+                    deviceItems.add(
+                            new AudioSharingDeviceItem(device.getName(), device.getGroupId()));
+                    break;
+                }
+            }
+        }
+        return deviceItems;
+    }
+
+    private void addSourceToTargetDevices(List<BluetoothDevice> sinks) {
+        if (sinks.isEmpty() || mBroadcast == null || mAssistant == null) {
+            Log.d(TAG, "Skip adding source to target.");
+            return;
+        }
+        BluetoothLeBroadcastMetadata broadcastMetadata =
+                mBroadcast.getLatestBluetoothLeBroadcastMetadata();
+        if (broadcastMetadata == null) {
+            Log.e(TAG, "Error: There is no broadcastMetadata.");
+            return;
+        }
+        for (BluetoothDevice sink : sinks) {
+            Log.d(
+                    TAG,
+                    "Add broadcast with broadcastId: "
+                            + broadcastMetadata.getBroadcastId()
+                            + "to the device: "
+                            + sink.getAnonymizedAddress());
+            mAssistant.addSource(sink, broadcastMetadata, /* isGroupOp= */ false);
+        }
+    }
 }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java
new file mode 100644
index 0000000..1840f58
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2023 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.connecteddevice.audiosharing;
+
+import android.app.Dialog;
+import android.app.settings.SettingsEnums;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+
+import com.android.internal.widget.LinearLayoutManager;
+import com.android.internal.widget.RecyclerView;
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settings.flags.Flags;
+
+import java.util.ArrayList;
+
+public class AudioSharingDisconnectDialogFragment extends InstrumentedDialogFragment {
+    private static final String TAG = "AudioSharingDisconnectDialog";
+
+    private static final String BUNDLE_KEY_DEVICE_TO_DISCONNECT_ITEMS =
+            "bundle_key_device_to_disconnect_items";
+    private static final String BUNDLE_KEY_NEW_DEVICE_NAME = "bundle_key_new_device_name";
+
+    // The host creates an instance of this dialog fragment must implement this interface to receive
+    // event callbacks.
+    public interface DialogEventListener {
+        /**
+         * Called when users click the device item to disconnect from the audio sharing in the
+         * dialog.
+         *
+         * @param item The device item clicked.
+         */
+        void onItemClick(AudioSharingDeviceItem item);
+    }
+
+    private static DialogEventListener sListener;
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.DIALOG_AUDIO_SHARING_SWITCH_DEVICE;
+    }
+
+    /**
+     * Display the {@link AudioSharingDisconnectDialogFragment} dialog.
+     *
+     * @param host The Fragment this dialog will be hosted.
+     */
+    public static void show(
+            Fragment host,
+            ArrayList<AudioSharingDeviceItem> deviceItems,
+            String newDeviceName,
+            DialogEventListener listener) {
+        if (!Flags.enableLeAudioSharing()) return;
+        final FragmentManager manager = host.getChildFragmentManager();
+        sListener = listener;
+        if (manager.findFragmentByTag(TAG) == null) {
+            final Bundle bundle = new Bundle();
+            bundle.putParcelableArrayList(BUNDLE_KEY_DEVICE_TO_DISCONNECT_ITEMS, deviceItems);
+            bundle.putString(BUNDLE_KEY_NEW_DEVICE_NAME, newDeviceName);
+            AudioSharingDisconnectDialogFragment dialog =
+                    new AudioSharingDisconnectDialogFragment();
+            dialog.setArguments(bundle);
+            dialog.show(manager, TAG);
+        }
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        Bundle arguments = requireArguments();
+        ArrayList<AudioSharingDeviceItem> deviceItems =
+                arguments.getParcelableArrayList(BUNDLE_KEY_DEVICE_TO_DISCONNECT_ITEMS);
+        String newDeviceName = arguments.getString(BUNDLE_KEY_NEW_DEVICE_NAME);
+        final AlertDialog.Builder builder =
+                new AlertDialog.Builder(getActivity())
+                        .setTitle("Choose headphone to disconnect")
+                        .setCancelable(false);
+        View rootView =
+                LayoutInflater.from(builder.getContext())
+                        .inflate(R.layout.dialog_audio_sharing_disconnect, /* parent= */ null);
+        TextView subTitle = rootView.findViewById(R.id.share_audio_disconnect_description);
+        subTitle.setText(
+                "To share audio with " + newDeviceName + ", disconnect another pair of headphone");
+        RecyclerView recyclerView = rootView.findViewById(R.id.device_btn_list);
+        recyclerView.setAdapter(
+                new AudioSharingDeviceAdapter(
+                        deviceItems,
+                        (AudioSharingDeviceItem item) -> {
+                            sListener.onItemClick(item);
+                            dismiss();
+                        }));
+        recyclerView.setLayoutManager(
+                new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
+        Button cancelBtn = rootView.findViewById(R.id.cancel_btn);
+        cancelBtn.setOnClickListener(
+                v -> {
+                    dismiss();
+                });
+        AlertDialog dialog = builder.setView(rootView).create();
+        dialog.setCanceledOnTouchOutside(false);
+        return dialog;
+    }
+}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragment.java
new file mode 100644
index 0000000..b9646ac
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragment.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2023 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.connecteddevice.audiosharing;
+
+import android.app.Dialog;
+import android.app.settings.SettingsEnums;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settings.flags.Flags;
+
+import java.util.ArrayList;
+import java.util.Locale;
+import java.util.stream.Collectors;
+
+public class AudioSharingJoinDialogFragment extends InstrumentedDialogFragment {
+    private static final String TAG = "AudioSharingJoinDialog";
+    private static final String BUNDLE_KEY_DEVICE_ITEMS = "bundle_key_device_items";
+    private static final String BUNDLE_KEY_NEW_DEVICE_NAME = "bundle_key_new_device_name";
+
+    // The host creates an instance of this dialog fragment must implement this interface to receive
+    // event callbacks.
+    public interface DialogEventListener {
+        /** Called when users click the share audio button in the dialog. */
+        void onShareClick();
+    }
+
+    private static DialogEventListener sListener;
+    private View mRootView;
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.DIALOG_START_AUDIO_SHARING;
+    }
+
+    /**
+     * Display the {@link AudioSharingJoinDialogFragment} dialog.
+     *
+     * @param host The Fragment this dialog will be hosted.
+     * @param deviceItems The existing connected device items eligible for audio sharing.
+     * @param newDeviceName The name of the latest connected device triggered this dialog.
+     * @param listener The callback to handle the user action on this dialog.
+     */
+    public static void show(
+            Fragment host,
+            ArrayList<AudioSharingDeviceItem> deviceItems,
+            String newDeviceName,
+            DialogEventListener listener) {
+        if (!Flags.enableLeAudioSharing()) return;
+        final FragmentManager manager = host.getChildFragmentManager();
+        sListener = listener;
+        if (manager.findFragmentByTag(TAG) == null) {
+            final Bundle bundle = new Bundle();
+            bundle.putParcelableArrayList(BUNDLE_KEY_DEVICE_ITEMS, deviceItems);
+            bundle.putString(BUNDLE_KEY_NEW_DEVICE_NAME, newDeviceName);
+            final AudioSharingJoinDialogFragment dialog = new AudioSharingJoinDialogFragment();
+            dialog.setArguments(bundle);
+            dialog.show(manager, TAG);
+        }
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        Bundle arguments = requireArguments();
+        ArrayList<AudioSharingDeviceItem> deviceItems =
+                arguments.getParcelableArrayList(BUNDLE_KEY_DEVICE_ITEMS);
+        String newDeviceName = arguments.getString(BUNDLE_KEY_NEW_DEVICE_NAME);
+        final AlertDialog.Builder builder =
+                new AlertDialog.Builder(getActivity())
+                        .setTitle("Share audio?")
+                        .setCancelable(false);
+        mRootView =
+                LayoutInflater.from(builder.getContext())
+                        .inflate(R.layout.dialog_audio_sharing_join, null /* parent */);
+        TextView subtitle1 = mRootView.findViewById(R.id.share_audio_subtitle1);
+        TextView subtitle2 = mRootView.findViewById(R.id.share_audio_subtitle2);
+        if (deviceItems.isEmpty()) {
+            subtitle1.setText(newDeviceName);
+        } else {
+            subtitle1.setText(
+                    String.format(
+                            Locale.US,
+                            "%s and %s",
+                            deviceItems.stream()
+                                    .map(AudioSharingDeviceItem::getName)
+                                    .collect(Collectors.joining(", ")),
+                            newDeviceName));
+        }
+        subtitle2.setText(
+                "Connected eligible headphones will hear videos ad music playing on this phone");
+        Button shareBtn = mRootView.findViewById(R.id.share_btn);
+        Button cancelBtn = mRootView.findViewById(R.id.cancel_btn);
+        shareBtn.setOnClickListener(
+                v -> {
+                    sListener.onShareClick();
+                    dismiss();
+                });
+        shareBtn.setText("Share audio");
+        cancelBtn.setOnClickListener(v -> dismiss());
+        Dialog dialog = builder.setView(mRootView).create();
+        dialog.setCanceledOnTouchOutside(false);
+        return dialog;
+    }
+}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingNamePreference.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingNamePreference.java
index 387ab7e..81465ed 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingNamePreference.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingNamePreference.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.connecteddevice.audiosharing;
 
+import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.util.AttributeSet;
 import android.widget.ImageButton;
@@ -23,6 +24,8 @@
 import androidx.preference.PreferenceViewHolder;
 
 import com.android.settings.R;
+import com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsQrCodeFragment;
+import com.android.settings.core.SubSettingLauncher;
 import com.android.settings.widget.ValidatedEditTextPreference;
 
 public class AudioSharingNamePreference extends ValidatedEditTextPreference {
@@ -60,5 +63,12 @@
         super.onBindViewHolder(holder);
         final ImageButton shareButton = (ImageButton) holder.findViewById(R.id.button_icon);
         shareButton.setImageDrawable(getContext().getDrawable(R.drawable.ic_qrcode_24dp));
+        shareButton.setOnClickListener(
+                unused ->
+                        new SubSettingLauncher(getContext())
+                                .setTitleText("Audio sharing QR code")
+                                .setDestination(AudioStreamsQrCodeFragment.class.getName())
+                                .setSourceMetricsCategory(SettingsEnums.AUDIO_SHARING_SETTINGS)
+                                .launch());
     }
 }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java
new file mode 100644
index 0000000..495fad3
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2023 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.connecteddevice.audiosharing;
+
+import android.app.Dialog;
+import android.app.settings.SettingsEnums;
+import android.os.Bundle;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settings.flags.Flags;
+
+public class AudioSharingStopDialogFragment extends InstrumentedDialogFragment {
+    private static final String TAG = "AudioSharingStopDialog";
+
+    private static final String BUNDLE_KEY_NEW_DEVICE_NAME = "bundle_key_new_device_name";
+
+    // The host creates an instance of this dialog fragment must implement this interface to receive
+    // event callbacks.
+    public interface DialogEventListener {
+        /** Called when users click the stop sharing button in the dialog. */
+        void onStopSharingClick();
+    }
+
+    private static DialogEventListener sListener;
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.DIALOG_STOP_AUDIO_SHARING;
+    }
+
+    /**
+     * Display the {@link AudioSharingStopDialogFragment} dialog.
+     *
+     * @param host The Fragment this dialog will be hosted.
+     */
+    public static void show(Fragment host, String newDeviceName, DialogEventListener listener) {
+        if (!Flags.enableLeAudioSharing()) return;
+        final FragmentManager manager = host.getChildFragmentManager();
+        sListener = listener;
+        if (manager.findFragmentByTag(TAG) == null) {
+            final Bundle bundle = new Bundle();
+            bundle.putString(BUNDLE_KEY_NEW_DEVICE_NAME, newDeviceName);
+            AudioSharingStopDialogFragment dialog = new AudioSharingStopDialogFragment();
+            dialog.setArguments(bundle);
+            dialog.show(manager, TAG);
+        }
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        Bundle arguments = requireArguments();
+        String newDeviceName = arguments.getString(BUNDLE_KEY_NEW_DEVICE_NAME);
+        final AlertDialog.Builder builder =
+                new AlertDialog.Builder(getActivity())
+                        .setTitle("Stop sharing audio?")
+                        .setCancelable(false);
+        builder.setMessage(
+                newDeviceName + " is connected, devices in audio sharing will disconnect.");
+        builder.setPositiveButton(
+                "Stop sharing",
+                (dialog, which) -> {
+                    sListener.onStopSharingClick();
+                });
+        builder.setNegativeButton(
+                "Cancel",
+                (dialog, which) -> {
+                    dismiss();
+                });
+        AlertDialog dialog = builder.create();
+        dialog.setCanceledOnTouchOutside(false);
+        return dialog;
+    }
+}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioStreamsCategoryController.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsCategoryController.java
similarity index 88%
rename from src/com/android/settings/connecteddevice/audiosharing/AudioStreamsCategoryController.java
rename to src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsCategoryController.java
index e25a6ab..84a7be9 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioStreamsCategoryController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsCategoryController.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settings.connecteddevice.audiosharing;
+package com.android.settings.connecteddevice.audiosharing.audiostreams;
 
 import android.content.Context;
 
@@ -29,6 +29,8 @@
 
     @Override
     public int getAvailabilityStatus() {
-        return Flags.enableLeAudioQrCodePrivateBroadcastSharing() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+        return Flags.enableLeAudioQrCodePrivateBroadcastSharing()
+                ? AVAILABLE
+                : UNSUPPORTED_ON_DEVICE;
     }
 }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioStreamsDashboardFragment.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsDashboardFragment.java
similarity index 95%
rename from src/com/android/settings/connecteddevice/audiosharing/AudioStreamsDashboardFragment.java
rename to src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsDashboardFragment.java
index 40a8b29..562427f 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioStreamsDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsDashboardFragment.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settings.connecteddevice.audiosharing;
+package com.android.settings.connecteddevice.audiosharing.audiostreams;
 
 import android.content.Context;
 import android.os.Bundle;
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryPreference.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryPreference.java
new file mode 100644
index 0000000..d259900
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryPreference.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 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.connecteddevice.audiosharing.audiostreams;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import com.android.settings.ProgressCategory;
+import com.android.settings.R;
+
+public class AudioStreamsProgressCategoryPreference extends ProgressCategory {
+
+    public AudioStreamsProgressCategoryPreference(Context context) {
+        super(context);
+        init();
+    }
+
+    public AudioStreamsProgressCategoryPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    public AudioStreamsProgressCategoryPreference(
+            Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init();
+    }
+
+    public AudioStreamsProgressCategoryPreference(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        init();
+    }
+
+    private void init() {
+        setEmptyTextRes(R.string.audio_streams_empty);
+    }
+}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsQrCodeFragment.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsQrCodeFragment.java
new file mode 100644
index 0000000..42b38ee
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsQrCodeFragment.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2023 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.connecteddevice.audiosharing.audiostreams;
+
+import android.bluetooth.BluetoothLeBroadcastMetadata;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+
+import com.android.settings.R;
+import com.android.settings.bluetooth.Utils;
+import com.android.settings.core.InstrumentedFragment;
+import com.android.settingslib.bluetooth.BluetoothLeBroadcastMetadataExt;
+import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
+import com.android.settingslib.qrcode.QrCodeGenerator;
+
+import com.google.zxing.WriterException;
+
+import java.util.Optional;
+
+public class AudioStreamsQrCodeFragment extends InstrumentedFragment {
+    private static final String TAG = "AudioStreamsQrCodeFragment";
+
+    @Override
+    public int getMetricsCategory() {
+        // TODO(chelseahao): update metrics id
+        return 0;
+    }
+
+    @Override
+    public final View onCreateView(
+            LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        View view = inflater.inflate(R.xml.bluetooth_audio_streams_qr_code, container, false);
+        getQrCodeBitmap()
+                .ifPresent(
+                        bm ->
+                                ((ImageView) view.requireViewById(R.id.qrcode_view))
+                                        .setImageBitmap(bm));
+        return view;
+    }
+
+    private Optional<Bitmap> getQrCodeBitmap() {
+        String broadcastMetadata = getBroadcastMetadataQrCode();
+        if (broadcastMetadata.isEmpty()) {
+            Log.d(TAG, "onCreateView: broadcastMetadata is empty!");
+            return Optional.empty();
+        }
+
+        try {
+            int qrcodeSize = getContext().getResources().getDimensionPixelSize(R.dimen.qrcode_size);
+            Bitmap bitmap = QrCodeGenerator.encodeQrCode(broadcastMetadata, qrcodeSize);
+            return Optional.of(bitmap);
+        } catch (WriterException e) {
+            Log.d(
+                    TAG,
+                    "onCreateView: broadcastMetadata "
+                            + broadcastMetadata
+                            + " qrCode generation exception "
+                            + e);
+        }
+
+        return Optional.empty();
+    }
+
+    private String getBroadcastMetadataQrCode() {
+        LocalBluetoothLeBroadcast localBluetoothLeBroadcast =
+                Utils.getLocalBtManager(getActivity())
+                        .getProfileManager()
+                        .getLeAudioBroadcastProfile();
+        if (localBluetoothLeBroadcast == null) {
+            Log.d(TAG, "getBroadcastMetadataQrCode: localBluetoothLeBroadcast is null!");
+            return "";
+        }
+
+        BluetoothLeBroadcastMetadata metadata =
+                localBluetoothLeBroadcast.getLatestBluetoothLeBroadcastMetadata();
+        if (metadata == null) {
+            Log.d(TAG, "getBroadcastMetadataQrCode: metadata is null!");
+            return "";
+        }
+
+        return BluetoothLeBroadcastMetadataExt.INSTANCE.toQrCodeString(metadata);
+    }
+}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/qrcode/QrCodeScanModeActivity.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/qrcode/QrCodeScanModeActivity.java
new file mode 100644
index 0000000..d6d0634
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/qrcode/QrCodeScanModeActivity.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2023 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.connecteddevice.audiosharing.audiostreams.qrcode;
+
+import static com.android.settingslib.bluetooth.BluetoothBroadcastUtils.EXTRA_BLUETOOTH_DEVICE_SINK;
+import static com.android.settingslib.bluetooth.BluetoothBroadcastUtils.EXTRA_BLUETOOTH_SINK_IS_GROUP;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+import androidx.fragment.app.FragmentTransaction;
+
+import com.android.settings.R;
+import com.android.settingslib.bluetooth.BluetoothBroadcastUtils;
+import com.android.settingslib.bluetooth.BluetoothUtils;
+
+/**
+ * Finding a broadcast through QR code.
+ *
+ * <p>To use intent action {@link
+ * BluetoothBroadcastUtils#ACTION_BLUETOOTH_LE_AUDIO_QR_CODE_SCANNER}, specify the bluetooth device
+ * sink of the broadcast to be provisioned in {@link
+ * BluetoothBroadcastUtils#EXTRA_BLUETOOTH_DEVICE_SINK} and check the operation for all coordinated
+ * set members throughout one session or not by {@link
+ * BluetoothBroadcastUtils#EXTRA_BLUETOOTH_SINK_IS_GROUP}.
+ */
+public class QrCodeScanModeActivity extends QrCodeScanModeBaseActivity {
+    private static final boolean DEBUG = BluetoothUtils.D;
+    private static final String TAG = "QrCodeScanModeActivity";
+
+    private boolean mIsGroupOp;
+    private BluetoothDevice mSink;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    protected void handleIntent(Intent intent) {
+        String action = intent != null ? intent.getAction() : null;
+        if (DEBUG) {
+            Log.d(TAG, "handleIntent(), action = " + action);
+        }
+
+        if (action == null) {
+            finish();
+            return;
+        }
+
+        switch (action) {
+            case BluetoothBroadcastUtils.ACTION_BLUETOOTH_LE_AUDIO_QR_CODE_SCANNER:
+                showQrCodeScannerFragment(intent);
+                break;
+            default:
+                if (DEBUG) {
+                    Log.e(TAG, "Launch with an invalid action");
+                }
+                finish();
+        }
+    }
+
+    protected void showQrCodeScannerFragment(Intent intent) {
+        if (intent == null) {
+            if (DEBUG) {
+                Log.d(TAG, "intent is null, can not get bluetooth information from intent.");
+            }
+            return;
+        }
+
+        if (DEBUG) {
+            Log.d(TAG, "showQrCodeScannerFragment");
+        }
+
+        mSink = intent.getParcelableExtra(EXTRA_BLUETOOTH_DEVICE_SINK);
+        mIsGroupOp = intent.getBooleanExtra(EXTRA_BLUETOOTH_SINK_IS_GROUP, false);
+        if (DEBUG) {
+            Log.d(TAG, "get extra from intent");
+        }
+
+        QrCodeScanModeFragment fragment =
+                (QrCodeScanModeFragment)
+                        mFragmentManager.findFragmentByTag(
+                                BluetoothBroadcastUtils.TAG_FRAGMENT_QR_CODE_SCANNER);
+
+        if (fragment == null) {
+            fragment = new QrCodeScanModeFragment();
+        } else {
+            if (fragment.isVisible()) {
+                return;
+            }
+
+            // When the fragment in back stack but not on top of the stack, we can simply pop
+            // stack because current fragment transactions are arranged in an order
+            mFragmentManager.popBackStackImmediate();
+            return;
+        }
+        final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
+
+        fragmentTransaction.replace(
+                R.id.fragment_container,
+                fragment,
+                BluetoothBroadcastUtils.TAG_FRAGMENT_QR_CODE_SCANNER);
+        fragmentTransaction.commit();
+    }
+}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/qrcode/QrCodeScanModeBaseActivity.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/qrcode/QrCodeScanModeBaseActivity.java
new file mode 100644
index 0000000..637014a
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/qrcode/QrCodeScanModeBaseActivity.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023 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.connecteddevice.audiosharing.audiostreams.qrcode;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.SystemProperties;
+
+import androidx.fragment.app.FragmentManager;
+
+import com.android.settings.R;
+import com.android.settingslib.core.lifecycle.ObservableActivity;
+
+import com.google.android.setupdesign.util.ThemeHelper;
+import com.google.android.setupdesign.util.ThemeResolver;
+
+public abstract class QrCodeScanModeBaseActivity extends ObservableActivity {
+
+    private static final String THEME_KEY = "setupwizard.theme";
+    private static final String THEME_DEFAULT_VALUE = "SudThemeGlifV3_DayNight";
+    protected FragmentManager mFragmentManager;
+
+    protected abstract void handleIntent(Intent intent);
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        int defaultTheme =
+                ThemeHelper.isSetupWizardDayNightEnabled(this)
+                        ? com.google.android.setupdesign.R.style.SudThemeGlifV3_DayNight
+                        : com.google.android.setupdesign.R.style.SudThemeGlifV3_Light;
+        ThemeResolver themeResolver =
+                new ThemeResolver.Builder(ThemeResolver.getDefault())
+                        .setDefaultTheme(defaultTheme)
+                        .setUseDayNight(true)
+                        .build();
+        setTheme(
+                themeResolver.resolve(
+                        SystemProperties.get(THEME_KEY, THEME_DEFAULT_VALUE),
+                        /* suppressDayNight= */ !ThemeHelper.isSetupWizardDayNightEnabled(this)));
+
+        setContentView(R.layout.qrcode_scan_mode_activity);
+        mFragmentManager = getSupportFragmentManager();
+
+        if (savedInstanceState == null) {
+            handleIntent(getIntent());
+        }
+    }
+}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/qrcode/QrCodeScanModeFragment.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/qrcode/QrCodeScanModeFragment.java
new file mode 100644
index 0000000..2b52039
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/qrcode/QrCodeScanModeFragment.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2023 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.connecteddevice.audiosharing.audiostreams.qrcode;
+
+import android.app.Activity;
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Matrix;
+import android.graphics.Outline;
+import android.graphics.Rect;
+import android.graphics.SurfaceTexture;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
+import android.util.Log;
+import android.util.Size;
+import android.view.LayoutInflater;
+import android.view.TextureView;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewOutlineProvider;
+import android.view.accessibility.AccessibilityEvent;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.StringRes;
+
+import com.android.settings.R;
+import com.android.settings.core.InstrumentedFragment;
+import com.android.settingslib.bluetooth.BluetoothBroadcastUtils;
+import com.android.settingslib.bluetooth.BluetoothUtils;
+import com.android.settingslib.qrcode.QrCamera;
+
+import java.time.Duration;
+
+public class QrCodeScanModeFragment extends InstrumentedFragment
+        implements TextureView.SurfaceTextureListener, QrCamera.ScannerCallback {
+    private static final boolean DEBUG = BluetoothUtils.D;
+    private static final String TAG = "QrCodeScanModeFragment";
+
+    /** Message sent to hide error message */
+    private static final int MESSAGE_HIDE_ERROR_MESSAGE = 1;
+
+    /** Message sent to show error message */
+    private static final int MESSAGE_SHOW_ERROR_MESSAGE = 2;
+
+    /** Message sent to broadcast QR code */
+    private static final int MESSAGE_SCAN_BROADCAST_SUCCESS = 3;
+
+    private static final long SHOW_ERROR_MESSAGE_INTERVAL = 10000;
+    private static final long SHOW_SUCCESS_SQUARE_INTERVAL = 1000;
+
+    private static final Duration VIBRATE_DURATION_QR_CODE_RECOGNITION = Duration.ofMillis(3);
+
+    public static final String KEY_BROADCAST_METADATA = "key_broadcast_metadata";
+
+    private int mCornerRadius;
+    private String mBroadcastMetadata;
+    private Context mContext;
+    private QrCamera mCamera;
+    private TextureView mTextureView;
+    private TextView mSummary;
+    private TextView mErrorMessage;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mContext = getContext();
+    }
+
+    @Override
+    public final View onCreateView(
+            LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        return inflater.inflate(
+                R.layout.qrcode_scanner_fragment, container, /* attachToRoot */ false);
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        mTextureView = view.findViewById(R.id.preview_view);
+        mCornerRadius =
+                mContext.getResources().getDimensionPixelSize(R.dimen.qrcode_preview_radius);
+        mTextureView.setSurfaceTextureListener(this);
+        mTextureView.setOutlineProvider(
+                new ViewOutlineProvider() {
+                    @Override
+                    public void getOutline(View view, Outline outline) {
+                        outline.setRoundRect(
+                                0, 0, view.getWidth(), view.getHeight(), mCornerRadius);
+                    }
+                });
+        mTextureView.setClipToOutline(true);
+        mErrorMessage = view.findViewById(R.id.error_message);
+    }
+
+    private void initCamera(SurfaceTexture surface) {
+        // Check if the camera has already created.
+        if (mCamera == null) {
+            mCamera = new QrCamera(mContext, this);
+            mCamera.start(surface);
+        }
+    }
+
+    private void destroyCamera() {
+        if (mCamera != null) {
+            mCamera.stop();
+            mCamera = null;
+        }
+    }
+
+    @Override
+    public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surface, int width, int height) {
+        initCamera(surface);
+    }
+
+    @Override
+    public void onSurfaceTextureSizeChanged(
+            @NonNull SurfaceTexture surface, int width, int height) {}
+
+    @Override
+    public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {
+        destroyCamera();
+        return true;
+    }
+
+    @Override
+    public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {}
+
+    @Override
+    public void handleSuccessfulResult(String qrCode) {
+        if (DEBUG) {
+            Log.d(TAG, "handleSuccessfulResult(), get the qr code string.");
+        }
+        mBroadcastMetadata = qrCode;
+        handleBtLeAudioScanner();
+    }
+
+    @Override
+    public void handleCameraFailure() {
+        destroyCamera();
+    }
+
+    @Override
+    public Size getViewSize() {
+        return new Size(mTextureView.getWidth(), mTextureView.getHeight());
+    }
+
+    @Override
+    public Rect getFramePosition(Size previewSize, int cameraOrientation) {
+        return new Rect(0, 0, previewSize.getHeight(), previewSize.getHeight());
+    }
+
+    @Override
+    public void setTransform(Matrix transform) {
+        mTextureView.setTransform(transform);
+    }
+
+    @Override
+    public boolean isValid(String qrCode) {
+        if (qrCode.startsWith(BluetoothBroadcastUtils.SCHEME_BT_BROADCAST_METADATA)) {
+            return true;
+        } else {
+            showErrorMessage(R.string.bt_le_audio_qr_code_is_not_valid_format);
+            return false;
+        }
+    }
+
+    protected boolean isDecodeTaskAlive() {
+        return mCamera != null && mCamera.isDecodeTaskAlive();
+    }
+
+    private final Handler mHandler =
+            new Handler() {
+                @Override
+                public void handleMessage(Message msg) {
+                    switch (msg.what) {
+                        case MESSAGE_HIDE_ERROR_MESSAGE:
+                            mErrorMessage.setVisibility(View.INVISIBLE);
+                            break;
+
+                        case MESSAGE_SHOW_ERROR_MESSAGE:
+                            final String errorMessage = (String) msg.obj;
+
+                            mErrorMessage.setVisibility(View.VISIBLE);
+                            mErrorMessage.setText(errorMessage);
+                            mErrorMessage.sendAccessibilityEvent(
+                                    AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+
+                            // Cancel any pending messages to hide error view and requeue the
+                            // message so
+                            // user has time to see error
+                            removeMessages(MESSAGE_HIDE_ERROR_MESSAGE);
+                            sendEmptyMessageDelayed(
+                                    MESSAGE_HIDE_ERROR_MESSAGE, SHOW_ERROR_MESSAGE_INTERVAL);
+                            break;
+
+                        case MESSAGE_SCAN_BROADCAST_SUCCESS:
+                            Log.d(TAG, "scan success");
+                            final Intent resultIntent = new Intent();
+                            resultIntent.putExtra(KEY_BROADCAST_METADATA, mBroadcastMetadata);
+                            getActivity().setResult(Activity.RESULT_OK, resultIntent);
+                            notifyUserForQrCodeRecognition();
+                            break;
+                        default:
+                    }
+                }
+            };
+
+    private void notifyUserForQrCodeRecognition() {
+        if (mCamera != null) {
+            mCamera.stop();
+        }
+
+        mErrorMessage.setVisibility(View.INVISIBLE);
+
+        triggerVibrationForQrCodeRecognition(getContext());
+
+        getActivity().finish();
+    }
+
+    private static void triggerVibrationForQrCodeRecognition(Context context) {
+        Vibrator vibrator = context.getSystemService(Vibrator.class);
+        if (vibrator == null) {
+            return;
+        }
+        vibrator.vibrate(
+                VibrationEffect.createOneShot(
+                        VIBRATE_DURATION_QR_CODE_RECOGNITION.toMillis(),
+                        VibrationEffect.DEFAULT_AMPLITUDE));
+    }
+
+    private void showErrorMessage(@StringRes int messageResId) {
+        final Message message =
+                mHandler.obtainMessage(MESSAGE_SHOW_ERROR_MESSAGE, getString(messageResId));
+        message.sendToTarget();
+    }
+
+    private void handleBtLeAudioScanner() {
+        Message message = mHandler.obtainMessage(MESSAGE_SCAN_BROADCAST_SUCCESS);
+        mHandler.sendMessageDelayed(message, SHOW_SUCCESS_SQUARE_INTERVAL);
+    }
+
+    private void updateSummary() {
+        mSummary.setText(getString(R.string.bt_le_audio_scan_qr_code_scanner));
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.LE_AUDIO_BROADCAST_SCAN_QR_CODE;
+    }
+}
diff --git a/src/com/android/settings/development/featureflags/FeatureFlagPreference.java b/src/com/android/settings/development/featureflags/FeatureFlagPreference.java
index d6bdb77..baac047 100644
--- a/src/com/android/settings/development/featureflags/FeatureFlagPreference.java
+++ b/src/com/android/settings/development/featureflags/FeatureFlagPreference.java
@@ -19,9 +19,9 @@
 import android.content.Context;
 import android.util.FeatureFlagUtils;
 
-import androidx.preference.SwitchPreference;
+import androidx.preference.SwitchPreferenceCompat;
 
-public class FeatureFlagPreference extends SwitchPreference {
+public class FeatureFlagPreference extends SwitchPreferenceCompat {
 
     private final String mKey;
     private final boolean mIsPersistent;
diff --git a/src/com/android/settings/development/snooplogger/SnoopLoggerFiltersPreference.java b/src/com/android/settings/development/snooplogger/SnoopLoggerFiltersPreference.java
index f0c9ff4..7462e0d 100644
--- a/src/com/android/settings/development/snooplogger/SnoopLoggerFiltersPreference.java
+++ b/src/com/android/settings/development/snooplogger/SnoopLoggerFiltersPreference.java
@@ -19,12 +19,12 @@
 import android.content.Context;
 import android.os.SystemProperties;
 
-import androidx.preference.SwitchPreference;
+import androidx.preference.SwitchPreferenceCompat;
 
 /**
  * Bluetooth Snoop Logger Filters Preference
  */
-public class SnoopLoggerFiltersPreference extends SwitchPreference {
+public class SnoopLoggerFiltersPreference extends SwitchPreferenceCompat {
 
     private final String mKey;
     private static final String TAG = "SnoopLoggerFiltersPreference";
diff --git a/src/com/android/settings/fuelgauge/batteryusage/AnomalyEventWrapper.java b/src/com/android/settings/fuelgauge/batteryusage/AnomalyEventWrapper.java
index 13c8a91..8658fba 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/AnomalyEventWrapper.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/AnomalyEventWrapper.java
@@ -234,7 +234,7 @@
         }
         preference.setTitle(titleString);
         preference.setIconResourceId(getIconResId());
-        preference.setMainButtonStrokeColorResourceId(getColorResId());
+        preference.setButtonColorResourceId(getColorResId());
         preference.setMainButtonLabel(getMainBtnString());
         preference.setDismissButtonLabel(getDismissBtnString());
         return true;
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java
index ad5d420..6ff52a2 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java
@@ -378,7 +378,7 @@
         mTransomTop = resources.getDimensionPixelSize(R.dimen.chartview_transom_padding_top);
         mTransomLineDefaultColor = Utils.getDisabled(mContext, DIVIDER_COLOR);
         mTransomLineSelectedColor =
-                resources.getColor(R.color.color_battery_anomaly_yellow_selector);
+                resources.getColor(R.color.color_battery_anomaly_app_warning_selector);
         final int slotHighlightColor = Utils.getDisabled(mContext, mTransomLineSelectedColor);
         mTransomIconSize = resources.getDimensionPixelSize(R.dimen.chartview_transom_icon_size);
         mTransomLinePaint = new Paint();
@@ -419,11 +419,13 @@
 
     private void drawPercentage(Canvas canvas, int index, float offsetY) {
         if (mTextPaint != null) {
-            mTextPaint.setTextAlign(Paint.Align.RIGHT);
+            mTextPaint.setTextAlign(isRTL() ? Paint.Align.RIGHT : Paint.Align.LEFT);
             mTextPaint.setColor(mDefaultTextColor);
             canvas.drawText(
                     mPercentages[index],
-                    isRTL() ? mIndent.left - mTextPadding : getWidth(),
+                    isRTL()
+                            ? mIndent.left - mTextPadding
+                            : getWidth() - mIndent.width() + mTextPadding,
                     offsetY + mPercentageBounds[index].height() * .5f,
                     mTextPaint);
         }
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java
index 7eec816..bbd1099 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java
@@ -29,8 +29,6 @@
 import androidx.preference.PreferenceViewHolder;
 
 import com.android.settings.R;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import com.google.android.material.button.MaterialButton;
 
@@ -47,11 +45,10 @@
         void onReject();
     }
 
-    private final MetricsFeatureProvider mMetricsFeatureProvider;
     private OnConfirmListener mOnConfirmListener;
     private OnRejectListener mOnRejectListener;
     private int mIconResourceId = 0;
-    private int mMainButtonStrokeColorResourceId = 0;
+    private int mButtonColorResourceId = 0;
 
     @VisibleForTesting CharSequence mMainButtonLabel;
     @VisibleForTesting CharSequence mDismissButtonLabel;
@@ -59,9 +56,8 @@
     public BatteryTipsCardPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
         setLayoutResource(R.layout.battery_tips_card);
+        setViewId(R.id.battery_tips_card);
         setSelectable(false);
-        final FeatureFactory featureFactory = FeatureFactory.getFeatureFactory();
-        mMetricsFeatureProvider = featureFactory.getMetricsFeatureProvider();
     }
 
     public void setOnConfirmListener(OnConfirmListener listener) {
@@ -72,7 +68,9 @@
         mOnRejectListener = listener;
     }
 
-    /** Sets the icon in tips card. */
+    /**
+     * Sets the icon in tips card.
+     */
     public void setIconResourceId(int resourceId) {
         if (mIconResourceId != resourceId) {
             mIconResourceId = resourceId;
@@ -80,15 +78,19 @@
         }
     }
 
-    /** Sets the stroke color of main button in tips card. */
-    public void setMainButtonStrokeColorResourceId(int resourceId) {
-        if (mMainButtonStrokeColorResourceId != resourceId) {
-            mMainButtonStrokeColorResourceId = resourceId;
+    /**
+     * Sets the background color for main button and the text color for dismiss button.
+     */
+    public void setButtonColorResourceId(int resourceId) {
+        if (mButtonColorResourceId != resourceId) {
+            mButtonColorResourceId = resourceId;
             notifyChanged();
         }
     }
 
-    /** Sets the label of main button in tips card. */
+    /**
+     * Sets the label of main button in tips card.
+     */
     public void setMainButtonLabel(CharSequence label) {
         if (!TextUtils.equals(mMainButtonLabel, label)) {
             mMainButtonLabel = label;
@@ -96,7 +98,9 @@
         }
     }
 
-    /** Sets the label of dismiss button in tips card. */
+    /**
+     * Sets the label of dismiss button in tips card.
+     */
     public void setDismissButtonLabel(CharSequence label) {
         if (!TextUtils.equals(mDismissButtonLabel, label)) {
             mDismissButtonLabel = label;
@@ -107,7 +111,7 @@
     @Override
     public void onClick(View view) {
         final int viewId = view.getId();
-        if (viewId == R.id.main_button || viewId == R.id.tips_card) {
+        if (viewId == R.id.main_button || viewId == R.id.battery_tips_card) {
             if (mOnConfirmListener != null) {
                 mOnConfirmListener.onConfirm();
             }
@@ -124,17 +128,21 @@
 
         ((TextView) view.findViewById(R.id.title)).setText(getTitle());
 
-        LinearLayout tipsCard = (LinearLayout) view.findViewById(R.id.tips_card);
+        final LinearLayout tipsCard = (LinearLayout) view.findViewById(R.id.battery_tips_card);
         tipsCard.setOnClickListener(this);
-        MaterialButton mainButton = (MaterialButton) view.findViewById(R.id.main_button);
+        final MaterialButton mainButton = (MaterialButton) view.findViewById(R.id.main_button);
         mainButton.setOnClickListener(this);
         mainButton.setText(mMainButtonLabel);
-        if (mMainButtonStrokeColorResourceId != 0) {
-            mainButton.setStrokeColorResource(mMainButtonStrokeColorResourceId);
-        }
-        MaterialButton dismissButton = (MaterialButton) view.findViewById(R.id.dismiss_button);
+        final MaterialButton dismissButton =
+                (MaterialButton) view.findViewById(R.id.dismiss_button);
         dismissButton.setOnClickListener(this);
         dismissButton.setText(mDismissButtonLabel);
+        if (mButtonColorResourceId != 0) {
+            final int colorInt = getContext().getColor(mButtonColorResourceId);
+            mainButton.setBackgroundColor(colorInt);
+            dismissButton.setTextColor(colorInt);
+        }
+
         if (mIconResourceId != 0) {
             ((ImageView) view.findViewById(R.id.icon)).setImageResource(mIconResourceId);
         }
diff --git a/src/com/android/settings/privatespace/CreatePrivateSpaceController.java b/src/com/android/settings/privatespace/CreatePrivateSpaceController.java
deleted file mode 100644
index 3214988..0000000
--- a/src/com/android/settings/privatespace/CreatePrivateSpaceController.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2023 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.privatespace;
-
-import android.content.Context;
-import android.text.TextUtils;
-import android.widget.Toast;
-
-import androidx.preference.Preference;
-
-import com.android.settings.R;
-import com.android.settings.core.BasePreferenceController;
-
-// TODO(b/293569406): Remove this when we have the setup flow in place to create PS
-/**
- * Temp Controller to create the private space from the PS Settings page. This is to allow PM, UX,
- * and other folks to play around with PS before the PS setup flow is ready.
- */
-public final class CreatePrivateSpaceController extends BasePreferenceController {
-
-    public CreatePrivateSpaceController(Context context, String preferenceKey) {
-        super(context, preferenceKey);
-    }
-
-    @Override
-    public int getAvailabilityStatus() {
-        return AVAILABLE;
-    }
-
-    @Override
-    public boolean handlePreferenceTreeClick(Preference preference) {
-        if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
-            return false;
-        }
-
-        if (PrivateSpaceMaintainer.getInstance(mContext).doesPrivateSpaceExist()) {
-            showPrivateSpaceAlreadyExistsToast();
-            return super.handlePreferenceTreeClick(preference);
-        }
-
-        if (PrivateSpaceMaintainer.getInstance(mContext).createPrivateSpace()) {
-            showPrivateSpaceCreatedToast();
-        } else {
-            showPrivateSpaceCreationFailedToast();
-        }
-        return super.handlePreferenceTreeClick(preference);
-    }
-
-    private void showPrivateSpaceCreatedToast() {
-        Toast.makeText(mContext, R.string.private_space_created, Toast.LENGTH_SHORT).show();
-    }
-
-    private void showPrivateSpaceCreationFailedToast() {
-        Toast.makeText(mContext, R.string.private_space_create_failed, Toast.LENGTH_SHORT).show();
-    }
-
-    private void showPrivateSpaceAlreadyExistsToast() {
-        Toast.makeText(mContext, R.string.private_space_already_exists, Toast.LENGTH_SHORT).show();
-    }
-}
diff --git a/src/com/android/settings/privatespace/PrivateSpaceDashboardFragment.java b/src/com/android/settings/privatespace/PrivateSpaceDashboardFragment.java
index f72bcd9..5d00329 100644
--- a/src/com/android/settings/privatespace/PrivateSpaceDashboardFragment.java
+++ b/src/com/android/settings/privatespace/PrivateSpaceDashboardFragment.java
@@ -17,25 +17,13 @@
 package com.android.settings.privatespace;
 
 import android.app.settings.SettingsEnums;
-import android.content.Context;
-import android.os.Flags;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
-import com.android.settings.safetycenter.SafetyCenterManagerWrapper;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.SearchIndexable;
-
-import java.util.List;
 
 /** Fragment representing the Private Space dashboard in Settings. */
-@SearchIndexable
 public class PrivateSpaceDashboardFragment extends DashboardFragment {
     private static final String TAG = "PrivateSpaceDashboardFragment";
-    private static final String KEY_CREATE_PROFILE_PREFERENCE = "private_space_create";
-    private static final String KEY_DELETE_PROFILE_PREFERENCE = "private_space_delete";
-    private static final String KEY_ONE_LOCK_PREFERENCE = "private_space_use_one_lock";
-    private static final String KEY_PS_HIDDEN_PREFERENCE = "private_space_hidden";
 
     @Override
     protected int getPreferenceScreenResId() {
@@ -51,23 +39,4 @@
     protected String getLogTag() {
         return TAG;
     }
-
-    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider(R.xml.private_space_settings) {
-                @Override
-                protected boolean isPageSearchEnabled(Context context) {
-                    return SafetyCenterManagerWrapper.get().isEnabled(context)
-                            && Flags.allowPrivateProfile();
-                }
-
-                @Override
-                public List<String> getNonIndexableKeys(Context context) {
-                    List<String> keys = super.getNonIndexableKeys(context);
-                    keys.add(KEY_CREATE_PROFILE_PREFERENCE);
-                    keys.add(KEY_DELETE_PROFILE_PREFERENCE);
-                    keys.add(KEY_ONE_LOCK_PREFERENCE);
-                    keys.add(KEY_PS_HIDDEN_PREFERENCE);
-                    return keys;
-                }
-            };
 }
diff --git a/src/com/android/settings/privatespace/UseOneLockController.java b/src/com/android/settings/privatespace/UseOneLockController.java
deleted file mode 100644
index a94db57..0000000
--- a/src/com/android/settings/privatespace/UseOneLockController.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2023 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.privatespace;
-
-import android.content.Context;
-
-import com.android.settings.core.TogglePreferenceController;
-
-/** Represents the preference controller for using the same lock as the screen lock */
-public class UseOneLockController extends TogglePreferenceController {
-    public UseOneLockController(Context context, String preferenceKey) {
-        super(context, preferenceKey);
-    }
-
-    @Override
-    public int getAvailabilityStatus() {
-        return AVAILABLE;
-    }
-
-    @Override
-    public boolean isChecked() {
-        // TODO(b/293569406) Need to save this to a persistent store, maybe like SettingsProvider
-        return false;
-    }
-
-    @Override
-    public boolean setChecked(boolean isChecked) {
-        // TODO(b/293569406) Need to save this to a persistent store, maybe like SettingsProvider
-        return true;
-    }
-
-    @Override
-    public int getSliceHighlightMenuRes() {
-        return 0;
-    }
-}
diff --git a/src/com/android/settings/privatespace/onelock/FaceFingerprintUnlockController.java b/src/com/android/settings/privatespace/onelock/FaceFingerprintUnlockController.java
new file mode 100644
index 0000000..e976261
--- /dev/null
+++ b/src/com/android/settings/privatespace/onelock/FaceFingerprintUnlockController.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2023 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.privatespace.onelock;
+
+import android.content.Context;
+import android.text.TextUtils;
+
+import androidx.preference.Preference;
+
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+/** Represents the preference controller to enroll biometrics for private space lock. */
+public class FaceFingerprintUnlockController extends AbstractPreferenceController {
+    private static final String KEY_SET_UNSET_FACE_FINGERPRINT = "private_space_biometrics";
+
+    public FaceFingerprintUnlockController(Context context, SettingsPreferenceFragment host) {
+        super(context);
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return false;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_SET_UNSET_FACE_FINGERPRINT;
+    }
+
+    @Override
+    public boolean handlePreferenceTreeClick(Preference preference) {
+        return TextUtils.equals(preference.getKey(), getPreferenceKey());
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        //TODO(b/308862923) : Add condition to check and enable when separate private lock is set.
+        preference.setSummary(mContext.getString(R.string.lock_settings_profile_unified_summary));
+        preference.setEnabled(false);
+    }
+}
diff --git a/src/com/android/settings/privatespace/onelock/PrivateSpaceLockController.java b/src/com/android/settings/privatespace/onelock/PrivateSpaceLockController.java
new file mode 100644
index 0000000..2783c1c
--- /dev/null
+++ b/src/com/android/settings/privatespace/onelock/PrivateSpaceLockController.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2023 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.privatespace.onelock;
+
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN;
+import static com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.preference.Preference;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.Utils;
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.password.ChooseLockGeneric;
+import com.android.settings.privatespace.PrivateSpaceMaintainer;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.transition.SettingsTransitionHelper;
+
+
+/** Represents the preference controller for changing private space lock. */
+public class PrivateSpaceLockController extends AbstractPreferenceController {
+    private static final String TAG = "PrivateSpaceLockContr";
+    private static final String KEY_CHANGE_PROFILE_LOCK =
+            "change_private_space_lock";
+
+    private final SettingsPreferenceFragment mHost;
+    private final UserManager mUserManager;
+    private final LockPatternUtils mLockPatternUtils;
+    private final int mProfileUserId;
+
+    public PrivateSpaceLockController(Context context, SettingsPreferenceFragment host) {
+        super(context);
+        mUserManager = context.getSystemService(UserManager.class);
+        mLockPatternUtils = FeatureFactory.getFeatureFactory()
+                .getSecurityFeatureProvider()
+                .getLockPatternUtils(context);
+        mHost = host;
+        UserHandle privateProfileHandle = PrivateSpaceMaintainer.getInstance(context)
+                .getPrivateProfileHandle();
+        if (privateProfileHandle != null) {
+            mProfileUserId = privateProfileHandle.getIdentifier();
+        } else {
+            mProfileUserId = -1;
+            Log.e(TAG, "Private profile user handle is not expected to be null.");
+        }
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return true;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_CHANGE_PROFILE_LOCK;
+    }
+
+    @Override
+    public boolean handlePreferenceTreeClick(Preference preference) {
+        if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
+            return false;
+        }
+        //Checks if the profile is in quiet mode and show a dialog to unpause the profile.
+        if (Utils.startQuietModeDialogIfNecessary(mContext, mUserManager,
+                mProfileUserId)) {
+            return false;
+        }
+        final Bundle extras = new Bundle();
+        extras.putInt(Intent.EXTRA_USER_ID, mProfileUserId);
+        extras.putBoolean(HIDE_INSECURE_OPTIONS, true);
+        new SubSettingLauncher(mContext)
+                .setDestination(ChooseLockGeneric.ChooseLockGenericFragment.class.getName())
+                .setSourceMetricsCategory(mHost.getMetricsCategory())
+                .setArguments(extras)
+                .setExtras(extras)
+                .setTransitionType(SettingsTransitionHelper.TransitionType.TRANSITION_SLIDE)
+                .launch();
+        return true;
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        if (mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileUserId)) {
+            preference.setSummary(
+                    mContext.getString(getCredentialTypeResId(mProfileUserId)));
+            preference.setEnabled(true);
+        } else {
+            preference.setSummary(mContext.getString(
+                    R.string.lock_settings_profile_unified_summary));
+            preference.setEnabled(false);
+        }
+    }
+
+    private int getCredentialTypeResId(int userId) {
+        int credentialType = mLockPatternUtils.getCredentialTypeForUser(userId);
+        switch (credentialType) {
+            case CREDENTIAL_TYPE_PATTERN :
+                return R.string.unlock_set_unlock_mode_pattern;
+            case CREDENTIAL_TYPE_PIN:
+                return R.string.unlock_set_unlock_mode_pin;
+            case CREDENTIAL_TYPE_PASSWORD:
+                return R.string.unlock_set_unlock_mode_password;
+            default:
+                // This is returned for CREDENTIAL_TYPE_NONE
+                return R.string.unlock_set_unlock_mode_off;
+        }
+    }
+}
diff --git a/src/com/android/settings/privatespace/onelock/UseOneLockController.java b/src/com/android/settings/privatespace/onelock/UseOneLockController.java
new file mode 100644
index 0000000..5c461e0
--- /dev/null
+++ b/src/com/android/settings/privatespace/onelock/UseOneLockController.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2023 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.privatespace.onelock;
+
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN;
+
+import android.content.Context;
+import android.os.UserHandle;
+import android.util.Log;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.privatespace.PrivateSpaceMaintainer;
+
+/** Represents the preference controller for using the same lock as the screen lock */
+public class UseOneLockController extends BasePreferenceController {
+    private static final String TAG = "UseOneLockController";
+    private final LockPatternUtils mLockPatternUtils;
+    private final PrivateSpaceMaintainer mPrivateSpaceMaintainer;
+
+    public UseOneLockController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+        mPrivateSpaceMaintainer = PrivateSpaceMaintainer.getInstance(mContext);
+        mLockPatternUtils = FeatureFactory.getFeatureFactory()
+                .getSecurityFeatureProvider()
+                .getLockPatternUtils(context);
+    }
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+
+    @Override
+    public int getSliceHighlightMenuRes() {
+        return 0;
+    }
+
+    @Override
+    public CharSequence getSummary() {
+        UserHandle privateProfileHandle = mPrivateSpaceMaintainer.getPrivateProfileHandle();
+        if (privateProfileHandle != null) {
+            int privateUserId = privateProfileHandle.getIdentifier();
+            if (mLockPatternUtils.isSeparateProfileChallengeEnabled(privateUserId)) {
+                return mContext.getString(getCredentialTypeResId(privateUserId));
+            }
+        } else {
+            Log.w(TAG, "Did not find Private Space.");
+        }
+        return mContext.getString(R.string.private_space_screen_lock_summary);
+    }
+
+    private int getCredentialTypeResId(int userId) {
+        int credentialType = mLockPatternUtils.getCredentialTypeForUser(userId);
+        switch (credentialType) {
+            case CREDENTIAL_TYPE_PATTERN:
+                return R.string.unlock_set_unlock_mode_pattern;
+            case CREDENTIAL_TYPE_PIN:
+                return R.string.unlock_set_unlock_mode_pin;
+            case CREDENTIAL_TYPE_PASSWORD:
+                return R.string.unlock_set_unlock_mode_password;
+            default:
+                // This is returned for CREDENTIAL_TYPE_NONE
+                return R.string.unlock_set_unlock_mode_off;
+        }
+    }
+}
diff --git a/src/com/android/settings/privatespace/onelock/UseOneLockControllerSwitch.java b/src/com/android/settings/privatespace/onelock/UseOneLockControllerSwitch.java
new file mode 100644
index 0000000..218b870
--- /dev/null
+++ b/src/com/android/settings/privatespace/onelock/UseOneLockControllerSwitch.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2023 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.privatespace.onelock;
+
+import static com.android.settings.privatespace.PrivateSpaceSetupActivity.EXTRA_ACTION_TYPE;
+import static com.android.settings.privatespace.PrivateSpaceSetupActivity.SET_LOCK_ACTION;
+import static com.android.settings.privatespace.onelock.UseOneLockSettingsFragment.UNIFY_PRIVATE_LOCK_WITH_DEVICE_REQUEST;
+import static com.android.settings.privatespace.onelock.UseOneLockSettingsFragment.UNUNIFY_PRIVATE_LOCK_FROM_DEVICE_REQUEST;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Log;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockscreenCredential;
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.Utils;
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.password.ChooseLockGeneric;
+import com.android.settings.password.ChooseLockSettingsHelper;
+import com.android.settings.privatespace.PrivateProfileContextHelperActivity;
+import com.android.settings.privatespace.PrivateSpaceMaintainer;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.transition.SettingsTransitionHelper;
+import com.android.settingslib.widget.MainSwitchPreference;
+
+/** Represents the preference controller for using the same lock as the screen lock */
+public class UseOneLockControllerSwitch extends AbstractPreferenceController
+        implements Preference.OnPreferenceChangeListener {
+    private static final String TAG = "UseOneLockSwitch";
+    private static final String KEY_UNIFICATION = "private_lock_unification";
+    private final String mPreferenceKey;
+    private final SettingsPreferenceFragment mHost;
+    private final LockPatternUtils mLockPatternUtils;
+    private final UserManager mUserManager;
+    private final int mProfileUserId;
+    private final UserHandle mUserHandle;
+    private LockscreenCredential mCurrentDevicePassword;
+    private LockscreenCredential mCurrentProfilePassword;
+    private MainSwitchPreference mUnifyProfile;
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mUnifyProfile = screen.findPreference(mPreferenceKey);
+    }
+    public UseOneLockControllerSwitch(Context context, SettingsPreferenceFragment host) {
+        this(context, host, KEY_UNIFICATION);
+    }
+
+    public UseOneLockControllerSwitch(Context context, SettingsPreferenceFragment host,
+              String key) {
+        super(context);
+        mHost = host;
+        mUserManager = context.getSystemService(UserManager.class);
+        mLockPatternUtils = FeatureFactory.getFeatureFactory().getSecurityFeatureProvider()
+                  .getLockPatternUtils(context);
+        mUserHandle =  PrivateSpaceMaintainer.getInstance(context).getPrivateProfileHandle();
+        mProfileUserId = mUserHandle != null ? mUserHandle.getIdentifier() : -1;
+        mCurrentDevicePassword = LockscreenCredential.createNone();
+        mCurrentProfilePassword = LockscreenCredential.createNone();
+        this.mPreferenceKey = key;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return mPreferenceKey;
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return true;
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object value) {
+        //Checks if the profile is in quiet mode and show a dialog to unpause the profile.
+        if (Utils.startQuietModeDialogIfNecessary(mContext, mUserManager, mProfileUserId)) {
+            return false;
+        }
+        final boolean useOneLock = (Boolean) value;
+        if (useOneLock) {
+            startUnification();
+        } else {
+            showAlertDialog();
+        }
+        return true;
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        if (mUnifyProfile != null) {
+            final boolean separate =
+                      mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileUserId);
+            mUnifyProfile.setChecked(!separate);
+        }
+    }
+
+    /** Method to handle onActivityResult */
+    public boolean handleActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == UNUNIFY_PRIVATE_LOCK_FROM_DEVICE_REQUEST
+                  && resultCode == Activity.RESULT_OK) {
+            mCurrentDevicePassword =
+                      data.getParcelableExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
+            separateLocks();
+            return true;
+        } else if (requestCode == UNIFY_PRIVATE_LOCK_WITH_DEVICE_REQUEST
+                  && resultCode == Activity.RESULT_OK) {
+            mCurrentProfilePassword =
+                      data.getParcelableExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
+            unifyLocks();
+            return true;
+        }
+        return false;
+    }
+
+    private void separateLocks() {
+        final Bundle extras = new Bundle();
+        extras.putInt(Intent.EXTRA_USER_ID, mProfileUserId);
+        extras.putParcelable(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, mCurrentDevicePassword);
+        new SubSettingLauncher(mContext)
+                  .setDestination(ChooseLockGeneric.ChooseLockGenericFragment.class.getName())
+                  .setSourceMetricsCategory(mHost.getMetricsCategory())
+                  .setArguments(extras)
+                  .setTransitionType(SettingsTransitionHelper.TransitionType.TRANSITION_SLIDE)
+                  .launch();
+    }
+
+    /** Unify primary and profile locks. */
+    public void startUnification() {
+        // Confirm profile lock
+        final ChooseLockSettingsHelper.Builder builder =
+                  new ChooseLockSettingsHelper.Builder(mHost.getActivity(), mHost);
+        final boolean launched = builder.setRequestCode(UNIFY_PRIVATE_LOCK_WITH_DEVICE_REQUEST)
+                  .setReturnCredentials(true)
+                  .setUserId(mProfileUserId)
+                  .show();
+        if (!launched) {
+            // If profile has no lock, go straight to unification.
+            unifyLocks();
+        }
+    }
+
+    private void unifyLocks() {
+        unifyKeepingDeviceLock();
+        if (mCurrentDevicePassword != null) {
+            mCurrentDevicePassword.zeroize();
+            mCurrentDevicePassword = null;
+        }
+        if (mCurrentProfilePassword != null) {
+            mCurrentProfilePassword.zeroize();
+            mCurrentProfilePassword = null;
+        }
+    }
+
+    private void unifyKeepingDeviceLock() {
+        mLockPatternUtils.setSeparateProfileChallengeEnabled(mProfileUserId, false,
+                  mCurrentProfilePassword);
+    }
+
+    private void showAlertDialog() {
+        if (mUserHandle == null) {
+            Log.e(TAG, "Private profile user handle is not expected to be null");
+            mUnifyProfile.setChecked(true);
+            return;
+        }
+        new AlertDialog.Builder(mContext)
+                  .setMessage(R.string.private_space_new_lock_title)
+                  .setPositiveButton(
+                            R.string.privatespace_set_lock_label,
+                            (dialog, which) -> {
+                                Intent intent = new Intent(mContext,
+                                          PrivateProfileContextHelperActivity.class);
+                                intent.putExtra(EXTRA_ACTION_TYPE, SET_LOCK_ACTION);
+                                ((Activity) mContext).startActivityForResultAsUser(intent,
+                                          UNUNIFY_PRIVATE_LOCK_FROM_DEVICE_REQUEST,
+                                          /*Options*/ null, mUserHandle);
+                            })
+                  .setNegativeButton(R.string.privatespace_cancel_label,
+                            (DialogInterface dialog, int which) -> {
+                                mUnifyProfile.setChecked(true);
+                                dialog.dismiss();
+                            })
+                  .setOnCancelListener(
+                            (DialogInterface dialog) -> {
+                                mUnifyProfile.setChecked(true);
+                                dialog.dismiss();
+                            })
+                  .show();
+    }
+}
diff --git a/src/com/android/settings/privatespace/onelock/UseOneLockSettingsFragment.java b/src/com/android/settings/privatespace/onelock/UseOneLockSettingsFragment.java
new file mode 100644
index 0000000..36f8448
--- /dev/null
+++ b/src/com/android/settings/privatespace/onelock/UseOneLockSettingsFragment.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2023 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.privatespace.onelock;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.content.Intent;
+
+import androidx.annotation.Nullable;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class UseOneLockSettingsFragment extends DashboardFragment {
+    private static final String TAG = "UseOneLockSettings";
+    public static final int UNIFY_PRIVATE_LOCK_WITH_DEVICE_REQUEST = 1;
+    public static final int UNUNIFY_PRIVATE_LOCK_FROM_DEVICE_REQUEST = 2;
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.PRIVATE_SPACE_SETTINGS;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.privatespace_one_lock;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    @Override
+    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+        final List<AbstractPreferenceController> controllers = new ArrayList<>();
+        controllers.add(new UseOneLockControllerSwitch(context, this));
+        controllers.add(new PrivateSpaceLockController(context, this));
+        controllers.add(new FaceFingerprintUnlockController(context, this));
+        return controllers;
+    }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
+        if (use(UseOneLockControllerSwitch.class)
+                  .handleActivityResult(requestCode, resultCode, data)) {
+            return;
+        }
+        super.onActivityResult(requestCode, resultCode, data);
+    }
+}
diff --git a/src/com/android/settings/security/ContentProtectionTogglePreferenceController.java b/src/com/android/settings/security/ContentProtectionTogglePreferenceController.java
index b656093..c874a5e 100644
--- a/src/com/android/settings/security/ContentProtectionTogglePreferenceController.java
+++ b/src/com/android/settings/security/ContentProtectionTogglePreferenceController.java
@@ -62,7 +62,6 @@
 
     @Override
     public boolean setChecked(boolean isChecked) {
-        mSwitchBar.setChecked(isChecked);
         Settings.Global.putInt(
                 mContentResolver, KEY_CONTENT_PROTECTION_PREFERENCE, isChecked ? 1 : -1);
         return true;
diff --git a/src/com/android/settings/slices/VolumeSliceHelper.java b/src/com/android/settings/slices/VolumeSliceHelper.java
index 1ba1778..8947cc4 100644
--- a/src/com/android/settings/slices/VolumeSliceHelper.java
+++ b/src/com/android/settings/slices/VolumeSliceHelper.java
@@ -24,7 +24,6 @@
 import android.content.IntentFilter;
 import android.media.AudioManager;
 import android.net.Uri;
-import android.util.ArrayMap;
 import android.util.Log;
 
 import androidx.annotation.VisibleForTesting;
@@ -32,6 +31,7 @@
 import com.android.settingslib.SliceBroadcastRelay;
 
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * This helper is to handle the broadcasts of volume slices
@@ -41,7 +41,7 @@
     private static final String TAG = "VolumeSliceHelper";
 
     @VisibleForTesting
-    static Map<Uri, Integer> sRegisteredUri = new ArrayMap<>();
+    static Map<Uri, Integer> sRegisteredUri = new ConcurrentHashMap<>();
     @VisibleForTesting
     static IntentFilter sIntentFilter;
 
@@ -133,23 +133,19 @@
     }
 
     private static void handleStreamChanged(Context context, int inputType) {
-        synchronized (sRegisteredUri) {
-            for (Map.Entry<Uri, Integer> entry : sRegisteredUri.entrySet()) {
-                if (entry.getValue() == inputType) {
-                    context.getContentResolver().notifyChange(entry.getKey(), null /* observer */);
-                    if (inputType != AudioManager.STREAM_RING) { // Two URIs are mapped to ring
-                        break;
-                    }
+        for (Map.Entry<Uri, Integer> entry : sRegisteredUri.entrySet()) {
+            if (entry.getValue() == inputType) {
+                context.getContentResolver().notifyChange(entry.getKey(), null /* observer */);
+                if (inputType != AudioManager.STREAM_RING) { // Two URIs are mapped to ring
+                    break;
                 }
             }
         }
     }
 
     private static void notifyAllStreamsChanged(Context context) {
-        synchronized (sRegisteredUri) {
-            sRegisteredUri.forEach((uri, audioStream) -> {
-                context.getContentResolver().notifyChange(uri, null /* observer */);
-            });
-        }
+        sRegisteredUri.keySet().forEach(uri -> {
+            context.getContentResolver().notifyChange(uri, null /* observer */);
+        });
     }
 }
diff --git a/src/com/android/settings/spa/SettingsSpaEnvironment.kt b/src/com/android/settings/spa/SettingsSpaEnvironment.kt
index 6b96460..7ab836b 100644
--- a/src/com/android/settings/spa/SettingsSpaEnvironment.kt
+++ b/src/com/android/settings/spa/SettingsSpaEnvironment.kt
@@ -82,35 +82,41 @@
             allProviders = getTogglePermissionAppListProviders()
         )
         SettingsPageProviderRepository(
-            allPageProviders = listOf(
-                HomePageProvider,
-                AppsMainPageProvider,
-                AllAppListPageProvider,
-                AppInfoSettingsProvider,
-                SpecialAppAccessPageProvider,
-                NotificationMainPageProvider,
-                AppListNotificationsPageProvider,
-                SystemMainPageProvider,
-                LanguageAndInputPageProvider,
-                AppLanguagesPageProvider,
-                UsageStatsPageProvider,
-                PlatformCompatAppListPageProvider,
-                BackgroundInstalledAppsPageProvider,
-                UserAspectRatioAppsPageProvider,
-                CloneAppInfoSettingsProvider,
-                NetworkAndInternetPageProvider,
-                AboutPhonePageProvider,
-                StorageAppListPageProvider.Apps,
-                StorageAppListPageProvider.Games,
-                ApnEditPageProvider,
-                ) + togglePermissionAppListTemplate.createPageProviders(),
+            allPageProviders = settingsPageProviders()
+                + togglePermissionAppListTemplate.createPageProviders(),
             rootPages = listOf(
                 HomePageProvider.createSettingsPage()
             ),
         )
     }
-    override val logger =
-        if (FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_ENABLE_SPA_METRICS))
-            SpaLogProvider
-        else object : SpaLogger {}
+
+
+    open fun settingsPageProviders() = listOf(
+        HomePageProvider,
+        AppsMainPageProvider,
+        AllAppListPageProvider,
+        AppInfoSettingsProvider,
+        SpecialAppAccessPageProvider,
+        NotificationMainPageProvider,
+        AppListNotificationsPageProvider,
+        SystemMainPageProvider,
+        LanguageAndInputPageProvider,
+        AppLanguagesPageProvider,
+        UsageStatsPageProvider,
+        PlatformCompatAppListPageProvider,
+        BackgroundInstalledAppsPageProvider,
+        UserAspectRatioAppsPageProvider,
+        CloneAppInfoSettingsProvider,
+        NetworkAndInternetPageProvider,
+        AboutPhonePageProvider,
+        StorageAppListPageProvider.Apps,
+        StorageAppListPageProvider.Games,
+        ApnEditPageProvider,
+    )
+
+    override val logger = if (FeatureFlagUtils.isEnabled(
+            context, FeatureFlagUtils.SETTINGS_ENABLE_SPA_METRICS
+        )
+    ) SpaLogProvider
+    else object : SpaLogger {}
 }
diff --git a/src/com/android/settings/vpn2/ConfigDialogFragment.java b/src/com/android/settings/vpn2/ConfigDialogFragment.java
index b8825fe..e38f92a 100644
--- a/src/com/android/settings/vpn2/ConfigDialogFragment.java
+++ b/src/com/android/settings/vpn2/ConfigDialogFragment.java
@@ -207,6 +207,10 @@
                 mService.startLegacyVpn(profile);
             } catch (IllegalStateException e) {
                 Toast.makeText(mContext, R.string.vpn_no_network, Toast.LENGTH_LONG).show();
+            } catch (UnsupportedOperationException e) {
+                Log.e(TAG, "Attempted to start an unsupported VPN type.");
+                Toast.makeText(mContext, R.string.vpn_insecure_dialog_subtitle, Toast.LENGTH_LONG)
+                        .show();
             }
         }
     }
diff --git a/src/com/android/settings/wfd/WifiDisplaySettings.java b/src/com/android/settings/wfd/WifiDisplaySettings.java
index 96f067c..2ec69c4 100644
--- a/src/com/android/settings/wfd/WifiDisplaySettings.java
+++ b/src/com/android/settings/wfd/WifiDisplaySettings.java
@@ -140,7 +140,6 @@
         mWifiP2pChannel = mWifiP2pManager.initialize(context, Looper.getMainLooper(), null);
 
         addPreferencesFromResource(R.xml.wifi_display_settings);
-        setHasOptionsMenu(true);
     }
 
     @Override
@@ -197,8 +196,9 @@
 
     @Override
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        if (mWifiDisplayStatus != null && mWifiDisplayStatus.getFeatureState()
-                != WifiDisplayStatus.FEATURE_STATE_UNAVAILABLE) {
+        if (getResources().getBoolean(R.bool.config_show_wifi_display_enable_menu)
+                && mWifiDisplayStatus != null && mWifiDisplayStatus.getFeatureState()
+                        != WifiDisplayStatus.FEATURE_STATE_UNAVAILABLE) {
             MenuItem item = menu.add(Menu.NONE, MENU_ID_ENABLE_WIFI_DISPLAY, 0,
                     R.string.wifi_display_enable_menu_item);
             item.setCheckable(true);
diff --git a/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java b/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java
index 5ab8807..faa0c3b 100644
--- a/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java
+++ b/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java
@@ -59,7 +59,6 @@
 import androidx.annotation.VisibleForTesting;
 import androidx.core.text.BidiFormatter;
 import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
 import androidx.preference.PreferenceFragmentCompat;
 import androidx.preference.PreferenceScreen;
 import androidx.recyclerview.widget.RecyclerView;
@@ -184,7 +183,6 @@
     private Preference mSubnetPref;
     private Preference mDnsPref;
     private Preference mTypePref;
-    private PreferenceCategory mIpv6Category;
     private Preference mIpv6AddressPref;
     private final IconInjector mIconInjector;
     private final Clock mClock;
@@ -376,8 +374,6 @@
         mSubnetPref = screen.findPreference(KEY_SUBNET_MASK_PREF);
         mDnsPref = screen.findPreference(KEY_DNS_PREF);
         mTypePref = screen.findPreference(KEY_WIFI_TYPE_PREF);
-
-        mIpv6Category = screen.findPreference(KEY_IPV6_CATEGORY);
         mIpv6AddressPref = screen.findPreference(KEY_IPV6_ADDRESSES_PREF);
     }
 
@@ -824,7 +820,7 @@
             mSubnetPref.setVisible(false);
             mGatewayPref.setVisible(false);
             mDnsPref.setVisible(false);
-            mIpv6Category.setVisible(false);
+            mIpv6AddressPref.setVisible(false);
             return;
         }
 
@@ -864,11 +860,11 @@
         updatePreference(mDnsPref, dnsServers);
 
         if (ipv6Addresses.length() > 0) {
+            mIpv6AddressPref.setVisible(true);
             mIpv6AddressPref.setSummary(
                     BidiFormatter.getInstance().unicodeWrap(ipv6Addresses.toString()));
-            mIpv6Category.setVisible(true);
         } else {
-            mIpv6Category.setVisible(false);
+            mIpv6AddressPref.setVisible(false);
         }
     }
 
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityDetailsSettingsFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityDetailsSettingsFragmentTest.java
index 995d74f..c105d08 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityDetailsSettingsFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityDetailsSettingsFragmentTest.java
@@ -32,7 +32,6 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
-import android.util.FeatureFlagUtils;
 import android.view.accessibility.AccessibilityManager;
 
 import androidx.test.core.app.ApplicationProvider;
@@ -158,8 +157,6 @@
 
     @Test
     public void onCreate_hearingAidsComponentName_launchAccessibilityHearingAidsFragment() {
-        FeatureFlagUtils.setEnabled(mContext,
-                FeatureFlagUtils.SETTINGS_ACCESSIBILITY_HEARING_AID_PAGE, true);
         Intent intent = new Intent();
         intent.putExtra(Intent.EXTRA_COMPONENT_NAME,
                 ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString());
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java
index 3333782..bb15378 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java
@@ -18,11 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.robolectric.Shadows.shadowOf;
 
@@ -35,7 +31,6 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
-import android.util.FeatureFlagUtils;
 
 import androidx.preference.Preference;
 import androidx.test.core.app.ApplicationProvider;
@@ -111,8 +106,6 @@
 
     @Before
     public void setUp() {
-        FeatureFlagUtils.setEnabled(mContext,
-                FeatureFlagUtils.SETTINGS_ACCESSIBILITY_HEARING_AID_PAGE, true);
         mShadowApplication = shadowOf((Application) ApplicationProvider.getApplicationContext());
         setupEnvironment();
 
@@ -252,37 +245,6 @@
     }
 
     @Test
-    public void handleHearingAidPreferenceClick_noHearingAid_launchHearingAidInstructionDialog() {
-        FeatureFlagUtils.setEnabled(mContext,
-                FeatureFlagUtils.SETTINGS_ACCESSIBILITY_HEARING_AID_PAGE, false);
-        mPreferenceController = spy(new AccessibilityHearingAidPreferenceController(mContext,
-                HEARING_AID_PREFERENCE));
-        mPreferenceController.setPreference(mHearingAidPreference);
-        doNothing().when(mPreferenceController).launchHearingAidInstructionDialog();
-
-        mPreferenceController.handlePreferenceTreeClick(mHearingAidPreference);
-
-        verify(mPreferenceController).launchHearingAidInstructionDialog();
-    }
-
-    @Test
-    public void handleHearingAidPreferenceClick_withHearingAid_launchBluetoothDeviceDetailSetting
-            () {
-        FeatureFlagUtils.setEnabled(mContext,
-                FeatureFlagUtils.SETTINGS_ACCESSIBILITY_HEARING_AID_PAGE, false);
-        mPreferenceController = spy(new AccessibilityHearingAidPreferenceController(mContext,
-                HEARING_AID_PREFERENCE));
-        mPreferenceController.setPreference(mHearingAidPreference);
-        when(mHearingAidProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList());
-        when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
-        doNothing().when(mPreferenceController).launchBluetoothDeviceDetailSetting(any());
-
-        mPreferenceController.handlePreferenceTreeClick(mHearingAidPreference);
-
-        verify(mPreferenceController).launchBluetoothDeviceDetailSetting(mCachedBluetoothDevice);
-    }
-
-    @Test
     public void onServiceConnected_onHearingAidProfileConnected_updateSummary() {
         when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
                 HearingAidInfo.DeviceSide.SIDE_LEFT);
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceControlsControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceControlsControllerTest.java
index bf4e055..364d299 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceControlsControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceControlsControllerTest.java
@@ -23,7 +23,6 @@
 
 import android.content.Context;
 import android.content.Intent;
-import android.util.FeatureFlagUtils;
 
 import androidx.preference.Preference;
 
@@ -63,8 +62,6 @@
 
     @Test
     public void isAvailable_isHearingAidDevice_available() {
-        FeatureFlagUtils.setEnabled(mContext,
-                FeatureFlagUtils.SETTINGS_ACCESSIBILITY_HEARING_AID_PAGE, true);
         when(mCachedDevice.isHearingAidDevice()).thenReturn(true);
 
         assertThat(mController.isAvailable()).isTrue();
@@ -72,8 +69,6 @@
 
     @Test
     public void isAvailable_isNotHearingAidDevice_notAvailable() {
-        FeatureFlagUtils.setEnabled(mContext,
-                FeatureFlagUtils.SETTINGS_ACCESSIBILITY_HEARING_AID_PAGE, true);
         when(mCachedDevice.isHearingAidDevice()).thenReturn(false);
 
         assertThat(mController.isAvailable()).isFalse();
diff --git a/tests/robotests/src/com/android/settings/display/ControlsTrivialPrivacyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/ControlsTrivialPrivacyPreferenceControllerTest.java
index a82e1f1..03bf763 100644
--- a/tests/robotests/src/com/android/settings/display/ControlsTrivialPrivacyPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/ControlsTrivialPrivacyPreferenceControllerTest.java
@@ -20,6 +20,7 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.spy;
@@ -220,7 +221,7 @@
             final ResolveInfo resolveInfo = new ResolveInfo();
             resolveInfo.activityInfo = activityInfo;
 
-            when(mPackageManager.resolveActivity(any(), any())).thenReturn(resolveInfo);
+            when(mPackageManager.resolveActivity(any(), anyInt())).thenReturn(resolveInfo);
         }
     }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/IncompatibleChargerDetectorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/IncompatibleChargerDetectorTest.java
index 3f65a67..c0f6108 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/IncompatibleChargerDetectorTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/IncompatibleChargerDetectorTest.java
@@ -81,6 +81,7 @@
         when(mUsbPort.getStatus()).thenReturn(mUsbPortStatus);
         when(mUsbPort.supportsComplianceWarnings()).thenReturn(true);
         when(mUsbPortStatus.isConnected()).thenReturn(true);
-        when(mUsbPortStatus.getComplianceWarnings()).thenReturn(new int[] {1});
+        when(mUsbPortStatus.getComplianceWarnings())
+                .thenReturn(new int[] {UsbPortStatus.COMPLIANCE_WARNING_DEBUG_ACCESSORY});
     }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java
index 91b2e15..e7c8e81 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java
@@ -84,8 +84,7 @@
         verify(mBatteryTipsCardPreference)
                 .setTitle("Turn on adaptive brightness to extend battery life");
         verify(mBatteryTipsCardPreference).setIconResourceId(R.drawable.ic_battery_tips_lightbulb);
-        verify(mBatteryTipsCardPreference)
-                .setMainButtonStrokeColorResourceId(R.color.color_accent_selector);
+        verify(mBatteryTipsCardPreference).setButtonColorResourceId(R.color.color_accent_selector);
         verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings");
         verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
         // Check proto info
@@ -104,8 +103,7 @@
 
         verify(mBatteryTipsCardPreference).setTitle("Reduce screen timeout to extend battery life");
         verify(mBatteryTipsCardPreference).setIconResourceId(R.drawable.ic_battery_tips_lightbulb);
-        verify(mBatteryTipsCardPreference)
-                .setMainButtonStrokeColorResourceId(R.color.color_accent_selector);
+        verify(mBatteryTipsCardPreference).setButtonColorResourceId(R.color.color_accent_selector);
         verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings");
         verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
         verify(mBatteryTipsCardPreference).setVisible(true);
@@ -134,8 +132,7 @@
 
         verify(mBatteryTipsCardPreference).setTitle(testTitle);
         verify(mBatteryTipsCardPreference).setIconResourceId(R.drawable.ic_battery_tips_lightbulb);
-        verify(mBatteryTipsCardPreference)
-                .setMainButtonStrokeColorResourceId(R.color.color_accent_selector);
+        verify(mBatteryTipsCardPreference).setButtonColorResourceId(R.color.color_accent_selector);
         verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings");
         verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
         verify(mBatteryTipsCardPreference).setVisible(true);
@@ -159,7 +156,7 @@
         verify(mBatteryTipsCardPreference)
                 .setIconResourceId(R.drawable.ic_battery_tips_warning_icon);
         verify(mBatteryTipsCardPreference)
-                .setMainButtonStrokeColorResourceId(R.color.color_battery_anomaly_yellow_selector);
+                .setButtonColorResourceId(R.color.color_battery_anomaly_app_warning_selector);
         verify(mBatteryTipsCardPreference).setMainButtonLabel("Check");
         verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
         verify(mBatteryTipsCardPreference).setVisible(true);
diff --git a/tests/unit/src/com/android/settings/privatespace/PrivateSpaceLockControllerTest.java b/tests/unit/src/com/android/settings/privatespace/PrivateSpaceLockControllerTest.java
new file mode 100644
index 0000000..0d9db7e
--- /dev/null
+++ b/tests/unit/src/com/android/settings/privatespace/PrivateSpaceLockControllerTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2023 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.privatespace;
+
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.Flags;
+import android.platform.test.flag.junit.SetFlagsRule;
+
+import androidx.preference.Preference;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.privatespace.onelock.PrivateSpaceLockController;
+import com.android.settings.testutils.FakeFeatureFactory;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class PrivateSpaceLockControllerTest {
+    @Mock
+    private Context mContext;
+    @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
+    @Mock SettingsPreferenceFragment mSettingsPreferenceFragment;
+    @Mock
+    LockPatternUtils mLockPatternUtils;
+
+    private Preference mPreference;
+    private PrivateSpaceLockController mPrivateSpaceLockController;
+
+    /** Required setup before a test. */
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = ApplicationProvider.getApplicationContext();
+        final String preferenceKey = "unlock_set_or_change_private_lock";
+
+        mPreference = new Preference(ApplicationProvider.getApplicationContext());
+        mPreference.setKey(preferenceKey);
+
+        final FakeFeatureFactory featureFactory = FakeFeatureFactory.setupForTest();
+        when(featureFactory.securityFeatureProvider.getLockPatternUtils(mContext))
+                .thenReturn(mLockPatternUtils);
+
+        mPrivateSpaceLockController = new PrivateSpaceLockController(mContext,
+                mSettingsPreferenceFragment);
+    }
+
+    /** Tests that the controller is always available. */
+    @Test
+    public void getAvailabilityStatus_returnsAvailable() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_PRIVATE_PROFILE);
+
+        assertThat(mPrivateSpaceLockController.isAvailable()).isEqualTo(true);
+    }
+
+    /** Tests that preference is disabled and summary says same as device lock. */
+    @Test
+    public void getSummary_whenScreenLock() {
+        doReturn(false).when(mLockPatternUtils).isSeparateProfileChallengeEnabled(anyInt());
+        mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_PRIVATE_PROFILE);
+
+        mPrivateSpaceLockController.updateState(mPreference);
+        assertThat(mPreference.isEnabled()).isFalse();
+        assertThat(mPreference.getSummary().toString()).isEqualTo("Same as device screen lock");
+    }
+
+    /** Tests that preference is enabled and summary is Pattern. */
+    @Test
+    public void getSummary_whenProfileLockPattern() {
+        doReturn(true)
+                .when(mLockPatternUtils).isSeparateProfileChallengeEnabled(anyInt());
+        doReturn(CREDENTIAL_TYPE_PATTERN)
+                .when(mLockPatternUtils).getCredentialTypeForUser(anyInt());
+        mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_PRIVATE_PROFILE);
+
+        mPrivateSpaceLockController.updateState(mPreference);
+        assertThat(mPreference.isEnabled()).isTrue();
+        assertThat(mPreference.getSummary().toString()).isEqualTo("Pattern");
+    }
+
+    /** Tests that preference is enabled and summary is Pin. */
+    @Test
+    public void getSummary_whenProfileLockPin() {
+        doReturn(true).when(mLockPatternUtils).isSeparateProfileChallengeEnabled(anyInt());
+        doReturn(CREDENTIAL_TYPE_PIN).when(mLockPatternUtils).getCredentialTypeForUser(anyInt());
+        mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_PRIVATE_PROFILE);
+
+        mPrivateSpaceLockController.updateState(mPreference);
+        assertThat(mPreference.isEnabled()).isTrue();
+        assertThat(mPreference.getSummary().toString()).isEqualTo("PIN");
+    }
+
+    /** Tests that preference is enabled and summary is Password. */
+    @Test
+    public void getSummary_whenProfileLockPassword() {
+        doReturn(true)
+                .when(mLockPatternUtils).isSeparateProfileChallengeEnabled(anyInt());
+        doReturn(CREDENTIAL_TYPE_PASSWORD)
+                .when(mLockPatternUtils).getCredentialTypeForUser(anyInt());
+        mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_PRIVATE_PROFILE);
+
+        mPrivateSpaceLockController.updateState(mPreference);
+        assertThat(mPreference.isEnabled()).isTrue();
+        assertThat(mPreference.getSummary().toString()).isEqualTo("Password");
+    }
+}
diff --git a/tests/unit/src/com/android/settings/privatespace/UseOneLockControllerTest.java b/tests/unit/src/com/android/settings/privatespace/UseOneLockControllerTest.java
index e7ebb37..744a8ec 100644
--- a/tests/unit/src/com/android/settings/privatespace/UseOneLockControllerTest.java
+++ b/tests/unit/src/com/android/settings/privatespace/UseOneLockControllerTest.java
@@ -16,36 +16,105 @@
 
 package com.android.settings.privatespace;
 
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN;
 import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+
 import static com.google.common.truth.Truth.assertThat;
 
-import android.content.Context;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
 
+import android.content.Context;
+import android.os.Flags;
+import android.platform.test.flag.junit.SetFlagsRule;
+
+import androidx.preference.Preference;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.privatespace.onelock.UseOneLockController;
+import com.android.settings.testutils.FakeFeatureFactory;
+
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 @RunWith(AndroidJUnit4.class)
 public class UseOneLockControllerTest {
     @Mock private Context mContext;
+    @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
     private UseOneLockController mUseOneLockController;
+    private Preference mPreference;
+
+    @Mock
+    LockPatternUtils mLockPatternUtils;
 
     /** Required setup before a test. */
     @Before
     public void setUp() {
+        MockitoAnnotations.initMocks(this);
         mContext = ApplicationProvider.getApplicationContext();
         final String preferenceKey = "private_space_use_one_lock";
+        mPreference = new Preference(mContext);
 
+        final FakeFeatureFactory featureFactory = FakeFeatureFactory.setupForTest();
+        when(featureFactory.securityFeatureProvider.getLockPatternUtils(mContext))
+                .thenReturn(mLockPatternUtils);
         mUseOneLockController = new UseOneLockController(mContext, preferenceKey);
+
     }
 
     /** Tests that the controller is always available. */
     @Test
     public void getAvailabilityStatus_returnsAvailable() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_PRIVATE_PROFILE);
+
         assertThat(mUseOneLockController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
     }
+
+
+    /** Tests that summary in controller is Pattern. */
+    @Test
+    public void getSummary_whenProfileLockPattern() {
+        doReturn(true)
+                .when(mLockPatternUtils).isSeparateProfileChallengeEnabled(anyInt());
+        doReturn(CREDENTIAL_TYPE_PATTERN)
+                .when(mLockPatternUtils).getCredentialTypeForUser(anyInt());
+        mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_PRIVATE_PROFILE);
+
+        mUseOneLockController.updateState(mPreference);
+        assertThat(mUseOneLockController.getSummary().toString()).isEqualTo("Pattern");
+    }
+
+    /** Tests that summary in controller is PIN. */
+    @Test
+    public void getSummary_whenProfileLockPin() {
+        doReturn(true)
+                .when(mLockPatternUtils).isSeparateProfileChallengeEnabled(anyInt());
+        doReturn(CREDENTIAL_TYPE_PIN).when(mLockPatternUtils).getCredentialTypeForUser(anyInt());
+        mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_PRIVATE_PROFILE);
+
+        mUseOneLockController.updateState(mPreference);
+        assertThat(mUseOneLockController.getSummary().toString()).isEqualTo("PIN");
+    }
+
+    /** Tests that summary in controller is Password. */
+    @Test
+    public void getSummary_whenProfileLockPassword() {
+        doReturn(true)
+                .when(mLockPatternUtils).isSeparateProfileChallengeEnabled(anyInt());
+        doReturn(CREDENTIAL_TYPE_PASSWORD)
+                .when(mLockPatternUtils).getCredentialTypeForUser(anyInt());
+        mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_PRIVATE_PROFILE);
+
+        mUseOneLockController.updateState(mPreference);
+        assertThat(mUseOneLockController.getSummary().toString()).isEqualTo("Password");
+    }
 }