Merge "Increase test coverage for fps pause enrollment feature" into main
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index c8f35ae..e4ed275 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -802,6 +802,11 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".network.SimOnboardingActivity"
+            android:exported="false"
+            android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"
+            android:theme="@style/Theme.SpaLib.BottomSheetDialog"/>
+
         <activity android:name=".network.telephony.ToggleSubscriptionDialogActivity"
                   android:exported="false"
                   android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"
@@ -3232,7 +3237,8 @@
 
         <receiver
             android:name=".fuelgauge.batteryusage.BootBroadcastReceiver"
-            android:exported="true">
+            android:exported="true"
+            android:permission="com.android.settings.BATTERY_DATA">
             <intent-filter>
                 <action android:name="android.intent.action.BOOT_COMPLETED"/>
                 <action android:name="com.google.android.setupwizard.SETUP_WIZARD_FINISHED"/>
@@ -4403,9 +4409,12 @@
         <activity android:name=".applications.credentials.CredentialsPickerActivity"
                 android:excludeFromRecents="true"
                 android:launchMode="singleInstance"
-                android:exported="false">
-            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
-                       android:value="com.android.settings.applications.credentials.DefaultCombinedPicker" />
+                android:exported="true">
+            <intent-filter android:priority="1">
+                <action android:name="android.settings.REQUEST_SET_AUTOFILL_SERVICE" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:scheme="package" />
+            </intent-filter>
         </activity>
 
         <activity
@@ -4550,19 +4559,6 @@
                 android:exported="false">
         </activity>
 
-        <activity android:name=".applications.autofill.AutofillPickerTrampolineActivity"
-                android:theme="@android:style/Theme.NoDisplay"
-                android:excludeFromRecents="true"
-                android:launchMode="singleInstance"
-                android:exported="true"
-                android:label="@string/autofill_app">
-            <intent-filter android:priority="1">
-                <action android:name="android.settings.REQUEST_SET_AUTOFILL_SERVICE" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <data android:scheme="package" />
-            </intent-filter>
-        </activity>
-
         <activity android:name="Settings$AdvancedConnectedDeviceActivity"
                   android:exported="true"
                   android:label="@string/connected_device_connections_title">
diff --git a/OWNERS b/OWNERS
index 6698752..12cd4ea 100644
--- a/OWNERS
+++ b/OWNERS
@@ -11,7 +11,6 @@
 jiannan@google.com
 millchen@google.com
 sunnyshao@google.com
-yantingyang@google.com
 
 # Android Settings extended
 chaohuiw@google.com
diff --git a/aconfig/settings_flag_declarations.aconfig b/aconfig/settings_flag_declarations.aconfig
index 56c4b32..36f104c 100644
--- a/aconfig/settings_flag_declarations.aconfig
+++ b/aconfig/settings_flag_declarations.aconfig
@@ -13,3 +13,10 @@
     description: "Enabling will provide an explicit package name for Intent to update mainline modules"
     bug: "278987474"
 }
+
+flag {
+    name: "app_archiving"
+    namespace: "android_settings"
+    description: "Feature flag to enable the archiving feature."
+    bug: "323164382"
+}
diff --git a/res/layout/dialog_audio_sharing_join.xml b/res/layout/dialog_audio_sharing_join.xml
index 4bdab7f..bfd4c77 100644
--- a/res/layout/dialog_audio_sharing_join.xml
+++ b/res/layout/dialog_audio_sharing_join.xml
@@ -24,16 +24,7 @@
     android:paddingBottom="?android:dialogPreferredPadding">
 
     <TextView
-        android:id="@+id/share_audio_subtitle1"
-        style="@style/DeviceAudioSharingText"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:paddingBottom="14dp"
-        android:textFontWeight="500" />
-
-    <TextView
-        android:id="@+id/share_audio_subtitle2"
+        android:id="@+id/share_audio_subtitle"
         style="@style/DeviceAudioSharingText"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 78900bc..caf3e7f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1219,15 +1219,15 @@
     <string name="work_profile_category_header">Work profile</string>
 
     <!-- Title for the Private Space page. [CHAR LIMIT=60] -->
-    <string name="private_space_title">Private Space</string>
+    <string name="private_space_title">Private space</string>
     <!-- Summary for the Private Space page. [CHAR LIMIT=NONE] -->
     <string name="private_space_summary">Keep private apps locked and hidden</string>
     <!-- Description for the Private Space page. [CHAR LIMIT=NONE] -->
     <string name="private_space_description">Keep private apps in a separate space that you can hide or lock</string>
     <!-- Title for the Private Space one lock preference. [CHAR LIMIT=60] -->
-    <string name="private_space_lock_title">Private Space 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>
+    <string name="private_space_one_lock_summary">You can unlock your 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] -->
@@ -1239,15 +1239,15 @@
     <!-- 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>
     <!-- Title for the Fingerprint unlock for private space preference. [CHAR LIMIT=60] -->
-    <string name="private_space_fingerprint_unlock_title">Fingerprint Unlock for Private Space</string>
+    <string name="private_space_fingerprint_unlock_title">Fingerprint Unlock for private space</string>
     <!-- Title for the Face unlock for private space preference. [CHAR LIMIT=60] -->
-    <string name="private_space_face_unlock_title">Face Unlock for Private Space</string>
+    <string name="private_space_face_unlock_title">Face Unlock for private space</string>
     <!-- Biometric category title - biometric options for unlocking the device. [CHAR LIMIT=50] -->
     <string name="private_space_category_ways_to_unlock">Ways to unlock</string>
     <!-- Summary for one lock when device screen lock is used as private profile lock. [CHAR LIMIT=40] -->
     <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>
+    <string name="private_space_new_lock_title">Choose a new lock for private space?</string>
     <!-- Title for the preference for auto lock private space. [CHAR LIMIT=40] -->
     <string name="private_space_auto_lock_title">Lock automatically</string>
     <!-- Title for private space auto lock settings page. [CHAR LIMIT=50] -->
@@ -1263,17 +1263,17 @@
     <!-- 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] -->
-    <string name="privatespace_hide_page_title">Hide Private Space when locked</string>
+    <string name="privatespace_hide_page_title">Hide private space when locked</string>
     <!-- Description for hide Private Space settings page. [CHAR LIMIT=NONE] -->
-    <string name="privatespace_hide_page_summary">To stop other people knowing Private Space is on your device, you can hide it from your apps list</string>
+    <string name="privatespace_hide_page_summary">To stop other people knowing you have a private space on your device, you can hide it from your apps list</string>
     <!-- Header in hide Private Space settings page to access Private Space when hidden. [CHAR LIMIT=60] -->
-    <string name="privatespace_access_header">Access Private Space when hidden</string>
+    <string name="privatespace_access_header">Access private space when hidden</string>
     <!-- Text in hide Private Space settings page on how to search Private Space when hidden. [CHAR LIMIT=60] -->
-    <string name="privatespace_search_description">Search for \'Private Space\' in the search bar</string>
+    <string name="privatespace_search_description">From your apps list, enter \'private space\' in the search bar</string>
     <!-- Text in hide Private Space settings page to tap on Private Space tile. [CHAR LIMIT=60] -->
-    <string name="privatespace_tap_tile_description">Tap the Private Space tile</string>
+    <string name="privatespace_tap_tile_description">Tap the private space tile</string>
     <!-- Text in hide Private Space settings page to Unlock Private Space. [CHAR LIMIT=60] -->
-    <string name="privatespace_unlock_description">Unlock your Private Space</string>
+    <string name="privatespace_unlock_description">Unlock your private space</string>
     <!-- Used to describe the off state of Private space hidden [CHAR LIMIT=30] -->
     <string name="privatespace_hide_off_summary">Off</string>
     <!-- Used to describe the off state of Private space hidden [CHAR LIMIT=30] -->
@@ -1295,9 +1295,9 @@
     <!-- Description for private space delete confirmation page that mentions it will take a few moments. [CHAR LIMIT=40] -->
     <string name="private_space_confirm_deletion_summary">This will take a few moments</string>
     <!-- Toast to show when the private space was deleted. [CHAR LIMIT=NONE] -->
-    <string name="private_space_deleted">Private Space successfully deleted</string>
+    <string name="private_space_deleted">Private space deleted</string>
     <!-- Toast to show when the private space could not be deleted. [CHAR LIMIT=NONE] -->
-    <string name="private_space_delete_failed">Private Space could not be deleted</string>
+    <string name="private_space_delete_failed">Private space could not be deleted</string>
     <!-- Toast to show when the private space is unlocked from settings entry point. [CHAR LIMIT=40] -->
     <string name="private_space_unlocked">Private space unlocked</string>
     <!-- Title of the Alert Dialog when no screen lock is set [CHAR LIMIT=30] -->
@@ -1329,13 +1329,13 @@
     <!-- Text shown at the bottom in private space auto advancing  screens. [CHAR LIMIT=60] -->
     <string name="private_space_setting_up_text">Setting up private space\u2026</string>
     <!-- Title for private space setup in auto advancing screen informing private space notifications are hidden when locked. [CHAR LIMIT=NONE] -->
-    <string name="private_space_notifications_hidden_title">Notifications from apps in private space are hidden when it\u2019s locked</string>
+    <string name="private_space_notifications_hidden_title">Notifications from private space apps are hidden when it\u2019s locked</string>
     <!-- Title for private space setup in auto advancing screen informing photos/files from private space can be shared when unlocked. [CHAR LIMIT=NONE] -->
-    <string name="private_space_share_photos_title">Unlock private space to share photos or files from private space apps</string>
+    <string name="private_space_share_photos_title">Unlock private space to share photos or files</string>
     <!-- Title for private space setup in auto advancing screen informing some system apps are already installed in private space. [CHAR LIMIT=NONE] -->
     <string name="private_space_apps_installed_title">Some apps are already installed in your private space</string>
     <!-- Title for private space creation error screen. [CHAR LIMIT=60] -->
-    <string name="private_space_error_screen_title">Couldn\u2019t set up private space</string>
+    <string name="private_space_error_screen_title">Couldn\u2019t set up a private space</string>
     <!-- Label for button to retry creating private space again on creation error. [CHAR LIMIT=30] -->
     <string name="private_space_tryagain_label">Try Again</string>
     <!-- Title for private space lock setup screen. [CHAR LIMIT=90] -->
@@ -1349,7 +1349,7 @@
     <!-- Title for private space setup success screen. [CHAR LIMIT=30] -->
     <string name="private_space_success_title">All set!</string>
     <!-- Summary for the private space setup success screen. [CHAR LIMIT=NONE] -->
-    <string name="private_space_access_text">To access your private space, go to your apps list then scroll down</string>
+    <string name="private_space_access_text">To find your private space, go to your apps list then scroll down</string>
     <!-- Label for private space done button to show a toast, finish setup and launch All apps [CHAR LIMIT=30] -->
     <string name="private_space_done_label">Done</string>
     <!-- Toast to show on private space setup completion informing user to scroll down All apps to access private space. [CHAR LIMIT=60] -->
@@ -1375,13 +1375,13 @@
 
     <!-- TODO(b/309950257): Remove below strings once QSTIle fulfillment is complete. -->
     <!-- Header in hide Private Space settings page to unhide Private Space. [CHAR LIMIT=90] -->
-    <string name="privatespace_unhide_header">To show Private Space (Not final UX)</string>
+    <string name="privatespace_unhide_header">To show private space (Not final UX)</string>
     <!-- Text in hide Private Space settings page on how to open Private Space setting. [CHAR LIMIT=NONE] -->
     <string name="privatespace_open_settings">Open the Settings App</string>
     <!-- Text in hide Private Space settings page on how to open Private Space setting. [CHAR LIMIT=NONE] -->
-    <string name="privatespace_tap_settings">Tap on Security &amp; privacy > Private Space > Hide Private Space when locked</string>
+    <string name="privatespace_tap_settings">Tap on Security &amp; privacy > private space > Hide private space when locked</string>
     <!-- Text in hide Private Space settings page to off hide toggle. [CHAR LIMIT=90] -->
-    <string name="privatespace_turnoff_hide">Turn off \‘Hide Private Space when locked\’ toggle</string>
+    <string name="privatespace_turnoff_hide">Turn off \‘Hide private space when locked\’ toggle</string>
     <!-- Note in hide Private Space settings page to inform that this is a development feature. [CHAR LIMIT=NONE] -->
     <string name="privatespace_development_note">Note to Googlers: The development of this feature is still in progress</string>
 
@@ -7265,7 +7265,7 @@
     <!-- Summary text describing signal strength to the user.  [CHAR LIMIT=60] -->
     <string name="sim_signal_strength"><xliff:g id="dbm">%1$d</xliff:g> dBm <xliff:g id="asu">%2$d</xliff:g> asu</string>
     <!-- Title for SIM notification.  [CHAR LIMIT=40] -->
-    <string name="sim_notification_title">SIMs changed.</string>
+    <string name="sim_notification_title">Your SIMs changed</string>
     <!-- Message under title informing the user to touch to go to SIM Cards in Settings.  [CHAR LIMIT=40] -->
     <string name="sim_notification_summary">Tap to set up</string>
 
@@ -7318,7 +7318,7 @@
     <!-- Title for setting tile leading to saved autofill passwords, autofill, and account settings [CHAR LIMIT=40]-->
     <string name="account_dashboard_title">Passwords &amp; accounts</string>
     <!-- Summary for setting tile leading to saved autofill passwords, autofill, and account settings [CHAR LIMIT=NONE]-->
-    <string name="account_dashboard_default_summary">Saved passwords, autofill, synced accounts</string>
+    <string name="account_dashboard_default_summary">Suggestions for sign-in &amp; autofill</string>
     <!-- Title for setting tile leading to setting UI which allows user set default app to
     handle actions such as open web page, making phone calls, default SMS apps [CHAR  LIMIT=40]-->
     <string name="app_default_dashboard_title">Default apps</string>
@@ -9055,7 +9055,7 @@
     <string name="screen_pinning_unlock_none">Lock device when unpinning</string>
 
     <!-- [CHAR LIMIT=60] turn eSim deletion confirmation on/off  -->
-    <string name="confirm_sim_deletion_title">Confirm SIM deletion</string>
+    <string name="confirm_sim_deletion_title">Confirm you want to erase your eSIM</string>
     <!-- [CHAR LIMIT=NONE] eSim deletion confirmation description  -->
     <string name="confirm_sim_deletion_description">Verify it\u0027s you before erasing an eSIM</string>
 
@@ -10785,8 +10785,8 @@
     <string name="autofill_passwords">Passwords</string>
     <!-- Preference category for showing autofill and credman services with saved credentials. [CHAR LIMIT=60] -->
     <string name="credman_chosen_app_title">Preferred service</string>
-    <!-- Preference category for showing additional credential providers. [CHAR LIMIT=60] -->
-    <string name="credman_credentials">Additional providers</string>
+    <!-- Preference category for showing additional credential services. [CHAR LIMIT=60] -->
+    <string name="credman_credentials">Additional services</string>
     <!-- Summary for passwords settings that shows how many passwords are saved for each autofill
          service. [CHAR LIMIT=NONE] -->
     <string name="autofill_passwords_count">{count, plural,
@@ -10831,7 +10831,7 @@
     </string>
 
     <!-- Title of the screen where the user picks a provider. [CHAR_LIMIT=NONE] -->
-    <string name="credman_picker_title">Passwords, passkeys, and data services</string>
+    <string name="credman_picker_title">Preferred service for passwords, passkeys &amp; autofill</string>
 
     <!-- Title of the warning dialog for disabling the credential provider. [CHAR_LIMIT=NONE] -->
     <string name="credman_confirmation_message_title">Turn off %1$s\?</string>
@@ -10848,6 +10848,9 @@
         ]]>
     </string>
 
+    <!-- Title for setting tile leading to saved autofill passwords, passkeys, autofill, and account settings [CHAR LIMIT=40]-->
+    <string name="account_dashboard_title_with_passkeys">Passwords, passkeys &amp; autofill</string>
+
     <!-- Message of the warning dialog for disabling the credential provider (new strings for 24Q3). [CHAR_LIMIT=NONE] -->
     <string name="credman_confirmation_message_new_ui">
         <![CDATA[
@@ -11370,7 +11373,7 @@
          the user that the way to disable this SIM is to physically remove it. This is in contrast
          to eSIM's, which can disabled using an on/off toggle switch. [CHAR LIMIT=NONE] -->
     <string name="mobile_network_disable_sim_explanation">
-        To disable this SIM, remove the SIM card
+        To turn off this SIM, remove the SIM card
     </string>
 
     <!--Summary used when a physical SIM is disabled, indicating that tapping on the preference will
@@ -11378,7 +11381,7 @@
         Network & internet page (if there are no other SIMs), or on the mobile network list page.
         [CHAR LIMIT=50] -->
     <string name="mobile_network_tap_to_activate">
-        Tap to activate <xliff:g id="carrier" example="T-mobile">%1$s</xliff:g>
+        Tap to activate your <xliff:g id="carrier" example="T-mobile">%1$s</xliff:g> SIM
     </string>
 
     <!-- Mobile network details page. Label for an option that lets the user delete an eSIM from
@@ -11502,13 +11505,13 @@
     <!-- Text of carrier list item in the mep confirmation dialog asking the user if they want to turn off the carrier. [CHAR_LIMIT=NONE] -->
     <string name="sim_action_switch_sub_dialog_info_outline_for_turning_off">Turning off a SIM won\u2019t cancel your service</string>
     <!-- Status message indicating the device is in the process of disconnecting from one mobile network and immediately connecting to another. [CHAR_LIMIT=NONE] -->
-    <string name="sim_action_enabling_sim_without_carrier_name">Connecting to network&#8230;</string>
+    <string name="sim_action_enabling_sim_without_carrier_name">Activating your SIM&#8230;</string>
     <!-- Text of progress dialog indicating the subscription switch is in progress. [CHAR_LIMIT=NONE] -->
-    <string name="sim_action_switch_sub_dialog_progress">Switching to <xliff:g id="carrier_name" example="Google Fi">%1$s</xliff:g> for calls and messages&#8230;</string>
+    <string name="sim_action_switch_sub_dialog_progress">Switching to <xliff:g id="carrier_name" example="Google Fi">%1$s</xliff:g>&#8230;</string>
     <!-- Title of error message indicating that the device could not disconnect from one mobile network and immediately connect to another. [CHAR_LIMIT=NONE] -->
-    <string name="sim_action_enable_sim_fail_title">Can\u2019t switch carrier</string>
+    <string name="sim_action_enable_sim_fail_title">Can\u2019t switch SIMs</string>
     <!-- Body text of error message indicating the device could not disconnect from one mobile network and immediately connect to another, due to an unspecified issue. [CHAR_LIMIT=NONE] -->
-    <string name="sim_action_enable_sim_fail_text">The carrier can\u2019t be switched due to an error.</string>
+    <string name="sim_action_enable_sim_fail_text">Something went wrong. Can\u2019t switch SIMs.</string>
     <!-- Title of confirmation dialog asking the user if they want to disable subscription. [CHAR_LIMIT=NONE] -->
     <string name="privileged_action_disable_sub_dialog_title">Turn off <xliff:g id="carrier_name" example="Google Fi">%1$s</xliff:g>?</string>
     <!-- Title of confirmation dialog asking the user if they want to disable subscription. [CHAR_LIMIT=NONE] -->
@@ -11516,9 +11519,9 @@
     <!-- Disabling SIMs progress dialog message [CHAR LIMIT=NONE] -->
     <string name="privileged_action_disable_sub_dialog_progress">Turning off SIM<xliff:g id="ellipsis" example="...">&#8230;</xliff:g></string>
     <!-- Title of error messaging indicating the device could not disable the mobile network. [CHAR LIMIT=NONE] -->
-    <string name="privileged_action_disable_fail_title">Can\u2019t disable carrier</string>
+    <string name="privileged_action_disable_fail_title">Can\u2019t turn off SIM</string>
     <!-- Body text of error message indicating the device could not disable the mobile network, due to an unknown issue. [CHAR LIMIT=NONE] -->
-    <string name="privileged_action_disable_fail_text">Something went wrong and your carrier could not be disabled.</string>
+    <string name="privileged_action_disable_fail_text">Something went wrong and your SIM could not be turned off.</string>
     <!-- Title on a dialog asking the users whether they want to enable DSDS mode. [CHAR LIMIT=NONE] -->
     <string name="sim_action_enable_dsds_title">Use 2 SIMs?</string>
     <!-- Message in a dialog indicating the user can enable DSDS mode. [CHAR LIMIT=NONE] -->
@@ -11598,7 +11601,7 @@
     <!-- Title on a push notification indicating that the user's device is in the middle of switching between mobile networks. [CHAR LIMIT=NONE] -->
     <string name="sim_switch_channel_id">Carrier switching</string>
     <!--  The title of post DSDS reboot notification. The title includes carrier's name. [CHAR LIMIT=NONE] -->
-    <string name="post_dsds_reboot_notification_title_with_carrier"><xliff:g id="carrier_name" example="Google Fi">%1$s</xliff:g> is active</string>
+    <string name="post_dsds_reboot_notification_title_with_carrier">Your <xliff:g id="carrier_name" example="Google Fi">%1$s</xliff:g> SIM is active</string>
     <!--  The body text of post DSDS reboot notification. [CHAR LIMIT=NONE] -->
     <string name="post_dsds_reboot_notification_text">Tap to update SIM settings</string>
     <!-- Title on a push notification indicating that the user's device switched to a new mobile network. [CHAR LIMIT=NONE] -->
@@ -11614,17 +11617,17 @@
 
     <!-- Strings for choose SIM activity -->
     <!--  The title text of choose SIM activity. [CHAR LIMIT=NONE] -->
-    <string name="choose_sim_title">Choose a number to use</string>
+    <string name="choose_sim_title">Choose a SIM to use</string>
     <!--  The body text of choose SIM activity. [CHAR LIMIT=NONE] -->
     <string name="choose_sim_text">{count, plural,
-      =1      {1 number is available on this device, but only one can be used at a time}
-      =2      {2 numbers are available on this device, but only one can be used at a time}
-      other   {# numbers are available on this device, but only one can be used at a time}
+      =1      {1 SIM is available on this device, but only one can be used at a time}
+      =2      {2 SIMs are available on this device, but only one can be used at a time}
+      other   {# SIMs are available on this device, but only one can be used at a time}
     }</string>
     <!-- String indicating that we are activating the profile [CHAR LIMIT=NONE] -->
     <string name="choose_sim_activating">Activating<xliff:g id="ellipsis" example="...">&#8230;</xliff:g></string>
     <!-- String indicating that we failed to activate the selected profile [CHAR LIMIT=NONE] -->
-    <string name="choose_sim_could_not_activate">Couldn\u2019t be activated right now</string>
+    <string name="choose_sim_could_not_activate">Couldn\u2019t activate this SIM right now</string>
 
     <!-- Strings for switch SIM confirmation dialog. -->
     <!--  The title text of switch SIM confirmation dialog. [CHAR LIMIT=NONE] -->
@@ -11979,6 +11982,11 @@
     <!-- Developer settings: Summary for allowing mock modem service. [CHAR LIMIT=NONE]-->
     <string name="allow_mock_modem_summary">Allow this device to run Mock Modem service for instrumentation testing. Do not enable this during normal usage of the phone</string>
 
+    <!-- Developer settings: Title for disable app and notification screen share protections [CHAR LIMIT=50] -->
+    <string name="disable_screen_share_protections_for_apps_and_notifications">Disable screen share protections</string>
+    <!-- Developer settings: Summary for disable app and notification screen share protections summary [CHAR LIMIT=150] -->
+    <string name="disable_screen_share_protections_for_apps_and_notifications_summary">Disables system applied app and notifications protections during screen sharing</string>
+
     <!-- Title for media control settings [CHAR LIMIT=50]-->
     <string name="media_controls_title">Media</string>
     <!-- Title of toggle to enable or disable the media resumption feature in quick settings [CHAR LIMIT=50]-->
diff --git a/res/xml/accounts_dashboard_settings_credman.xml b/res/xml/accounts_dashboard_settings_credman.xml
index 7266bda..08377c9 100644
--- a/res/xml/accounts_dashboard_settings_credman.xml
+++ b/res/xml/accounts_dashboard_settings_credman.xml
@@ -18,7 +18,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:key="user_and_account_settings_screen"
-    android:title="@string/account_dashboard_title"
+    android:title="@string/account_dashboard_title_with_passkeys"
     settings:keywords="@string/keywords_accounts">
 
     <PreferenceCategory
diff --git a/res/xml/accounts_personal_dashboard_settings_credman.xml b/res/xml/accounts_personal_dashboard_settings_credman.xml
index 9473e17..16ab31b 100644
--- a/res/xml/accounts_personal_dashboard_settings_credman.xml
+++ b/res/xml/accounts_personal_dashboard_settings_credman.xml
@@ -19,7 +19,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:key="user_and_account_settings_screen"
-    android:title="@string/account_dashboard_title"
+    android:title="@string/account_dashboard_title_with_passkeys"
     settings:keywords="@string/keywords_accounts">
 
     <PreferenceCategory
diff --git a/res/xml/accounts_private_dashboard_settings_credman.xml b/res/xml/accounts_private_dashboard_settings_credman.xml
index 54db839..c0b12b5 100644
--- a/res/xml/accounts_private_dashboard_settings_credman.xml
+++ b/res/xml/accounts_private_dashboard_settings_credman.xml
@@ -19,7 +19,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:key="user_and_account_settings_screen"
-    android:title="@string/account_dashboard_title"
+    android:title="@string/account_dashboard_title_with_passkeys"
     settings:keywords="@string/keywords_accounts">
 
     <PreferenceCategory
diff --git a/res/xml/accounts_work_dashboard_settings_credman.xml b/res/xml/accounts_work_dashboard_settings_credman.xml
index d649940..44bdb52 100644
--- a/res/xml/accounts_work_dashboard_settings_credman.xml
+++ b/res/xml/accounts_work_dashboard_settings_credman.xml
@@ -19,7 +19,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:key="user_and_account_settings_screen"
-    android:title="@string/account_dashboard_title"
+    android:title="@string/account_dashboard_title_with_passkeys"
     settings:keywords="@string/keywords_accounts">
 
     <PreferenceCategory
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index fb5e280..c0b6560 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -705,6 +705,11 @@
             android:title="@string/show_notification_channel_warnings"
             android:summary="@string/show_notification_channel_warnings_summary" />
 
+        <SwitchPreferenceCompat
+            android:key="disable_screen_share_protections_for_apps_and_notifications"
+            android:title="@string/disable_screen_share_protections_for_apps_and_notifications"
+            android:summary="@string/disable_screen_share_protections_for_apps_and_notifications_summary" />
+
         <Preference
             android:key="asst_importance_reset"
             android:title="@string/asst_importance_reset_title"
diff --git a/res/xml/top_level_settings.xml b/res/xml/top_level_settings.xml
index d050a1f..31c6af3 100644
--- a/res/xml/top_level_settings.xml
+++ b/res/xml/top_level_settings.xml
@@ -180,7 +180,7 @@
         android:icon="@drawable/ic_settings_accounts"
         android:key="top_level_accounts"
         android:order="-10"
-        android:title="@string/account_dashboard_title"
+        android:title="@string/account_dashboard_title_with_passkeys"
         android:summary="@string/summary_placeholder"
         settings:highlightableMenuKey="@string/menu_key_accounts"
         settings:controller="com.android.settings.accounts.TopLevelAccountEntryPreferenceController"/>
diff --git a/src/com/android/settings/applications/AppCounter.java b/src/com/android/settings/applications/AppCounter.java
index d536932..2b1e47e 100644
--- a/src/com/android/settings/applications/AppCounter.java
+++ b/src/com/android/settings/applications/AppCounter.java
@@ -22,12 +22,15 @@
 import android.content.pm.PackageManager.ApplicationInfoFlags;
 import android.content.pm.UserInfo;
 import android.os.AsyncTask;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
 
+import com.android.settings.flags.Flags;
+
 import java.util.List;
 
 public abstract class AppCounter extends AsyncTask<Void, Void, Integer> {
@@ -54,7 +57,7 @@
         for (UserInfo user : mUm.getProfiles(UserHandle.myUserId())) {
             long flags = PackageManager.GET_DISABLED_COMPONENTS
                     | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS
-                    | (mFf.archiving() ? PackageManager.MATCH_ARCHIVED_PACKAGES : 0)
+                    | (isArchivingEnabled() ? PackageManager.MATCH_ARCHIVED_PACKAGES : 0)
                     | (user.isAdmin() ? PackageManager.MATCH_ANY_USER : 0);
             ApplicationInfoFlags infoFlags = ApplicationInfoFlags.of(flags);
             final List<ApplicationInfo> list =
@@ -68,6 +71,11 @@
         return count;
     }
 
+    private boolean isArchivingEnabled() {
+        return mFf.archiving() || SystemProperties.getBoolean("pm.archiving.enabled", false)
+                || Flags.appArchiving();
+    }
+
     @Override
     protected void onPostExecute(Integer count) {
         onCountComplete(count);
diff --git a/src/com/android/settings/applications/credentials/CombinedProviderInfo.java b/src/com/android/settings/applications/credentials/CombinedProviderInfo.java
index f8a3b0f..4f27870 100644
--- a/src/com/android/settings/applications/credentials/CombinedProviderInfo.java
+++ b/src/com/android/settings/applications/credentials/CombinedProviderInfo.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.applications.credentials;
 
+import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -24,7 +25,6 @@
 import android.credentials.CredentialProviderInfo;
 import android.graphics.drawable.Drawable;
 import android.os.UserHandle;
-import android.os.UserManager;
 import android.service.autofill.AutofillServiceInfo;
 import android.text.TextUtils;
 import android.util.IconDrawableFactory;
@@ -49,7 +49,7 @@
     private static final String TAG = "CombinedProviderInfo";
     private static final String SETTINGS_ACTIVITY_INTENT_ACTION = "android.intent.action.MAIN";
     private static final String SETTINGS_ACTIVITY_INTENT_CATEGORY =
-            "android.intent.category.LAUNCHER";
+            "android.intent.category.DEFAULT";
 
     private final List<CredentialProviderInfo> mCredentialProviderInfos;
     private final @Nullable AutofillServiceInfo mAutofillServiceInfo;
@@ -327,10 +327,8 @@
     }
 
     public static @Nullable Intent createSettingsActivityIntent(
-            @NonNull Context context,
             @Nullable CharSequence packageName,
-            @Nullable CharSequence settingsActivity,
-            int currentUserId) {
+            @Nullable CharSequence settingsActivity) {
         if (TextUtils.isEmpty(packageName) || TextUtils.isEmpty(settingsActivity)) {
             return null;
         }
@@ -350,19 +348,25 @@
         Intent intent = new Intent(SETTINGS_ACTIVITY_INTENT_ACTION);
         intent.addCategory(SETTINGS_ACTIVITY_INTENT_CATEGORY);
         intent.setComponent(cn);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        return intent;
+    }
 
-        int contextUserId = context.getUser().getIdentifier();
-        if (currentUserId != contextUserId && UserManager.isHeadlessSystemUserMode()) {
-            Log.w(
-                    TAG,
-                    "onLeftSideClicked(): using context for current user ("
-                            + currentUserId
-                            + ") instead of user "
-                            + contextUserId
-                            + " on headless system user mode");
-            context = context.createContextAsUser(UserHandle.of(currentUserId), /* flags= */ 0);
+    /** Launches the settings activity intent. */
+    public static void launchSettingsActivityIntent(
+            @NonNull Context context,
+            @Nullable CharSequence packageName,
+            @Nullable CharSequence settingsActivity,
+            int userId) {
+        Intent settingsIntent = createSettingsActivityIntent(packageName, settingsActivity);
+        if (settingsIntent == null) {
+            return;
         }
 
-        return intent;
+        try {
+            context.startActivityAsUser(settingsIntent, UserHandle.of(userId));
+        } catch (ActivityNotFoundException e) {
+            Log.e(TAG, "Failed to open settings activity", e);
+        }
     }
 }
diff --git a/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java b/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
index 4fc0e16..d98bc51 100644
--- a/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
+++ b/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
@@ -20,7 +20,6 @@
 
 import android.app.Activity;
 import android.app.Dialog;
-import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -677,16 +676,8 @@
 
                     @Override
                     public void onLeftSideClicked() {
-                        Intent settingsIntent =
-                                CombinedProviderInfo.createSettingsActivityIntent(
-                                        mContext, packageName, settingsActivity, getUser());
-                        if (settingsIntent != null) {
-                            try {
-                                mContext.startActivity(settingsIntent);
-                            } catch (ActivityNotFoundException e) {
-                                Log.e(TAG, "Failed to open settings activity", e);
-                            }
-                        }
+                        CombinedProviderInfo.launchSettingsActivityIntent(
+                                mContext, packageName, settingsActivity, getUser());
                     }
                 });
 
diff --git a/src/com/android/settings/applications/credentials/CredentialsPickerActivity.java b/src/com/android/settings/applications/credentials/CredentialsPickerActivity.java
index 495c104..479a184 100644
--- a/src/com/android/settings/applications/credentials/CredentialsPickerActivity.java
+++ b/src/com/android/settings/applications/credentials/CredentialsPickerActivity.java
@@ -16,15 +16,53 @@
 
 package com.android.settings.applications.credentials;
 
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Slog;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.SettingsActivity;
 
-/** Standalone activity used to launch a {@link DefaultCombinedPicker} fragment. */
+/**
+ * Standalone activity used to launch a {@link DefaultCombinedPicker} fragment if the user is a
+ * normal user, a {@link DefaultCombinedPickerWork} fragment if the user is a work profile or {@link
+ * DefaultCombinedPickerPrivate} fragment if the user is a private profile.
+ */
 public class CredentialsPickerActivity extends SettingsActivity {
+    private static final String TAG = "CredentialsPickerActivity";
+
+    /** Injects the fragment name into the intent so the correct fragment is opened. */
+    @VisibleForTesting
+    public static void injectFragmentIntoIntent(Context context, Intent intent) {
+        final int userId = UserHandle.myUserId();
+        final UserManager userManager = UserManager.get(context);
+
+        if (DefaultCombinedPickerWork.isUserHandledByFragment(userManager, userId)) {
+            Slog.d(TAG, "Creating picker fragment using work profile");
+            intent.putExtra(EXTRA_SHOW_FRAGMENT, DefaultCombinedPickerWork.class.getName());
+        } else if (DefaultCombinedPickerPrivate.isUserHandledByFragment(userManager)) {
+            Slog.d(TAG, "Creating picker fragment using private profile");
+            intent.putExtra(EXTRA_SHOW_FRAGMENT, DefaultCombinedPickerPrivate.class.getName());
+        } else {
+            Slog.d(TAG, "Creating picker fragment using normal profile");
+            intent.putExtra(EXTRA_SHOW_FRAGMENT, DefaultCombinedPicker.class.getName());
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        injectFragmentIntoIntent(this, getIntent());
+        super.onCreate(savedInstanceState);
+    }
 
     @Override
     protected boolean isValidFragment(String fragmentName) {
         return super.isValidFragment(fragmentName)
-                || DefaultCombinedPicker.class.getName().equals(fragmentName);
+                || DefaultCombinedPicker.class.getName().equals(fragmentName)
+                || DefaultCombinedPickerWork.class.getName().equals(fragmentName)
+                || DefaultCombinedPickerPrivate.class.getName().equals(fragmentName);
     }
 }
diff --git a/src/com/android/settings/applications/credentials/DefaultCombinedPickerPrivate.java b/src/com/android/settings/applications/credentials/DefaultCombinedPickerPrivate.java
index 722cb1a..8d8af0e 100644
--- a/src/com/android/settings/applications/credentials/DefaultCombinedPickerPrivate.java
+++ b/src/com/android/settings/applications/credentials/DefaultCombinedPickerPrivate.java
@@ -17,14 +17,29 @@
 package com.android.settings.applications.credentials;
 
 import android.os.UserManager;
+import android.util.Slog;
 
 import com.android.settings.Utils;
 import com.android.settings.dashboard.profileselector.ProfileSelectFragment.ProfileType;
 
 public class DefaultCombinedPickerPrivate extends DefaultCombinedPicker {
+    private static final String TAG = "DefaultCombinedPickerPrivate";
+
     @Override
     protected int getUser() {
         UserManager userManager = getContext().getSystemService(UserManager.class);
         return Utils.getCurrentUserIdOfType(userManager, ProfileType.PRIVATE);
     }
+
+    /** Returns whether the user is handled by this fragment. */
+    public static boolean isUserHandledByFragment(UserManager userManager) {
+        try {
+            // If there is no private profile then this will throw an exception.
+            Utils.getCurrentUserIdOfType(userManager, ProfileType.PRIVATE);
+            return true;
+        } catch (IllegalStateException e) {
+            Slog.e(TAG, "Failed to get private profile user id", e);
+            return false;
+        }
+    }
 }
diff --git a/src/com/android/settings/applications/credentials/DefaultCombinedPickerWork.java b/src/com/android/settings/applications/credentials/DefaultCombinedPickerWork.java
index 9808502..945d6b8 100644
--- a/src/com/android/settings/applications/credentials/DefaultCombinedPickerWork.java
+++ b/src/com/android/settings/applications/credentials/DefaultCombinedPickerWork.java
@@ -19,13 +19,16 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 
-import com.android.settings.Utils;
-
 public class DefaultCombinedPickerWork extends DefaultCombinedPicker {
+    private static final String TAG = "DefaultCombinedPickerWork";
 
     @Override
     protected int getUser() {
-        UserHandle workProfile = Utils.getManagedProfile(UserManager.get(getContext()));
-        return workProfile.getIdentifier();
+        return UserHandle.myUserId();
+    }
+
+    /** Returns whether the user is handled by this fragment. */
+    public static boolean isUserHandledByFragment(UserManager userManager, int userId) {
+        return userManager.isManagedProfile(userId);
     }
 }
diff --git a/src/com/android/settings/applications/credentials/DefaultCombinedPreferenceController.java b/src/com/android/settings/applications/credentials/DefaultCombinedPreferenceController.java
index 0fb1769..49dd7cd 100644
--- a/src/com/android/settings/applications/credentials/DefaultCombinedPreferenceController.java
+++ b/src/com/android/settings/applications/credentials/DefaultCombinedPreferenceController.java
@@ -16,7 +16,6 @@
 
 package com.android.settings.applications.credentials;
 
-import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
 import android.credentials.CredentialManager;
@@ -26,11 +25,11 @@
 import android.provider.Settings;
 import android.service.autofill.AutofillService;
 import android.service.autofill.AutofillServiceInfo;
+import android.text.TextUtils;
 import android.view.autofill.AutofillManager;
-import android.util.Slog;
 
-import androidx.annotation.Nullable;
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.preference.Preference;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -83,7 +82,7 @@
         // hand side presses to align the UX.
         if (PrimaryProviderPreference.shouldUseNewSettingsUi()) {
             // We need to return an empty intent here since the class we inherit
-            // from will throw an NPE if we return null and we don't want it to 
+            // from will throw an NPE if we return null and we don't want it to
             // open anything since we added the buttons.
             return new Intent();
         }
@@ -99,10 +98,10 @@
                     topProvider.getAppName(mContext),
                     topProvider.getSettingsSubtitle(),
                     topProvider.getAppIcon(mContext, getUser()),
-                    createSettingsActivityIntent(
-                            topProvider.getPackageName(), topProvider.getSettingsActivity()));
+                    topProvider.getPackageName(),
+                    topProvider.getSettingsActivity());
         } else {
-            updatePreferenceForProvider(preference, null, null, null, null);
+            updatePreferenceForProvider(preference, null, null, null, null, null);
         }
     }
 
@@ -112,7 +111,8 @@
             @Nullable CharSequence appName,
             @Nullable String appSubtitle,
             @Nullable Drawable appIcon,
-            @Nullable Intent settingsActivityIntent) {
+            @Nullable CharSequence packageName,
+            @Nullable CharSequence settingsActivity) {
         if (appName == null) {
             preference.setTitle(R.string.app_list_preference_none);
         } else {
@@ -133,13 +133,8 @@
             primaryPref.setDelegate(
                     new PrimaryProviderPreference.Delegate() {
                         public void onOpenButtonClicked() {
-                            if (settingsActivityIntent != null) {
-                                try {
-                                    startActivity(settingsActivityIntent);
-                                } catch (ActivityNotFoundException e) {
-                                    Slog.e(TAG, "Failed to open settings activity", e);
-                                }
-                            }
+                            CombinedProviderInfo.launchSettingsActivityIntent(
+                                    mContext, packageName, settingsActivity, getUser());
                         }
 
                         public void onChangeButtonClicked() {
@@ -148,7 +143,7 @@
                     });
 
             // Hide the open button if there is no defined settings activity.
-            primaryPref.setOpenButtonVisible(settingsActivityIntent != null);
+            primaryPref.setOpenButtonVisible(!TextUtils.isEmpty(settingsActivity));
             primaryPref.setButtonsVisible(appName != null);
         }
     }
@@ -198,13 +193,8 @@
 
     /** Creates an intent to open the credential picker. */
     private Intent createIntentToOpenPicker() {
-        return new Intent(mContext, CredentialsPickerActivity.class);
-    }
-
-    /** Creates an intent to open the settings activity of the primary provider (if available). */
-    public @Nullable Intent createSettingsActivityIntent(
-            @Nullable String packageName, @Nullable String settingsActivity) {
-        return CombinedProviderInfo.createSettingsActivityIntent(
-                mContext, packageName, settingsActivity, getUser());
+        final Context context =
+                mContext.createContextAsUser(UserHandle.of(getUser()), /* flags= */ 0);
+        return new Intent(context, CredentialsPickerActivity.class);
     }
 }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java
index 3fd5127..ef0f226 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java
@@ -17,6 +17,7 @@
 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;
@@ -27,6 +28,7 @@
 import android.util.Log;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.fragment.app.DialogFragment;
 import androidx.fragment.app.Fragment;
 import androidx.lifecycle.DefaultLifecycleObserver;
@@ -43,6 +45,7 @@
 import com.android.settingslib.bluetooth.BluetoothCallback;
 import com.android.settingslib.bluetooth.BluetoothUtils;
 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;
@@ -68,9 +71,10 @@
             "connected_device_audio_sharing_settings";
 
     private final LocalBluetoothManager mLocalBtManager;
-    private final LocalBluetoothLeBroadcast mBroadcast;
-    private final LocalBluetoothLeBroadcastAssistant mAssistant;
     private final Executor mExecutor;
+    private CachedBluetoothDeviceManager mDeviceManager;
+    private LocalBluetoothLeBroadcast mBroadcast;
+    private LocalBluetoothLeBroadcastAssistant mAssistant;
     private PreferenceGroup mPreferenceGroup;
     private Preference mAudioSharingSettingsPreference;
     private BluetoothDeviceUpdater mBluetoothDeviceUpdater;
@@ -165,6 +169,12 @@
                                     + ", reason = "
                                     + reason);
                     mBluetoothDeviceUpdater.forceUpdate();
+                    if (mDeviceManager != null) {
+                        CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(sink);
+                        if (cachedDevice != null) {
+                            closeOpeningDialogsForLeaDevice(cachedDevice);
+                        }
+                    }
                 }
 
                 @Override
@@ -241,8 +251,11 @@
     public AudioSharingDevicePreferenceController(Context context) {
         super(context, KEY);
         mLocalBtManager = Utils.getLocalBtManager(mContext);
-        mBroadcast = mLocalBtManager.getProfileManager().getLeAudioBroadcastProfile();
-        mAssistant = mLocalBtManager.getProfileManager().getLeAudioBroadcastAssistantProfile();
+        if (mLocalBtManager != null) {
+            mDeviceManager = mLocalBtManager.getCachedDeviceManager();
+            mBroadcast = mLocalBtManager.getProfileManager().getLeAudioBroadcastProfile();
+            mAssistant = mLocalBtManager.getProfileManager().getLeAudioBroadcastAssistantProfile();
+        }
         mExecutor = Executors.newSingleThreadExecutor();
     }
 
@@ -344,6 +357,17 @@
             @NonNull CachedBluetoothDevice cachedDevice,
             @ConnectionState int state,
             int bluetoothProfile) {
+        if (state == BluetoothAdapter.STATE_DISCONNECTED) {
+            boolean isLeAudio = isLeAudioSupported(cachedDevice);
+            if (isLeAudio && bluetoothProfile == BluetoothProfile.LE_AUDIO) {
+                closeOpeningDialogsForLeaDevice(cachedDevice);
+                return;
+            }
+            if (!isLeAudio && !cachedDevice.isConnected()) {
+                closeOpeningDialogsForNonLeaDevice(cachedDevice);
+                return;
+            }
+        }
         if (state != BluetoothAdapter.STATE_CONNECTED || !cachedDevice.getDevice().isConnected()) {
             Log.d(TAG, "Ignore onProfileConnectionStateChanged, not connected state");
             return;
@@ -420,10 +444,10 @@
             // connected during a sharing session.
             postOnMainThread(
                     () -> {
-                        closeOpeningDialogs();
+                        closeOpeningDialogsOtherThan(AudioSharingStopDialogFragment.tag());
                         AudioSharingStopDialogFragment.show(
                                 mFragment,
-                                cachedDevice.getName(),
+                                cachedDevice,
                                 () -> mBroadcast.stopBroadcast(mBroadcast.getLatestBroadcastId()));
                     });
         } else {
@@ -466,11 +490,12 @@
             if (deviceItemsInSharingSession.size() >= 2) {
                 postOnMainThread(
                         () -> {
-                            closeOpeningDialogs();
+                            closeOpeningDialogsOtherThan(
+                                    AudioSharingDisconnectDialogFragment.tag());
                             AudioSharingDisconnectDialogFragment.show(
                                     mFragment,
                                     deviceItemsInSharingSession,
-                                    cachedDevice.getName(),
+                                    cachedDevice,
                                     (AudioSharingDeviceItem item) -> {
                                         // Remove all sources from the device user clicked
                                         if (groupedDevices.containsKey(item.getGroupId())) {
@@ -497,11 +522,11 @@
                 // remote device connected during a sharing session.
                 postOnMainThread(
                         () -> {
-                            closeOpeningDialogs();
+                            closeOpeningDialogsOtherThan(AudioSharingJoinDialogFragment.tag());
                             AudioSharingJoinDialogFragment.show(
                                     mFragment,
                                     deviceItemsInSharingSession,
-                                    cachedDevice.getName(),
+                                    cachedDevice,
                                     () -> {
                                         // Add current broadcast to the latest connected device
                                         mAssistant.addSource(
@@ -527,11 +552,11 @@
             if (deviceItems.size() == 1) {
                 postOnMainThread(
                         () -> {
-                            closeOpeningDialogs();
+                            closeOpeningDialogsOtherThan(AudioSharingJoinDialogFragment.tag());
                             AudioSharingJoinDialogFragment.show(
                                     mFragment,
                                     deviceItems,
-                                    cachedDevice.getName(),
+                                    cachedDevice,
                                     () -> {
                                         mTargetSinks = new ArrayList<>();
                                         for (List<CachedBluetoothDevice> devices :
@@ -591,17 +616,61 @@
         }
     }
 
-    private void closeOpeningDialogs() {
+    private void closeOpeningDialogsOtherThan(String tag) {
         if (mFragment == null) return;
         List<Fragment> fragments = mFragment.getChildFragmentManager().getFragments();
         for (Fragment fragment : fragments) {
-            if (fragment instanceof DialogFragment) {
+            if (fragment instanceof DialogFragment && !fragment.getTag().equals(tag)) {
                 Log.d(TAG, "Remove staled opening dialog " + fragment.getTag());
                 ((DialogFragment) fragment).dismiss();
             }
         }
     }
 
+    private void closeOpeningDialogsForLeaDevice(@NonNull CachedBluetoothDevice cachedDevice) {
+        if (mFragment == null) return;
+        int groupId = AudioSharingUtils.getGroupId(cachedDevice);
+        List<Fragment> fragments = mFragment.getChildFragmentManager().getFragments();
+        for (Fragment fragment : fragments) {
+            CachedBluetoothDevice device = getCachedBluetoothDeviceFromDialog(fragment);
+            if (device != null
+                    && groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID
+                    && AudioSharingUtils.getGroupId(device) == groupId) {
+                Log.d(TAG, "Remove staled opening dialog for group " + groupId);
+                ((DialogFragment) fragment).dismiss();
+            }
+        }
+    }
+
+    private void closeOpeningDialogsForNonLeaDevice(@NonNull CachedBluetoothDevice cachedDevice) {
+        if (mFragment == null) return;
+        String address = cachedDevice.getAddress();
+        List<Fragment> fragments = mFragment.getChildFragmentManager().getFragments();
+        for (Fragment fragment : fragments) {
+            CachedBluetoothDevice device = getCachedBluetoothDeviceFromDialog(fragment);
+            if (device != null && address != null && address.equals(device.getAddress())) {
+                Log.d(
+                        TAG,
+                        "Remove staled opening dialog for device "
+                                + cachedDevice.getDevice().getAnonymizedAddress());
+                ((DialogFragment) fragment).dismiss();
+            }
+        }
+    }
+
+    @Nullable
+    private CachedBluetoothDevice getCachedBluetoothDeviceFromDialog(Fragment fragment) {
+        CachedBluetoothDevice device = null;
+        if (fragment instanceof AudioSharingJoinDialogFragment) {
+            device = ((AudioSharingJoinDialogFragment) fragment).getDevice();
+        } else if (fragment instanceof AudioSharingStopDialogFragment) {
+            device = ((AudioSharingStopDialogFragment) fragment).getDevice();
+        } else if (fragment instanceof AudioSharingDisconnectDialogFragment) {
+            device = ((AudioSharingDisconnectDialogFragment) fragment).getDevice();
+        }
+        return device;
+    }
+
     private void postOnMainThread(@NonNull Runnable runnable) {
         mContext.getMainExecutor().execute(runnable);
     }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java
index a2b1824..74c73aa 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java
@@ -19,13 +19,17 @@
 import android.app.Dialog;
 import android.app.settings.SettingsEnums;
 import android.os.Bundle;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.DialogFragment;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentManager;
 import androidx.recyclerview.widget.LinearLayoutManager;
@@ -33,8 +37,10 @@
 
 import com.android.settings.R;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 
 import java.util.ArrayList;
+import java.util.Locale;
 
 public class AudioSharingDisconnectDialogFragment extends InstrumentedDialogFragment {
     private static final String TAG = "AudioSharingDisconnectDialog";
@@ -56,6 +62,7 @@
     }
 
     private static DialogEventListener sListener;
+    @Nullable private static CachedBluetoothDevice sNewDevice;
 
     @Override
     public int getMetricsCategory() {
@@ -65,35 +72,78 @@
     /**
      * Display the {@link AudioSharingDisconnectDialogFragment} dialog.
      *
+     * <p>If the dialog is showing for the same group, update the dialog event listener.
+     *
      * @param host The Fragment this dialog will be hosted.
      * @param deviceItems The existing connected device items in audio sharing session.
-     * @param newDeviceName The name of the latest connected device triggered this dialog.
+     * @param newDevice 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,
+            CachedBluetoothDevice newDevice,
             DialogEventListener listener) {
         if (!AudioSharingUtils.isFeatureEnabled()) return;
         final FragmentManager manager = host.getChildFragmentManager();
+        Fragment dialog = manager.findFragmentByTag(TAG);
+        if (dialog != null
+                && ((DialogFragment) dialog).getDialog() != null
+                && ((DialogFragment) dialog).getDialog().isShowing()) {
+            int newGroupId = AudioSharingUtils.getGroupId(newDevice);
+            if (sNewDevice != null && newGroupId == AudioSharingUtils.getGroupId(sNewDevice)) {
+                Log.d(
+                        TAG,
+                        String.format(
+                                Locale.US,
+                                "Dialog is showing for the same device group %d, "
+                                        + "update the content.",
+                                newGroupId));
+                sListener = listener;
+                sNewDevice = newDevice;
+                return;
+            } else {
+                Log.d(
+                        TAG,
+                        String.format(
+                                Locale.US,
+                                "Dialog is showing for new device group %d, "
+                                        + "dismiss current dialog.",
+                                newGroupId));
+                ((DialogFragment) dialog).dismiss();
+            }
+        }
         sListener = listener;
+        sNewDevice = newDevice;
+        Log.d(TAG, "Show up the dialog.");
         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);
+        bundle.putString(BUNDLE_KEY_NEW_DEVICE_NAME, newDevice.getName());
+        AudioSharingDisconnectDialogFragment dialogFrag =
+                new AudioSharingDisconnectDialogFragment();
+        dialogFrag.setArguments(bundle);
+        dialogFrag.show(manager, TAG);
+    }
+
+    /** Return the tag of {@link AudioSharingDisconnectDialogFragment} dialog. */
+    public static @NonNull String tag() {
+        return TAG;
+    }
+
+    /** Get the latest connected device which triggers the dialog. */
+    public @Nullable CachedBluetoothDevice getDevice() {
+        return sNewDevice;
     }
 
     @Override
-    public Dialog onCreateDialog(Bundle savedInstanceState) {
+    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
         Bundle arguments = requireArguments();
         ArrayList<AudioSharingDeviceItem> deviceItems =
                 arguments.getParcelableArrayList(BUNDLE_KEY_DEVICE_TO_DISCONNECT_ITEMS);
         final AlertDialog.Builder builder =
                 new AlertDialog.Builder(getActivity()).setCancelable(false);
         LayoutInflater inflater = LayoutInflater.from(builder.getContext());
+        // Set custom title for the dialog.
         View customTitle = inflater.inflate(R.layout.dialog_custom_title_audio_sharing, null);
         ImageView icon = customTitle.findViewById(R.id.title_icon);
         icon.setImageResource(R.drawable.ic_bt_audio_sharing);
@@ -115,10 +165,7 @@
         recyclerView.setLayoutManager(
                 new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
         Button cancelBtn = rootView.findViewById(R.id.cancel_btn);
-        cancelBtn.setOnClickListener(
-                v -> {
-                    dismiss();
-                });
+        cancelBtn.setOnClickListener(v -> dismiss());
         AlertDialog dialog = builder.setCustomTitle(customTitle).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
index f3f0fe4..8791c11 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragment.java
@@ -18,19 +18,25 @@
 
 import android.app.Dialog;
 import android.app.settings.SettingsEnums;
+import android.graphics.Typeface;
 import android.os.Bundle;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.DialogFragment;
 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.settingslib.bluetooth.CachedBluetoothDevice;
 
 import java.util.ArrayList;
 import java.util.Locale;
@@ -49,6 +55,7 @@
     }
 
     private static DialogEventListener sListener;
+    private static @Nullable CachedBluetoothDevice sNewDevice;
 
     @Override
     public int getMetricsCategory() {
@@ -58,29 +65,54 @@
     /**
      * Display the {@link AudioSharingJoinDialogFragment} dialog.
      *
+     * <p>If the dialog is showing, update the dialog message and event listener.
+     *
      * @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 newDevice 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,
+            CachedBluetoothDevice newDevice,
             DialogEventListener listener) {
         if (!AudioSharingUtils.isFeatureEnabled()) return;
         final FragmentManager manager = host.getChildFragmentManager();
         sListener = listener;
-        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);
+        sNewDevice = newDevice;
+        Fragment dialog = manager.findFragmentByTag(TAG);
+        if (dialog != null
+                && ((DialogFragment) dialog).getDialog() != null
+                && ((DialogFragment) dialog).getDialog().isShowing()) {
+            Log.d(TAG, "Dialog is showing, update the content.");
+            updateDialog(
+                    deviceItems,
+                    newDevice.getName(),
+                    (AlertDialog) ((DialogFragment) dialog).getDialog());
+        } else {
+            Log.d(TAG, "Show up the dialog.");
+            final Bundle bundle = new Bundle();
+            bundle.putParcelableArrayList(BUNDLE_KEY_DEVICE_ITEMS, deviceItems);
+            bundle.putString(BUNDLE_KEY_NEW_DEVICE_NAME, newDevice.getName());
+            final AudioSharingJoinDialogFragment dialogFrag = new AudioSharingJoinDialogFragment();
+            dialogFrag.setArguments(bundle);
+            dialogFrag.show(manager, TAG);
+        }
+    }
+
+    /** Return the tag of {@link AudioSharingJoinDialogFragment} dialog. */
+    public static @NonNull String tag() {
+        return TAG;
+    }
+
+    /** Get the latest connected device which triggers the dialog. */
+    public @Nullable CachedBluetoothDevice getDevice() {
+        return sNewDevice;
     }
 
     @Override
-    public Dialog onCreateDialog(Bundle savedInstanceState) {
+    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
         Bundle arguments = requireArguments();
         ArrayList<AudioSharingDeviceItem> deviceItems =
                 arguments.getParcelableArrayList(BUNDLE_KEY_DEVICE_ITEMS);
@@ -88,6 +120,7 @@
         final AlertDialog.Builder builder =
                 new AlertDialog.Builder(getActivity()).setCancelable(false);
         LayoutInflater inflater = LayoutInflater.from(builder.getContext());
+        // Set custom title for the dialog.
         View customTitle =
                 inflater.inflate(R.layout.dialog_custom_title_audio_sharing, /* parent= */ null);
         ImageView icon = customTitle.findViewById(R.id.title_icon);
@@ -95,21 +128,8 @@
         TextView title = customTitle.findViewById(R.id.title_text);
         title.setText("Share your audio");
         View rootView = inflater.inflate(R.layout.dialog_audio_sharing_join, /* parent= */ null);
-        TextView subtitle1 = rootView.findViewById(R.id.share_audio_subtitle1);
-        TextView subtitle2 = rootView.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("This device's music and videos will play on both pairs of headphones");
+        TextView subtitle = rootView.findViewById(R.id.share_audio_subtitle);
+        subtitle.setText("This device's music and videos will play on both pairs of headphones");
         Button shareBtn = rootView.findViewById(R.id.share_btn);
         Button cancelBtn = rootView.findViewById(R.id.cancel_btn);
         shareBtn.setOnClickListener(
@@ -119,8 +139,37 @@
                 });
         shareBtn.setText("Share audio");
         cancelBtn.setOnClickListener(v -> dismiss());
-        Dialog dialog = builder.setCustomTitle(customTitle).setView(rootView).create();
+        AlertDialog dialog = builder.setCustomTitle(customTitle).setView(rootView).create();
         dialog.setCanceledOnTouchOutside(false);
+        updateDialog(deviceItems, newDeviceName, dialog);
+        dialog.show();
+        TextView messageView = (TextView) dialog.findViewById(android.R.id.message);
+        if (messageView != null) {
+            Typeface typeface = Typeface.create(Typeface.DEFAULT_FAMILY, Typeface.NORMAL);
+            messageView.setTypeface(typeface);
+            messageView.setTextDirection(View.TEXT_DIRECTION_LOCALE);
+            messageView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
+        } else {
+            Log.w(TAG, "Fail to update message style: message view is null");
+        }
         return dialog;
     }
+
+    private static void updateDialog(
+            ArrayList<AudioSharingDeviceItem> deviceItems,
+            String newDeviceName,
+            @NonNull AlertDialog dialog) {
+        if (deviceItems.isEmpty()) {
+            dialog.setMessage(newDeviceName);
+        } else {
+            dialog.setMessage(
+                    String.format(
+                            Locale.US,
+                            "%s and %s",
+                            deviceItems.stream()
+                                    .map(AudioSharingDeviceItem::getName)
+                                    .collect(Collectors.joining(", ")),
+                            newDeviceName));
+        }
+    }
 }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java
index 1454f76..3ba41f7 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java
@@ -18,18 +18,24 @@
 
 import android.app.Dialog;
 import android.app.settings.SettingsEnums;
+import android.graphics.Typeface;
 import android.os.Bundle;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.DialogFragment;
 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.settingslib.bluetooth.CachedBluetoothDevice;
 
 public class AudioSharingStopDialogFragment extends InstrumentedDialogFragment {
     private static final String TAG = "AudioSharingStopDialog";
@@ -44,6 +50,7 @@
     }
 
     private static DialogEventListener sListener;
+    private static @Nullable CachedBluetoothDevice sNewDevice;
 
     @Override
     public int getMetricsCategory() {
@@ -53,41 +60,79 @@
     /**
      * Display the {@link AudioSharingStopDialogFragment} dialog.
      *
+     * <p>If the dialog is showing, update the dialog message and event listener.
+     *
      * @param host The Fragment this dialog will be hosted.
-     * @param newDeviceName The name of the latest connected device triggered this dialog.
+     * @param newDevice 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, String newDeviceName, DialogEventListener listener) {
+    public static void show(
+            Fragment host, CachedBluetoothDevice newDevice, DialogEventListener listener) {
         if (!AudioSharingUtils.isFeatureEnabled()) return;
         final FragmentManager manager = host.getChildFragmentManager();
         sListener = listener;
-        final Bundle bundle = new Bundle();
-        bundle.putString(BUNDLE_KEY_NEW_DEVICE_NAME, newDeviceName);
-        AudioSharingStopDialogFragment dialog = new AudioSharingStopDialogFragment();
-        dialog.setArguments(bundle);
-        dialog.show(manager, TAG);
+        sNewDevice = newDevice;
+        Fragment dialog = manager.findFragmentByTag(TAG);
+        if (dialog != null
+                && ((DialogFragment) dialog).getDialog() != null
+                && ((DialogFragment) dialog).getDialog().isShowing()) {
+            Log.d(TAG, "Dialog is showing, update the content.");
+            updateDialog(newDevice.getName(), (AlertDialog) ((DialogFragment) dialog).getDialog());
+        } else {
+            Log.d(TAG, "Show up the dialog.");
+            final Bundle bundle = new Bundle();
+            bundle.putString(BUNDLE_KEY_NEW_DEVICE_NAME, newDevice.getName());
+            AudioSharingStopDialogFragment dialogFrag = new AudioSharingStopDialogFragment();
+            dialogFrag.setArguments(bundle);
+            dialogFrag.show(manager, TAG);
+        }
+    }
+
+    /** Return the tag of {@link AudioSharingStopDialogFragment} dialog. */
+    public static @NonNull String tag() {
+        return TAG;
+    }
+
+    /** Get the latest connected device which triggers the dialog. */
+    public @Nullable CachedBluetoothDevice getDevice() {
+        return sNewDevice;
     }
 
     @Override
-    public Dialog onCreateDialog(Bundle savedInstanceState) {
+    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
         Bundle arguments = requireArguments();
         String newDeviceName = arguments.getString(BUNDLE_KEY_NEW_DEVICE_NAME);
         final AlertDialog.Builder builder =
                 new AlertDialog.Builder(getActivity()).setCancelable(false);
         LayoutInflater inflater = LayoutInflater.from(builder.getContext());
+        // Set custom title for the dialog.
         View customTitle =
                 inflater.inflate(R.layout.dialog_custom_title_audio_sharing, /* parent= */ null);
         ImageView icon = customTitle.findViewById(R.id.title_icon);
         icon.setImageResource(R.drawable.ic_warning_24dp);
         TextView title = customTitle.findViewById(R.id.title_text);
         title.setText("Stop sharing audio?");
-        builder.setMessage(
-                newDeviceName + " wants to connect, headphones in audio sharing will disconnect.");
         builder.setPositiveButton(
                 "Stop sharing", (dialog, which) -> sListener.onStopSharingClick());
         builder.setNegativeButton("Cancel", (dialog, which) -> dismiss());
         AlertDialog dialog = builder.setCustomTitle(customTitle).create();
         dialog.setCanceledOnTouchOutside(false);
+        updateDialog(newDeviceName, dialog);
+        dialog.show();
+        TextView messageView = (TextView) dialog.findViewById(android.R.id.message);
+        if (messageView != null) {
+            Typeface typeface = Typeface.create(Typeface.DEFAULT_FAMILY, Typeface.NORMAL);
+            messageView.setTypeface(typeface);
+            messageView.setTextDirection(View.TEXT_DIRECTION_LOCALE);
+            messageView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
+        } else {
+            Log.w(TAG, "sssFail to update dialog: message view is null");
+        }
         return dialog;
     }
+
+    private static void updateDialog(String newDeviceName, @NonNull AlertDialog dialog) {
+        dialog.setMessage(
+                newDeviceName + " wants to connect, headphones in audio sharing will disconnect.");
+    }
 }
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index 504eda8..6b38b28 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -763,6 +763,7 @@
                 context, context.getSystemService(UiModeManager.class)));
         controllers.add(new ForceEnableNotesRolePreferenceController(context));
         controllers.add(new GrammaticalGenderPreferenceController(context));
+        controllers.add(new SensitiveContentProtectionPreferenceController(context));
 
         return controllers;
     }
diff --git a/src/com/android/settings/development/OWNERS b/src/com/android/settings/development/OWNERS
index 09a4914..92c8cfa 100644
--- a/src/com/android/settings/development/OWNERS
+++ b/src/com/android/settings/development/OWNERS
@@ -1,6 +1,9 @@
 # GameDefaultFrameRatePreferenceController
 per-file GameDefaultFrameRatePreferenceController.java=file:platform/frameworks/base:/GAME_MANAGER_OWNERS
 
+# SensitiveContentProtectionPreferenceController
+per-file SensitiveContentProtectionPreferenceController.kt=file:platform/frameworks/base:/core/java/android/permission/OWNERS
+
 # ShowHdrSdrRatioPreferenceController
 per-file ShowHdrSdrRatioPreferenceController.java=file:platform/frameworks/native:/services/surfaceflinger/OWNERS
 
diff --git a/src/com/android/settings/development/SensitiveContentProtectionPreferenceController.kt b/src/com/android/settings/development/SensitiveContentProtectionPreferenceController.kt
new file mode 100644
index 0000000..6fe56c8
--- /dev/null
+++ b/src/com/android/settings/development/SensitiveContentProtectionPreferenceController.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2024 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.development
+
+import android.content.Context
+import android.provider.Settings
+import androidx.annotation.VisibleForTesting
+import androidx.preference.Preference
+import androidx.preference.TwoStatePreference
+import com.android.server.notification.Flags.sensitiveNotificationAppProtection
+import com.android.server.notification.Flags.screenshareNotificationHiding
+import com.android.settings.core.PreferenceControllerMixin
+import com.android.settingslib.development.DeveloperOptionsPreferenceController
+
+class SensitiveContentProtectionPreferenceController(val context: Context) :
+    DeveloperOptionsPreferenceController(context),
+    Preference.OnPreferenceChangeListener,
+    PreferenceControllerMixin {
+
+    override fun getPreferenceKey(): String =
+        DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS_KEY
+
+    override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
+        val isEnabled = newValue as Boolean
+        Settings.Global.putInt(
+            mContext.getContentResolver(),
+            Settings.Global.DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS,
+            if (isEnabled) SETTING_VALUE_ON else SETTING_VALUE_OFF
+        )
+        return true
+    }
+
+    override fun updateState(preference: Preference?) {
+        val mode = Settings.Global.getInt(
+            mContext.getContentResolver(),
+            Settings.Global.DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS,
+            0)
+        (mPreference as TwoStatePreference).isChecked = mode != SETTING_VALUE_OFF
+    }
+
+    // Overriding as public, kotlin tests can not invoke a protected method
+    public override fun onDeveloperOptionsSwitchDisabled() {
+        super.onDeveloperOptionsSwitchDisabled()
+        Settings.Global.putInt(
+            mContext.getContentResolver(),
+            Settings.Global.DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS,
+            SETTING_VALUE_OFF
+        )
+        (mPreference as TwoStatePreference).isChecked = false
+    }
+
+    override fun isAvailable(): Boolean {
+        return sensitiveNotificationAppProtection() || screenshareNotificationHiding()
+    }
+
+    companion object {
+        private const val DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS_KEY =
+            "disable_screen_share_protections_for_apps_and_notifications"
+
+        @VisibleForTesting
+        val SETTING_VALUE_ON = 1
+
+        @VisibleForTesting
+        val SETTING_VALUE_OFF = 0
+    }
+}
diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsController.java b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsController.java
index 45c1be0..6425833 100644
--- a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsController.java
+++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsController.java
@@ -41,7 +41,7 @@
 public class BatterySaverScheduleRadioButtonsController {
     private static final String TAG = "BatterySaverScheduleRadioButtonsController";
 
-    public static final int TRIGGER_LEVEL_MIN = 10;
+    public static final int TRIGGER_LEVEL_MIN = 20;
 
     private Context mContext;
     private BatterySaverScheduleSeekBarController mSeekBarController;
diff --git a/src/com/android/settings/network/SimOnboardingActivity.kt b/src/com/android/settings/network/SimOnboardingActivity.kt
new file mode 100644
index 0000000..f5dc886
--- /dev/null
+++ b/src/com/android/settings/network/SimOnboardingActivity.kt
@@ -0,0 +1,430 @@
+/*
+ * Copyright (C) 2024 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.network
+
+import android.app.ProgressDialog
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import android.telephony.SubscriptionManager
+import android.util.Log
+import android.view.MotionEvent
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.outlined.SignalCellularAlt
+import androidx.compose.material3.Button
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.Icon
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.ModalBottomSheet
+import androidx.compose.material3.SheetState
+import androidx.compose.material3.Text
+import androidx.compose.material3.rememberModalBottomSheetState
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.LocalLifecycleOwner
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.text.style.TextOverflow
+import com.android.settings.R
+import com.android.settings.SidecarFragment
+import com.android.settings.network.telephony.SubscriptionActionDialogActivity
+import com.android.settings.spa.SpaActivity.Companion.startSpaActivity
+import com.android.settings.spa.network.SimOnboardingPageProvider.getRoute
+import com.android.settingslib.spa.SpaBaseDialogActivity
+import com.android.settingslib.spa.framework.theme.SettingsDimension
+import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
+import com.android.settingslib.spa.widget.ui.SettingsTitle
+import com.android.settingslib.spaprivileged.framework.common.userManager
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.catch
+import kotlinx.coroutines.flow.conflate
+import kotlinx.coroutines.launch
+
+class SimOnboardingActivity : SpaBaseDialogActivity() {
+    lateinit var scope: CoroutineScope
+    lateinit var showBottomSheet: MutableState<Boolean>
+    lateinit var showError: MutableState<Boolean>
+    lateinit var showDialog: MutableState<Boolean>
+
+    private var switchToEuiccSubscriptionSidecar: SwitchToEuiccSubscriptionSidecar? = null
+    private var switchToRemovableSlotSidecar: SwitchToRemovableSlotSidecar? = null
+    private var enableMultiSimSidecar: EnableMultiSimSidecar? = null
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        if (!this.userManager.isAdminUser) {
+            Log.e(TAG, "It is not the admin user. Unable to toggle subscription.")
+            finish()
+            return
+        }
+
+        var targetSubId = intent.getIntExtra(SUB_ID,SubscriptionManager.INVALID_SUBSCRIPTION_ID)
+        initServiceData(this, targetSubId, callbackListener)
+        if (!onboardingService.isUsableTargetSubscriptionId) {
+            Log.e(TAG, "The subscription id is not usable.")
+            finish()
+            return
+        }
+
+        switchToEuiccSubscriptionSidecar = SwitchToEuiccSubscriptionSidecar.get(fragmentManager)
+        switchToRemovableSlotSidecar = SwitchToRemovableSlotSidecar.get(fragmentManager)
+        enableMultiSimSidecar = EnableMultiSimSidecar.get(fragmentManager)
+
+        setContent {
+            Content()
+        }
+    }
+
+    override fun finish() {
+        setProgressDialog(false)
+        onboardingService.clear()
+        super.finish()
+    }
+
+    var callbackListener: (Int) -> Unit = {
+        Log.d(TAG, "Receive the CALLBACK: $it")
+        when (it) {
+            CALLBACK_ERROR -> {
+                setProgressDialog(false)
+                showError.value = true
+            }
+
+            CALLBACK_ONBOARDING_COMPLETE -> {
+                showBottomSheet.value = false
+                setProgressDialog(true)
+                scope.launch {
+                    // TODO: refactor the Sidecar
+                    // start to activate the sim
+                    startSimSwitching()
+                }
+            }
+
+            CALLBACK_SETUP_NAME -> {
+                scope.launch {
+                    onboardingService.startSetupName()
+                }
+            }
+
+            CALLBACK_SETUP_PRIMARY_SIM -> {
+                scope.launch {
+                    onboardingService.startSetupPrimarySim(this@SimOnboardingActivity)
+                }
+            }
+
+            CALLBACK_FINISH -> {
+                finish()
+            }
+        }
+    }
+
+    fun setProgressDialog(enable: Boolean) {
+        showDialog.value = enable
+        val progressState = if (enable) {
+            SubscriptionActionDialogActivity.PROGRESS_IS_SHOWING
+        } else {
+            SubscriptionActionDialogActivity.PROGRESS_IS_NOT_SHOWING
+        }
+        setProgressState(progressState)
+    }
+
+    @OptIn(ExperimentalMaterial3Api::class)
+    @Composable
+    override fun Content() {
+        showBottomSheet = remember { mutableStateOf(true) }
+        showError = remember { mutableStateOf(false) }
+        showDialog = remember { mutableStateOf(false) }
+        scope = rememberCoroutineScope()
+
+        registerSidecarReceiverFlow()
+
+        if(showError.value){
+            // show error
+            return
+        }
+
+        if (showBottomSheet.value) {
+            var sheetState = rememberModalBottomSheetState()
+            BottomSheetImpl(
+                sheetState = sheetState,
+                nextAction = {
+                    // TODO: if the phone is SS mode and the isDsdsConditionSatisfied is true, then
+                    //  enable the DSDS mode.
+                    //  case#1: the device need the reboot after enabling DSDS. Showing the confirm
+                    //          dialog to user whether reboot device or not.
+                    //  case#2: The device don't need the reboot. Enabling DSDS and then showing
+                    //          the SIM onboarding UI.
+
+                    // case#2
+                    val route = getRoute(onboardingService.targetSubId)
+                    startSpaActivity(route)
+                },
+                cancelAction = { finish() },
+            )
+        } else {
+            ProgressDialogImpl()
+        }
+    }
+
+    @Composable
+    fun ProgressDialogImpl() {
+        // TODO: 1. Create the SPA's ProgressDialog and using SPA's widget
+        val dialog: ProgressDialog = object : ProgressDialog(this) {
+            override fun onTouchEvent(event: MotionEvent): Boolean {
+                return true
+            }
+        }
+        dialog.setMessage(
+            stringResource(
+                R.string.sim_onboarding_progressbar_turning_sim_on,
+                onboardingService.targetSubInfo?.displayName ?: ""
+            )
+        )
+        dialog.setCancelable(false)
+
+        if(showDialog.value) {
+            dialog.show()
+        }
+    }
+    @Composable
+    fun registerSidecarReceiverFlow(){
+        switchToEuiccSubscriptionSidecar?.sidecarReceiverFlow()
+            ?.collectLatestWithLifecycle(LocalLifecycleOwner.current) {
+                onStateChange(it)
+            }
+        switchToRemovableSlotSidecar?.sidecarReceiverFlow()
+            ?.collectLatestWithLifecycle(LocalLifecycleOwner.current) {
+                onStateChange(it)
+            }
+        enableMultiSimSidecar?.sidecarReceiverFlow()
+            ?.collectLatestWithLifecycle(LocalLifecycleOwner.current) {
+                onStateChange(it)
+            }
+    }
+
+    fun SidecarFragment.sidecarReceiverFlow(): Flow<SidecarFragment> = callbackFlow {
+        val broadcastReceiver = SidecarFragment.Listener {
+            Log.d(TAG, "onReceive: $it")
+            trySend(it)
+        }
+        addListener(broadcastReceiver)
+
+        awaitClose { removeListener(broadcastReceiver) }
+    }.catch { e ->
+        Log.e(TAG, "Error while sidecarReceiverFlow", e)
+    }.conflate()
+
+    fun startSimSwitching(){
+        Log.d(TAG, "startSimSwitching:")
+
+        var targetSubInfo = onboardingService.targetSubInfo
+        targetSubInfo?.let {
+            var removedSubInfo = onboardingService.getRemovedSim()
+            if (targetSubInfo.isEmbedded) {
+                switchToEuiccSubscriptionSidecar!!.run(
+                    targetSubInfo.subscriptionId,
+                    UiccSlotUtil.INVALID_PORT_ID,
+                    removedSubInfo
+                )
+                return@let
+            }
+            switchToRemovableSlotSidecar!!.run(
+                UiccSlotUtil.INVALID_PHYSICAL_SLOT_ID,
+                removedSubInfo
+            )
+        } ?: run {
+            Log.e(TAG, "no target subInfo in onboardingService")
+            finish()
+        }
+    }
+
+    fun onStateChange(fragment: SidecarFragment?) {
+        if (fragment === switchToEuiccSubscriptionSidecar) {
+            handleSwitchToEuiccSubscriptionSidecarStateChange()
+        } else if (fragment === switchToRemovableSlotSidecar) {
+            handleSwitchToRemovableSlotSidecarStateChange()
+        } else if (fragment === enableMultiSimSidecar) {
+            handleEnableMultiSimSidecarStateChange()
+        }
+    }
+
+    fun handleSwitchToEuiccSubscriptionSidecarStateChange() {
+        when (switchToEuiccSubscriptionSidecar!!.state) {
+            SidecarFragment.State.SUCCESS -> {
+                Log.i(TAG, "Successfully enable the eSIM profile.")
+                switchToEuiccSubscriptionSidecar!!.reset()
+                callbackListener(CALLBACK_SETUP_NAME)
+            }
+
+            SidecarFragment.State.ERROR -> {
+                Log.i(TAG, "Failed to enable the eSIM profile.")
+                switchToEuiccSubscriptionSidecar!!.reset()
+                callbackListener(CALLBACK_ERROR)
+                // TODO: showErrorDialog and using privileged_action_disable_fail_title and
+                //       privileged_action_disable_fail_text
+            }
+        }
+    }
+
+    fun handleSwitchToRemovableSlotSidecarStateChange() {
+        when (switchToRemovableSlotSidecar!!.state) {
+            SidecarFragment.State.SUCCESS -> {
+                Log.i(TAG, "Successfully switched to removable slot.")
+                switchToRemovableSlotSidecar!!.reset()
+                onboardingService.handleTogglePsimAction()
+                callbackListener(CALLBACK_SETUP_NAME)
+            }
+
+            SidecarFragment.State.ERROR -> {
+                Log.e(TAG, "Failed switching to removable slot.")
+                switchToRemovableSlotSidecar!!.reset()
+                callbackListener(CALLBACK_ERROR)
+                // TODO: showErrorDialog and using sim_action_enable_sim_fail_title and
+                //       sim_action_enable_sim_fail_text
+            }
+        }
+    }
+
+    fun handleEnableMultiSimSidecarStateChange() {
+        when (enableMultiSimSidecar!!.state) {
+            SidecarFragment.State.SUCCESS -> {
+                enableMultiSimSidecar!!.reset()
+                Log.i(TAG, "Successfully switched to DSDS without reboot.")
+                handleEnableSubscriptionAfterEnablingDsds()
+            }
+
+            SidecarFragment.State.ERROR -> {
+                enableMultiSimSidecar!!.reset()
+                Log.i(TAG, "Failed to switch to DSDS without rebooting.")
+                callbackListener(CALLBACK_ERROR)
+                // TODO: showErrorDialog and using dsds_activation_failure_title and
+                //       dsds_activation_failure_body_msg2
+            }
+        }
+    }
+
+    fun handleEnableSubscriptionAfterEnablingDsds() {
+        var targetSubInfo = onboardingService.targetSubInfo
+        if (targetSubInfo?.isEmbedded == true) {
+            Log.i(TAG,
+                    "DSDS enabled, start to enable profile: " + targetSubInfo.getSubscriptionId()
+            )
+            // For eSIM operations, we simply switch to the selected eSIM profile.
+            switchToEuiccSubscriptionSidecar!!.run(
+                targetSubInfo.subscriptionId,
+                UiccSlotUtil.INVALID_PORT_ID,
+                null
+            )
+            return
+        }
+        Log.i(TAG, "DSDS enabled, start to enable pSIM profile.")
+        onboardingService.handleTogglePsimAction()
+        callbackListener(CALLBACK_FINISH)
+    }
+
+    @Composable
+    fun BottomSheetBody(nextAction: () -> Unit) {
+        Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.padding(bottom = SettingsDimension.itemPaddingVertical)) {
+            Icon(
+                imageVector = Icons.Outlined.SignalCellularAlt,
+                contentDescription = null,
+                modifier = Modifier
+                    .size(SettingsDimension.iconLarge),
+                tint = MaterialTheme.colorScheme.primary,
+            )
+            SettingsTitle(stringResource(R.string.sim_onboarding_bottomsheets_title))
+            Column(Modifier.padding(SettingsDimension.itemPadding)) {
+                Text(
+                    text = stringResource(R.string.sim_onboarding_bottomsheets_msg),
+                    color = MaterialTheme.colorScheme.onSurfaceVariant,
+                    style = MaterialTheme.typography.bodyMedium,
+                    overflow = TextOverflow.Ellipsis,
+                    textAlign = TextAlign.Center
+                )
+            }
+            Button(onClick = nextAction) {
+                Text(stringResource(R.string.sim_onboarding_setup))
+            }
+        }
+    }
+
+    @OptIn(ExperimentalMaterial3Api::class)
+    @Composable
+    fun BottomSheetImpl(
+        sheetState: SheetState,
+        nextAction: () -> Unit,
+        cancelAction: () -> Unit,
+    ) {
+        ModalBottomSheet(
+            onDismissRequest = cancelAction,
+            sheetState = sheetState,
+        ) {
+            BottomSheetBody(nextAction = nextAction)
+        }
+        LaunchedEffect(Unit) {
+            sheetState.show()
+        }
+    }
+
+    fun setProgressState(state: Int) {
+        val prefs = getSharedPreferences(
+            SubscriptionActionDialogActivity.SIM_ACTION_DIALOG_PREFS,
+            MODE_PRIVATE
+        )
+        prefs.edit().putInt(SubscriptionActionDialogActivity.KEY_PROGRESS_STATE, state).apply()
+        Log.i(TAG, "setProgressState:$state")
+    }
+
+    fun initServiceData(context: Context,targetSubId: Int, callback:(Int)->Unit) {
+        onboardingService.initData(targetSubId, context,callback)
+    }
+
+    companion object {
+        @JvmStatic
+        fun startSimOnboardingActivity(
+            context: Context,
+            subId: Int,
+        ) {
+            val intent = Intent(context, SimOnboardingActivity::class.java).apply {
+                putExtra(SUB_ID, subId)
+            }
+            context.startActivity(intent)
+        }
+
+        var onboardingService:SimOnboardingService = SimOnboardingService()
+        const val TAG = "SimOnboardingActivity"
+        const val SUB_ID = "sub_id"
+        const val CALLBACK_ERROR = -1
+        const val CALLBACK_ONBOARDING_COMPLETE = 1
+        const val CALLBACK_SETUP_NAME = 2
+        const val CALLBACK_SETUP_PRIMARY_SIM = 3
+        const val CALLBACK_FINISH = 4
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/network/SimOnboardingService.kt b/src/com/android/settings/network/SimOnboardingService.kt
index 1b3994e..8679385 100644
--- a/src/com/android/settings/network/SimOnboardingService.kt
+++ b/src/com/android/settings/network/SimOnboardingService.kt
@@ -23,11 +23,17 @@
 import android.telephony.UiccCardInfo
 import android.telephony.UiccSlotInfo
 import android.util.Log
+import com.android.settings.spa.network.setAutomaticData
+import com.android.settings.spa.network.setDefaultData
+import com.android.settings.spa.network.setDefaultSms
+import com.android.settings.spa.network.setDefaultVoice
 import com.android.settingslib.utils.ThreadUtils
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
 
 
 private const val TAG = "SimOnboardingService"
-private const val INVALID = -1
+private const val INVALID = SubscriptionManager.INVALID_SUBSCRIPTION_ID
 
 class SimOnboardingService {
     var subscriptionManager:SubscriptionManager? = null
@@ -40,19 +46,72 @@
     var slotInfoList: List<UiccSlotInfo> = listOf()
     var uiccCardInfoList: List<UiccCardInfo> = listOf()
     var selectedSubInfoList: MutableList<SubscriptionInfo> = mutableListOf()
-    var targetPrimarySimCalls: Int = -1
-    var targetPrimarySimTexts: Int = -1
-    var targetPrimarySimMobileData: Int = -1
+    var targetPrimarySimCalls: Int = SubscriptionManager.INVALID_SUBSCRIPTION_ID
+    var targetPrimarySimTexts: Int = SubscriptionManager.INVALID_SUBSCRIPTION_ID
+    var targetPrimarySimMobileData: Int = SubscriptionManager.INVALID_SUBSCRIPTION_ID
+    var targetPrimarySimAutoDataSwitch: Boolean = false
+    var targetNonDds: Int = SubscriptionManager.INVALID_SUBSCRIPTION_ID
+        get() {
+            if(targetPrimarySimMobileData == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+                Log.w(TAG, "No DDS")
+                return SubscriptionManager.INVALID_SUBSCRIPTION_ID
+            }
+            return selectedSubInfoList
+                .filter { info ->
+                    (info.simSlotIndex != -1) && (info.subscriptionId != targetPrimarySimMobileData)
+                }
+                .map { it.subscriptionId }
+                .firstOrNull() ?: SubscriptionManager.INVALID_SUBSCRIPTION_ID
+        }
+    var callback: (Int) -> Unit = {}
+
     var isMultipleEnabledProfilesSupported: Boolean = false
         get() {
             if (uiccCardInfoList.isEmpty()) {
                 Log.w(TAG, "UICC cards info list is empty.")
                 return false
             }
-            return uiccCardInfoList.stream()
-                .anyMatch { cardInfo: UiccCardInfo -> cardInfo.isMultipleEnabledProfilesSupported }
+            return  uiccCardInfoList.any { it.isMultipleEnabledProfilesSupported }
         }
+    var isRemovableSimEnabled: Boolean = false
+        get() {
+            if(slotInfoList.isEmpty()) {
+                Log.w(TAG, "UICC Slot info list is empty.")
+                return false
+            }
+            return UiccSlotUtil.isRemovableSimEnabled(slotInfoList)
+        }
+
+    var doesTargetSimHaveEsimOperation = false
+        get() {
+            return targetSubInfo?.isEmbedded ?: false
+        }
+
+    var isUsableTargetSubscriptionId = false
+        get() {
+            return SubscriptionManager.isUsableSubscriptionId(targetSubId)
+        }
+    var getActiveModemCount = 0
+        get() {
+            return telephonyManager?.getActiveModemCount() ?: 0
+        }
+
     var renameMutableMap : MutableMap<Int, String> = mutableMapOf()
+    var userSelectedSubInfoList : MutableList<SubscriptionInfo> = mutableListOf()
+
+    var isSimSelectionFinished = false
+        get() {
+            return getActiveModemCount != 0 && userSelectedSubInfoList.size == getActiveModemCount
+        }
+
+    var isAllOfSlotAssigned = false
+        get() {
+            if(getActiveModemCount == 0){
+                Log.e(TAG, "isAllOfSlotAssigned: getActiveModemCount is 0")
+                return true
+            }
+            return getActiveModemCount != 0 && activeSubInfoList.size == getActiveModemCount
+        }
 
     fun isValid(): Boolean {
         return targetSubId != INVALID
@@ -73,18 +132,27 @@
         targetPrimarySimCalls = -1
         targetPrimarySimTexts = -1
         targetPrimarySimMobileData = -1
-        renameMutableMap.clear()
+        clearUserRecord()
     }
 
-    fun initData(inputTargetSubId:Int,context: Context) {
+    fun clearUserRecord(){
+        renameMutableMap.clear()
+        userSelectedSubInfoList.clear()
+    }
+
+    fun initData(inputTargetSubId:Int,context: Context, callback: (Int) -> Unit) {
+        this.callback = callback
         targetSubId = inputTargetSubId
         subscriptionManager = context.getSystemService(SubscriptionManager::class.java)
         telephonyManager = context.getSystemService(TelephonyManager::class.java)
-
+        Log.d(
+            TAG, "startInit: targetSubId:$targetSubId"
+        )
         ThreadUtils.postOnBackgroundThread {
             activeSubInfoList = SubscriptionUtil.getActiveSubscriptions(subscriptionManager)
             availableSubInfoList = SubscriptionUtil.getAvailableSubscriptions(context)
             targetSubInfo = availableSubInfoList.find { subInfo -> subInfo.subscriptionId == targetSubId }
+            targetSubInfo?.let { userSelectedSubInfoList.add(it) }
             Log.d(
                 TAG, "targetSubId: $targetSubId" + ", targetSubInfo: $targetSubInfo" +
                     ". activeSubInfoList: $activeSubInfoList"
@@ -94,11 +162,24 @@
             uiccCardInfoList = telephonyManager?.uiccCardsInfo!!
             Log.d(TAG, "uiccCardInfoList: $uiccCardInfoList")
 
-            Log.d(TAG, "isMultipleEnabledProfilesSupported: $isMultipleEnabledProfilesSupported")
+            targetPrimarySimCalls = SubscriptionManager.getDefaultVoiceSubscriptionId()
+            targetPrimarySimTexts = SubscriptionManager.getDefaultSmsSubscriptionId()
+            targetPrimarySimMobileData = SubscriptionManager.getDefaultDataSubscriptionId()
+            Log.d(
+                TAG,"doesTargetSimHaveEsimOperation: $doesTargetSimHaveEsimOperation" +
+                    ", isRemovableSimEnabled: $isRemovableSimEnabled" +
+                    ", isMultipleEnabledProfilesSupported: $isMultipleEnabledProfilesSupported" +
+                    ", targetPrimarySimCalls: $targetPrimarySimCalls" +
+                    ", targetPrimarySimTexts: $targetPrimarySimTexts" +
+                    ", targetPrimarySimMobileData: $targetPrimarySimMobileData")
         }
     }
 
-    fun getSelectableSubscriptionInfo(): List<SubscriptionInfo> {
+    /**
+     * Return the subscriptionInfo list which has
+     * the target subscriptionInfo + active subscriptionInfo.
+     */
+    fun getSelectableSubscriptionInfoList(): List<SubscriptionInfo> {
         var list: MutableList<SubscriptionInfo> = mutableListOf()
         list.addAll(activeSubInfoList)
         if (!list.contains(targetSubInfo)) {
@@ -109,18 +190,102 @@
         return list.toList()
     }
 
+    /**
+     * Return the user selected SubscriptionInfo list.
+     */
+    fun getSelectedSubscriptionInfoList(): List<SubscriptionInfo> {
+        if (userSelectedSubInfoList.isEmpty()){
+            Log.d(TAG, "userSelectedSubInfoList is empty")
+            return activeSubInfoList
+        }
+        return userSelectedSubInfoList.toList()
+    }
+
     fun addItemForRenaming(subInfo: SubscriptionInfo, newName: String) {
         if (subInfo.displayName == newName) {
             return
         }
         renameMutableMap[subInfo.subscriptionId] = newName
+        Log.d(TAG, "renameMutableMap add ${subInfo.subscriptionId} & $newName into: $renameMutableMap")
     }
 
     fun getSubscriptionInfoDisplayName(subInfo: SubscriptionInfo): String {
         return renameMutableMap[subInfo.subscriptionId] ?: subInfo.displayName.toString()
     }
 
-    fun startActivatingSim(callback:() -> Unit){
+    fun addCurrentItemForSelectedSim(){
+        userSelectedSubInfoList.addAll(activeSubInfoList)
+    }
+
+    fun addItemForSelectedSim(selectedSubInfo: SubscriptionInfo) {
+        userSelectedSubInfoList.add(selectedSubInfo)
+    }
+
+    fun removeItemForSelectedSim(selectedSubInfo: SubscriptionInfo) {
+        if (userSelectedSubInfoList.contains(selectedSubInfo)) {
+            userSelectedSubInfoList.remove(selectedSubInfo)
+        }
+    }
+
+    /**
+     * Return the subscriptionInfo which will be removed in the slot during the sim onboarding.
+     * If return Null, then no subscriptionInfo will be removed in the slot.
+     */
+    fun getRemovedSim():SubscriptionInfo?{
+        return activeSubInfoList.find { !userSelectedSubInfoList.contains(it) }
+    }
+
+    fun handleTogglePsimAction() {
+        val canDisablePhysicalSubscription =
+            subscriptionManager?.canDisablePhysicalSubscription() == true
+        if (targetSubInfo != null && canDisablePhysicalSubscription) {
+            // TODO: to support disable case.
+            subscriptionManager?.setUiccApplicationsEnabled(
+                    targetSubInfo!!.subscriptionId, /*enabled=*/true)
+        } else {
+            Log.i(TAG, "The device does not support toggling pSIM. It is enough to just "
+                    + "enable the removable slot."
+            )
+        }
+    }
+
+    fun startActivatingSim(){
         // TODO: start to activate sim
+        callback(SimOnboardingActivity.CALLBACK_FINISH)
+    }
+
+    suspend fun startSetupName() {
+        withContext(Dispatchers.Default) {
+            renameMutableMap.forEach {
+                subscriptionManager?.setDisplayName(
+                    it.value, it.key,
+                    SubscriptionManager.NAME_SOURCE_USER_INPUT
+                )
+            }
+            // next action is SETUP_PRIMARY_SIM
+            callback(SimOnboardingActivity.CALLBACK_SETUP_PRIMARY_SIM)
+        }
+    }
+
+    suspend fun startSetupPrimarySim(context: Context) {
+        withContext(Dispatchers.Default) {
+            setDefaultVoice(subscriptionManager,targetPrimarySimCalls)
+            setDefaultSms(subscriptionManager,targetPrimarySimTexts)
+            setDefaultData(
+                context,
+                subscriptionManager,
+                null,
+                targetPrimarySimMobileData
+            )
+
+
+            val telephonyManagerForNonDds: TelephonyManager? =
+                context.getSystemService(TelephonyManager::class.java)
+                    ?.createForSubscriptionId(targetNonDds)
+            setAutomaticData(telephonyManagerForNonDds, targetPrimarySimAutoDataSwitch)
+
+            // no next action, send finish
+            callback(SimOnboardingActivity.CALLBACK_FINISH)
+        }
     }
 }
\ No newline at end of file
diff --git a/src/com/android/settings/network/SubscriptionUtil.java b/src/com/android/settings/network/SubscriptionUtil.java
index b6b433b..84e4e75 100644
--- a/src/com/android/settings/network/SubscriptionUtil.java
+++ b/src/com/android/settings/network/SubscriptionUtil.java
@@ -48,8 +48,6 @@
 import com.android.settings.network.helper.SubscriptionAnnotation;
 import com.android.settings.network.telephony.DeleteEuiccSubscriptionDialogActivity;
 import com.android.settings.network.telephony.ToggleSubscriptionDialogActivity;
-import com.android.settings.spa.SpaActivity;
-import com.android.settings.spa.network.SimOnboardingPageProvider;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -546,8 +544,7 @@
             return;
         }
         if (enable && Flags.isDualSimOnboardingEnabled()) {
-            String route = SimOnboardingPageProvider.INSTANCE.getRoute(subId);
-            SpaActivity.startSpaActivity(context, route);
+            SimOnboardingActivity.startSimOnboardingActivity(context, subId);
             return;
         }
         context.startActivity(ToggleSubscriptionDialogActivity.getIntent(context, subId, enable));
diff --git a/src/com/android/settings/network/UiccSlotUtil.java b/src/com/android/settings/network/UiccSlotUtil.java
index 5175c23..df23f12 100644
--- a/src/com/android/settings/network/UiccSlotUtil.java
+++ b/src/com/android/settings/network/UiccSlotUtil.java
@@ -463,17 +463,27 @@
         if (telMgr == null) {
             return false;
         }
-        ImmutableList<UiccSlotInfo> slotInfos = UiccSlotUtil.getSlotInfos(telMgr);
+        List<UiccSlotInfo> slotInfos = UiccSlotUtil.getSlotInfos(telMgr);
+        return isRemovableSimEnabled(slotInfos);
+    }
+
+    /**
+     * Return whether the removable psim is enabled.
+     *
+     * @param slotInfos is a List of UiccSlotInfo.
+     * @return whether the removable psim is enabled.
+     */
+    public static boolean isRemovableSimEnabled(List<UiccSlotInfo> slotInfos) {
         boolean isRemovableSimEnabled =
                 slotInfos.stream()
                         .anyMatch(
                                 slot -> slot != null
                                         && slot.isRemovable()
                                         && !slot.getIsEuicc()
-                                        && slot.getPorts().stream().anyMatch(
-                                                port -> port.isActive())
+                                        && slot.getPorts().stream()
+                                                .anyMatch(port -> port.isActive())
                                         && slot.getCardStateInfo()
-                                                == UiccSlotInfo.CARD_STATE_INFO_PRESENT);
+                                        == UiccSlotInfo.CARD_STATE_INFO_PRESENT);
         Log.i(TAG, "isRemovableSimEnabled: " + isRemovableSimEnabled);
         return isRemovableSimEnabled;
     }
diff --git a/src/com/android/settings/nfc/NfcForegroundPreferenceController.java b/src/com/android/settings/nfc/NfcForegroundPreferenceController.java
index a4cad87..b036da2 100644
--- a/src/com/android/settings/nfc/NfcForegroundPreferenceController.java
+++ b/src/com/android/settings/nfc/NfcForegroundPreferenceController.java
@@ -16,6 +16,7 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.permission.flags.Flags;
 
 import androidx.preference.ListPreference;
 import androidx.preference.Preference;
@@ -68,6 +69,9 @@
 
     @Override
     public int getAvailabilityStatus() {
+        if (Flags.walletRoleEnabled()) {
+            return UNSUPPORTED_ON_DEVICE;
+        }
         final PackageManager pm = mContext.getPackageManager();
         if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC)) {
             return UNSUPPORTED_ON_DEVICE;
diff --git a/src/com/android/settings/notification/PoliteNotifWorkProfileToggleController.java b/src/com/android/settings/notification/PoliteNotifWorkProfileToggleController.java
index 65b4fb8..99d0a69 100644
--- a/src/com/android/settings/notification/PoliteNotifWorkProfileToggleController.java
+++ b/src/com/android/settings/notification/PoliteNotifWorkProfileToggleController.java
@@ -62,7 +62,7 @@
     @Override
     public boolean isChecked() {
         return Settings.System.getIntForUser(mContext.getContentResolver(),
-                Settings.System.NOTIFICATION_COOLDOWN_ENABLED, OFF, mManagedProfileId) != OFF;
+                Settings.System.NOTIFICATION_COOLDOWN_ENABLED, ON, mManagedProfileId) != OFF;
     }
 
     @Override
diff --git a/src/com/android/settings/sim/SimDialogActivity.java b/src/com/android/settings/sim/SimDialogActivity.java
index d65b2d1..4544e73 100644
--- a/src/com/android/settings/sim/SimDialogActivity.java
+++ b/src/com/android/settings/sim/SimDialogActivity.java
@@ -41,6 +41,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
+import com.android.settings.flags.Flags;
 import com.android.settings.network.CarrierConfigCache;
 import com.android.settings.network.SubscriptionUtil;
 import com.android.settings.network.ims.WifiCallingQueryImsState;
@@ -134,6 +135,17 @@
             return;
         }
 
+        if (Flags.isDualSimOnboardingEnabled()
+                && getProgressState() == SubscriptionActionDialogActivity.PROGRESS_IS_SHOWING
+                && (dialogType == PREFERRED_PICK
+                || dialogType == DATA_PICK
+                || dialogType == CALLS_PICK
+                || dialogType == SMS_PICK)) {
+            Log.d(TAG, "Finish the sim dialog since the sim onboarding is shown");
+            finish();
+            return;
+        }
+
         final String tag = Integer.toString(dialogType);
         final FragmentManager fragmentManager = getSupportFragmentManager();
         SimDialogFragment fragment = (SimDialogFragment) fragmentManager.findFragmentByTag(tag);
diff --git a/src/com/android/settings/spa/app/appinfo/AppButtons.kt b/src/com/android/settings/spa/app/appinfo/AppButtons.kt
index dcce1d9..3d9c4b1 100644
--- a/src/com/android/settings/spa/app/appinfo/AppButtons.kt
+++ b/src/com/android/settings/spa/app/appinfo/AppButtons.kt
@@ -17,8 +17,8 @@
 package com.android.settings.spa.app.appinfo
 
 import android.content.pm.ApplicationInfo
-import android.content.pm.FeatureFlags
-import android.content.pm.FeatureFlagsImpl
+import android.content.pm.FeatureFlags as PmFeatureFlags
+import android.content.pm.FeatureFlagsImpl as PmFeatureFlagsImpl
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.remember
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -34,7 +34,7 @@
 fun AppButtons(
     packageInfoPresenter: PackageInfoPresenter,
     isHibernationSwitchEnabledStateFlow: MutableStateFlow<Boolean>,
-    featureFlags: FeatureFlags = FeatureFlagsImpl()
+    featureFlags: PmFeatureFlags = PmFeatureFlagsImpl()
 ) {
     if (remember(packageInfoPresenter) { packageInfoPresenter.isMainlineModule() }) return
     val presenter = remember {
@@ -53,7 +53,7 @@
 private class AppButtonsPresenter(
     private val packageInfoPresenter: PackageInfoPresenter,
     isHibernationSwitchEnabledStateFlow: MutableStateFlow<Boolean>,
-    private val featureFlags: FeatureFlags
+    private val featureFlags: PmFeatureFlags
 ) {
     private val appLaunchButton = AppLaunchButton(packageInfoPresenter)
     private val appInstallButton = AppInstallButton(packageInfoPresenter)
diff --git a/src/com/android/settings/spa/app/appinfo/AppInfoSettings.kt b/src/com/android/settings/spa/app/appinfo/AppInfoSettings.kt
index dba6184..695e114 100644
--- a/src/com/android/settings/spa/app/appinfo/AppInfoSettings.kt
+++ b/src/com/android/settings/spa/app/appinfo/AppInfoSettings.kt
@@ -18,9 +18,8 @@
 
 import android.app.settings.SettingsEnums
 import android.content.pm.ApplicationInfo
-import android.content.pm.FeatureFlags
-import android.content.pm.FeatureFlagsImpl
 import android.os.Bundle
+import android.os.SystemProperties
 import android.os.UserHandle
 import android.util.FeatureFlagUtils
 import androidx.compose.runtime.Composable
@@ -51,6 +50,8 @@
 import com.android.settingslib.spaprivileged.model.app.toRoute
 import com.android.settingslib.spaprivileged.template.app.AppInfoProvider
 import kotlinx.coroutines.flow.MutableStateFlow
+import android.content.pm.FeatureFlags as PmFeatureFlags
+import android.content.pm.FeatureFlagsImpl as PmFeatureFlagsImpl
 
 private const val PACKAGE_NAME = "packageName"
 private const val USER_ID = "userId"
@@ -121,7 +122,7 @@
 @Composable
 private fun AppInfoSettings(packageInfoPresenter: PackageInfoPresenter) {
     val packageInfoState = packageInfoPresenter.flow.collectAsStateWithLifecycle()
-    val featureFlags: FeatureFlags = FeatureFlagsImpl()
+    val featureFlags: PmFeatureFlags = PmFeatureFlagsImpl()
     RegularScaffold(
         title = stringResource(R.string.application_info_label),
         actions = {
@@ -177,5 +178,6 @@
     }
 }
 
-fun isArchivingEnabled(featureFlags: FeatureFlags) =
-        featureFlags.archiving() || "true" == System.getProperty("pm.archiving.enabled")
+fun isArchivingEnabled(featureFlags: PmFeatureFlags) =
+        featureFlags.archiving() || SystemProperties.getBoolean("pm.archiving.enabled", false)
+                || Flags.appArchiving()
\ No newline at end of file
diff --git a/src/com/android/settings/spa/app/appinfo/HibernationSwitchPreference.kt b/src/com/android/settings/spa/app/appinfo/HibernationSwitchPreference.kt
index 4f47266..86d7f44 100644
--- a/src/com/android/settings/spa/app/appinfo/HibernationSwitchPreference.kt
+++ b/src/com/android/settings/spa/app/appinfo/HibernationSwitchPreference.kt
@@ -22,8 +22,9 @@
 import android.app.AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED
 import android.content.Context
 import android.content.pm.ApplicationInfo
-import android.content.pm.Flags
+import android.content.pm.Flags as PmFlags
 import android.os.Build
+import android.os.SystemProperties
 import android.permission.PermissionControllerManager.HIBERNATION_ELIGIBILITY_EXEMPT_BY_SYSTEM
 import android.permission.PermissionControllerManager.HIBERNATION_ELIGIBILITY_UNKNOWN
 import android.provider.DeviceConfig
@@ -36,6 +37,7 @@
 import com.android.settings.R
 import com.android.settings.Utils.PROPERTY_APP_HIBERNATION_ENABLED
 import com.android.settings.Utils.PROPERTY_HIBERNATION_TARGETS_PRE_S_APPS
+import com.android.settings.flags.Flags
 import com.android.settingslib.spa.framework.compose.OverridableFlow
 import com.android.settingslib.spa.widget.preference.SwitchPreference
 import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
@@ -91,7 +93,8 @@
 }
 
 private fun isArchivingEnabled() =
-        Flags.archiving() || "true" == System.getProperty("pm.archiving.enabled")
+        PmFlags.archiving() || SystemProperties.getBoolean("pm.archiving.enabled", false)
+                || Flags.appArchiving()
 
 private class HibernationSwitchPresenter(context: Context, private val app: ApplicationInfo) {
     private val appOpsManager = context.appOpsManager
diff --git a/src/com/android/settings/spa/app/appinfo/PackageInfoPresenter.kt b/src/com/android/settings/spa/app/appinfo/PackageInfoPresenter.kt
index 230ccb9..81abae5 100644
--- a/src/com/android/settings/spa/app/appinfo/PackageInfoPresenter.kt
+++ b/src/com/android/settings/spa/app/appinfo/PackageInfoPresenter.kt
@@ -20,14 +20,16 @@
 import android.content.Context
 import android.content.Intent
 import android.content.IntentFilter
-import android.content.pm.FeatureFlags
-import android.content.pm.FeatureFlagsImpl
+import android.content.pm.FeatureFlags as PmFeatureFlags
+import android.content.pm.FeatureFlagsImpl as PmFeatureFlagsImpl
 import android.content.pm.PackageInfo
 import android.content.pm.PackageManager
 import android.os.UserHandle
 import android.util.Log
 import androidx.annotation.VisibleForTesting
 import androidx.compose.runtime.Composable
+import com.android.settings.flags.FeatureFlags
+import com.android.settings.flags.FeatureFlagsImpl
 import com.android.settings.overlay.FeatureFactory.Companion.featureFactory
 import com.android.settings.spa.app.startUninstallActivity
 import com.android.settingslib.spa.framework.compose.LocalNavController
@@ -60,7 +62,7 @@
     val userId: Int,
     private val coroutineScope: CoroutineScope,
     private val packageManagers: IPackageManagers = PackageManagers,
-    private val featureFlags: FeatureFlags = FeatureFlagsImpl(),
+    private val featureFlags: PmFeatureFlags = PmFeatureFlagsImpl(),
 ) {
     private val metricsFeatureProvider = featureFactory.metricsFeatureProvider
     private val userHandle = UserHandle.of(userId)
diff --git a/src/com/android/settings/spa/app/specialaccess/AlarmsAndRemindersAppList.kt b/src/com/android/settings/spa/app/specialaccess/AlarmsAndRemindersAppList.kt
index 3e48aa5..2b8d12d 100644
--- a/src/com/android/settings/spa/app/specialaccess/AlarmsAndRemindersAppList.kt
+++ b/src/com/android/settings/spa/app/specialaccess/AlarmsAndRemindersAppList.kt
@@ -27,7 +27,8 @@
 import androidx.compose.runtime.Composable
 import com.android.settings.overlay.FeatureFactory.Companion.featureFactory
 import com.android.settingslib.R
-import com.android.settingslib.spa.livedata.observeAsCallback
+import com.android.settingslib.spa.lifecycle.collectAsCallbackWithLifecycle
+import com.android.settingslib.spaprivileged.model.app.AppOpsController
 import com.android.settingslib.spaprivileged.model.app.AppRecord
 import com.android.settingslib.spaprivileged.model.app.IPackageManagers
 import com.android.settingslib.spaprivileged.model.app.PackageManagers
@@ -47,7 +48,7 @@
     override val app: ApplicationInfo,
     val isTrumped: Boolean,
     val isChangeable: Boolean,
-    var controller: AlarmsAndRemindersController,
+    var controller: AppOpsController,
 ) : AppRecord
 
 class AlarmsAndRemindersAppListModel(
@@ -82,7 +83,7 @@
     @Composable
     override fun isAllowed(record: AlarmsAndRemindersAppRecord): () -> Boolean? = when {
         record.isTrumped -> ({ true })
-        else -> record.controller.isAllowed.observeAsCallback()
+        else -> record.controller.isAllowed.collectAsCallbackWithLifecycle()
     }
 
     override fun isChangeable(record: AlarmsAndRemindersAppRecord) = record.isChangeable
@@ -112,7 +113,12 @@
             app = app,
             isTrumped = isTrumped,
             isChangeable = hasRequestPermission && !isTrumped,
-            controller = AlarmsAndRemindersController(context, app),
+            controller = AppOpsController(
+                context = context,
+                app = app,
+                op = AppOpsManager.OP_SCHEDULE_EXACT_ALARM,
+                setModeByUid = true,
+            ),
         )
     }
 
diff --git a/src/com/android/settings/spa/app/specialaccess/AlarmsAndRemindersController.kt b/src/com/android/settings/spa/app/specialaccess/AlarmsAndRemindersController.kt
deleted file mode 100644
index bd40f45..0000000
--- a/src/com/android/settings/spa/app/specialaccess/AlarmsAndRemindersController.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.spa.app.specialaccess
-
-import android.app.AppOpsManager
-import android.app.AppOpsManager.MODE_ALLOWED
-import android.app.AppOpsManager.MODE_ERRORED
-import android.content.Context
-import android.content.pm.ApplicationInfo
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.MutableLiveData
-import com.android.settingslib.spaprivileged.framework.common.alarmManager
-import com.android.settingslib.spaprivileged.framework.common.appOpsManager
-import com.android.settingslib.spaprivileged.model.app.userId
-
-class AlarmsAndRemindersController(
-    context: Context,
-    private val app: ApplicationInfo,
-) {
-    private val alarmManager = context.alarmManager
-    private val appOpsManager = context.appOpsManager
-
-    val isAllowed: LiveData<Boolean>
-        get() = _allowed
-
-    fun setAllowed(allowed: Boolean) {
-        val mode = if (allowed) MODE_ALLOWED else MODE_ERRORED
-        appOpsManager.setUidMode(AppOpsManager.OP_SCHEDULE_EXACT_ALARM, app.uid, mode)
-        _allowed.postValue(allowed)
-    }
-
-    private val _allowed = object : MutableLiveData<Boolean>() {
-        override fun onActive() {
-            postValue(alarmManager.hasScheduleExactAlarm(app.packageName, app.userId))
-        }
-    }
-}
diff --git a/src/com/android/settings/spa/network/NetworkCellularGroupProvider.kt b/src/com/android/settings/spa/network/NetworkCellularGroupProvider.kt
index e746d4a..b6d83f2 100644
--- a/src/com/android/settings/spa/network/NetworkCellularGroupProvider.kt
+++ b/src/com/android/settings/spa/network/NetworkCellularGroupProvider.kt
@@ -67,6 +67,7 @@
 
 import com.android.settingslib.spaprivileged.model.enterprise.Restrictions
 import com.android.settingslib.spaprivileged.template.preference.RestrictedPreference
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.combine
@@ -171,6 +172,8 @@
                     .map { it.subscriptionId }
                     .firstOrNull() ?: SubscriptionManager.INVALID_SUBSCRIPTION_ID
         }
+
+        Log.d(name, "defaultDataSubId: $defaultDataSubId, nonDds: $nonDds")
     }
 }
 
@@ -195,7 +198,6 @@
                 selectableSubscriptionInfoList
         )
         PrimarySimSectionImpl(
-                subscriptionManager,
                 activeSubscriptionInfoList,
                 defaultVoiceSubId,
                 defaultSmsSubId,
@@ -257,12 +259,49 @@
 
 @Composable
 fun PrimarySimSectionImpl(
-        subscriptionManager: SubscriptionManager?,
-        activeSubscriptionInfoList: List<SubscriptionInfo>,
-        callsSelectedId: MutableIntState,
-        textsSelectedId: MutableIntState,
-        mobileDataSelectedId: MutableIntState,
-        nonDds: MutableIntState
+    subscriptionInfoList: List<SubscriptionInfo>,
+    callsSelectedId: MutableIntState,
+    textsSelectedId: MutableIntState,
+    mobileDataSelectedId: MutableIntState,
+    nonDds: MutableIntState,
+    subscriptionManager: SubscriptionManager? =
+        LocalContext.current.getSystemService(SubscriptionManager::class.java),
+    coroutineScope: CoroutineScope = rememberCoroutineScope(),
+    context: Context = LocalContext.current,
+    actionSetCalls: (Int) -> Unit = {
+        callsSelectedId.intValue = it
+        coroutineScope.launch {
+            setDefaultVoice(subscriptionManager, it)
+        }
+    },
+    actionSetTexts: (Int) -> Unit = {
+        textsSelectedId.intValue = it
+        coroutineScope.launch {
+            setDefaultSms(subscriptionManager, it)
+        }
+    },
+    actionSetMobileData: (Int) -> Unit = {
+        mobileDataSelectedId.intValue = it
+        coroutineScope.launch {
+            // TODO: to fix the WifiPickerTracker crash when create
+            //       the wifiPickerTrackerHelper
+            setDefaultData(
+                context,
+                subscriptionManager,
+                null/*wifiPickerTrackerHelper*/,
+                it
+            )
+        }
+    },
+    actionSetAutoDataSwitch: (Boolean) -> Unit = { newState ->
+        coroutineScope.launch {
+            val telephonyManagerForNonDds: TelephonyManager? =
+                context.getSystemService(TelephonyManager::class.java)
+                    ?.createForSubscriptionId(nonDds.intValue)
+            Log.d(NetworkCellularGroupProvider.name, "NonDds:${nonDds.intValue} setAutomaticData")
+            setAutomaticData(telephonyManagerForNonDds, newState)
+        }
+    },
 ) {
     var state = rememberSaveable { mutableStateOf(false) }
     var callsAndSmsList = remember {
@@ -272,11 +311,11 @@
         mutableListOf(ListPreferenceOption(id = -1, text = "Loading"))
     }
 
-    if (activeSubscriptionInfoList.size >= 2) {
+    if (subscriptionInfoList.size >= 2) {
         state.value = true
         callsAndSmsList.clear()
         dataList.clear()
-        for (info in activeSubscriptionInfoList) {
+        for (info in subscriptionInfoList) {
             var item = ListPreferenceOption(
                     id = info.subscriptionId,
                     text = "${info.displayName}"
@@ -291,12 +330,10 @@
     } else {
         // hide the primary sim
         state.value = false
-        Log.d("NetworkCellularGroupProvider", "Hide primary sim")
+        Log.d(NetworkCellularGroupProvider.name, "Hide primary sim")
     }
 
     if (state.value) {
-        val coroutineScope = rememberCoroutineScope()
-        var context = LocalContext.current
         val telephonyManagerForNonDds: TelephonyManager? =
                 context.getSystemService(TelephonyManager::class.java)
                         ?.createForSubscriptionId(nonDds.intValue)
@@ -305,44 +342,27 @@
         }
 
         Category(title = stringResource(id = R.string.primary_sim_title)) {
-            createPrimarySimListPreference(
+            CreatePrimarySimListPreference(
                     stringResource(id = R.string.primary_sim_calls_title),
                     callsAndSmsList,
                     callsSelectedId,
                     ImageVector.vectorResource(R.drawable.ic_phone),
-            ) {
-                callsSelectedId.intValue = it
-                coroutineScope.launch {
-                    setDefaultVoice(subscriptionManager, it)
-                }
-            }
-            createPrimarySimListPreference(
+                    actionSetCalls
+            )
+            CreatePrimarySimListPreference(
                     stringResource(id = R.string.primary_sim_texts_title),
                     callsAndSmsList,
                     textsSelectedId,
                     Icons.AutoMirrored.Outlined.Message,
-            ) {
-                textsSelectedId.intValue = it
-                coroutineScope.launch {
-                    setDefaultSms(subscriptionManager, it)
-                }
-            }
-            createPrimarySimListPreference(
+                    actionSetTexts
+            )
+            CreatePrimarySimListPreference(
                     stringResource(id = R.string.mobile_data_settings_title),
                     dataList,
                     mobileDataSelectedId,
                     Icons.Outlined.DataUsage,
-            ) {
-                mobileDataSelectedId.intValue = it
-                coroutineScope.launch {
-                    // TODO: to fix the WifiPickerTracker crash when create
-                    //       the wifiPickerTrackerHelper
-                    setDefaultData(context,
-                            subscriptionManager,
-                            null/*wifiPickerTrackerHelper*/,
-                            it)
-                }
-            }
+                    actionSetMobileData
+            )
         }
 
         val autoDataTitle = stringResource(id = R.string.primary_sim_automatic_data_title)
@@ -351,25 +371,18 @@
             object : SwitchPreferenceModel {
                 override val title = autoDataTitle
                 override val summary = { autoDataSummary }
-                override val changeable: () -> Boolean = {
-                    nonDds.intValue != SubscriptionManager.INVALID_SUBSCRIPTION_ID
-                }
                 override val checked = {
-                    coroutineScope.launch {
-                        withContext(Dispatchers.Default) {
-                            automaticDataChecked.value = telephonyManagerForNonDds != null
-                                    && telephonyManagerForNonDds.isMobileDataPolicyEnabled(
-                                    TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH)
+                    if (nonDds.intValue != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+                        coroutineScope.launch {
+                            automaticDataChecked.value = getAutomaticData(telephonyManagerForNonDds)
                         }
                     }
                     automaticDataChecked.value
                 }
-                override val onCheckedChange: ((Boolean) -> Unit)? =
-                        { newChecked: Boolean ->
-                            coroutineScope.launch {
-                                setAutomaticData(telephonyManagerForNonDds, newChecked)
-                            }
-                        }
+                override val onCheckedChange: ((Boolean) -> Unit)? = {
+                    automaticDataChecked.value = it
+                    actionSetAutoDataSwitch(it)
+                }
             }
         })
     }
@@ -428,19 +441,19 @@
     return MobileNetworkUtils.showEuiccSettings(context)
 }
 
-private suspend fun setDefaultVoice(
+suspend fun setDefaultVoice(
         subscriptionManager: SubscriptionManager?,
         subId: Int): Unit = withContext(Dispatchers.Default) {
     subscriptionManager?.setDefaultVoiceSubscriptionId(subId)
 }
 
-private suspend fun setDefaultSms(
+suspend fun setDefaultSms(
         subscriptionManager: SubscriptionManager?,
         subId: Int): Unit = withContext(Dispatchers.Default) {
     subscriptionManager?.setDefaultSmsSubId(subId)
 }
 
-private suspend fun setDefaultData(context: Context,
+suspend fun setDefaultData(context: Context,
                                    subscriptionManager: SubscriptionManager?,
                                    wifiPickerTrackerHelper: WifiPickerTrackerHelper?,
                                    subId: Int): Unit = withContext(Dispatchers.Default) {
@@ -455,11 +468,22 @@
         wifiPickerTrackerHelper.setCarrierNetworkEnabled(true)
     }
 }
+suspend fun getAutomaticData(telephonyManagerForNonDds: TelephonyManager?): Boolean =
+    withContext(Dispatchers.Default) {
+        telephonyManagerForNonDds != null
+            && telephonyManagerForNonDds.isMobileDataPolicyEnabled(
+            TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH)
+    }
 
-private suspend fun setAutomaticData(telephonyManager: TelephonyManager?, newState: Boolean): Unit =
-        withContext(Dispatchers.Default) {
-            telephonyManager?.setMobileDataPolicyEnabled(
-                    TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH,
-                    newState)
-            //TODO: setup backup calling
-        }
\ No newline at end of file
+suspend fun setAutomaticData(telephonyManager: TelephonyManager?, newState: Boolean): Unit =
+    withContext(Dispatchers.Default) {
+        Log.d(
+            "NetworkCellularGroupProvider",
+            "setAutomaticData: MOBILE_DATA_POLICY_AUTO_DATA_SWITCH as $newState"
+        )
+        telephonyManager?.setMobileDataPolicyEnabled(
+            TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH,
+            newState
+        )
+        //TODO: setup backup calling
+    }
\ No newline at end of file
diff --git a/src/com/android/settings/spa/network/SimOnboardingLabelSim.kt b/src/com/android/settings/spa/network/SimOnboardingLabelSim.kt
index 4cb04b6..e88c5c7 100644
--- a/src/com/android/settings/spa/network/SimOnboardingLabelSim.kt
+++ b/src/com/android/settings/spa/network/SimOnboardingLabelSim.kt
@@ -27,11 +27,9 @@
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.stringResource
 import com.android.settings.R
 import com.android.settings.network.SimOnboardingService
-import com.android.settings.network.SubscriptionUtil
 import com.android.settingslib.spa.framework.theme.SettingsDimension
 import com.android.settingslib.spa.widget.dialog.AlertDialogButton
 import com.android.settingslib.spa.widget.dialog.rememberAlertDialogPresenter
@@ -74,7 +72,7 @@
         SettingsBody(stringResource(R.string.sim_onboarding_label_sim_msg))
     }
 
-    for (subInfo in onboardingService.getSelectableSubscriptionInfo()) {
+    for (subInfo in onboardingService.getSelectableSubscriptionInfoList()) {
         var titleSimName by remember {
             mutableStateOf(
                 onboardingService.getSubscriptionInfoDisplayName(subInfo)
diff --git a/src/com/android/settings/spa/network/SimOnboardingPageProvider.kt b/src/com/android/settings/spa/network/SimOnboardingPageProvider.kt
index e46dc2e..c60ac88 100644
--- a/src/com/android/settings/spa/network/SimOnboardingPageProvider.kt
+++ b/src/com/android/settings/spa/network/SimOnboardingPageProvider.kt
@@ -21,6 +21,7 @@
 import android.content.Context
 import android.content.ContextWrapper
 import android.os.Bundle
+import android.util.Log
 import androidx.annotation.VisibleForTesting
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.platform.LocalContext
@@ -31,12 +32,12 @@
 import androidx.navigation.compose.rememberNavController
 import androidx.navigation.navArgument
 import com.android.settings.R
+import com.android.settings.network.SimOnboardingActivity
 import com.android.settings.network.SimOnboardingService
 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
 import com.android.settingslib.spa.framework.common.createSettingsPage
 import com.android.settingslib.spa.framework.compose.navigator
-
 import com.android.settingslib.spa.widget.preference.Preference
 import com.android.settingslib.spa.widget.preference.PreferenceModel
 
@@ -59,7 +60,7 @@
 
     private val owner = createSettingsPage()
     @VisibleForTesting
-    var onboardingService: SimOnboardingService = SimOnboardingService()
+    var onboardingService: SimOnboardingService = SimOnboardingActivity.onboardingService
 
     fun buildInjectEntry() = SettingsEntryBuilder.createInject(owner = owner)
         .setUiLayoutFn {
@@ -72,18 +73,12 @@
 
     @Composable
     override fun Page(arguments: Bundle?) {
-        initServiceData(arguments!!.getInt(SUB_ID))
         PageImpl(onboardingService,rememberNavController())
     }
 
     fun getRoute(
         subId: Int
     ): String = "${name}/$subId"
-
-    @Composable
-    fun initServiceData(targetSubId: Int) {
-        onboardingService.initData(targetSubId, LocalContext.current)
-    }
 }
 
 private fun Context.getActivity(): Activity? = when (this) {
@@ -95,7 +90,10 @@
 @Composable
 fun PageImpl(onboardingService:SimOnboardingService,navHostController: NavHostController) {
     val context = LocalContext.current
-    var previousPageOfOnboarding: () -> Unit = { context.getActivity()?.finish() }
+    var finishOnboarding: () -> Unit = {
+        context.getActivity()?.finish()
+        onboardingService.callback(SimOnboardingActivity.CALLBACK_FINISH)
+    }
 
     NavHost(
         navController = navHostController,
@@ -103,31 +101,32 @@
     ) {
         composable(route = SimOnboardingScreen.LabelSim.name) {
             val nextPage =
-                // Adding more conditions
-                if (onboardingService.isMultipleEnabledProfilesSupported) {
+                if (onboardingService.isMultipleEnabledProfilesSupported && onboardingService.isAllOfSlotAssigned) {
                     SimOnboardingScreen.SelectSim.name
                 } else {
+                    onboardingService.addCurrentItemForSelectedSim()
                     SimOnboardingScreen.PrimarySim.name
                 }
             SimOnboardingLabelSimImpl(
                 nextAction = { navHostController.navigate(nextPage) },
-                cancelAction = previousPageOfOnboarding,
+                cancelAction = finishOnboarding,
                 onboardingService = onboardingService
             )
         }
         composable(route = SimOnboardingScreen.PrimarySim.name) {
             SimOnboardingPrimarySimImpl(
                 nextAction = {
-                    //go back and activate sim
+                    onboardingService.callback(SimOnboardingActivity.CALLBACK_ONBOARDING_COMPLETE)
+                    context.getActivity()?.finish()
                 },
-                cancelAction = previousPageOfOnboarding,
+                cancelAction = finishOnboarding,
                 onboardingService = onboardingService
             )
         }
         composable(route = SimOnboardingScreen.SelectSim.name) {
             SimOnboardingSelectSimImpl(
                 nextAction = { navHostController.navigate(SimOnboardingScreen.PrimarySim.name) },
-                cancelAction = previousPageOfOnboarding,
+                cancelAction = finishOnboarding,
                 onboardingService = onboardingService
             )
         }
diff --git a/src/com/android/settings/spa/network/SimOnboardingPrimarySim.kt b/src/com/android/settings/spa/network/SimOnboardingPrimarySim.kt
index 5752a4f..999abb4 100644
--- a/src/com/android/settings/spa/network/SimOnboardingPrimarySim.kt
+++ b/src/com/android/settings/spa/network/SimOnboardingPrimarySim.kt
@@ -16,32 +16,25 @@
 
 package com.android.settings.spa.network
 
+import android.telephony.SubscriptionManager
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.padding
 import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.outlined.Message
-import androidx.compose.material.icons.outlined.DataUsage
 import androidx.compose.material.icons.outlined.SignalCellularAlt
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.MutableIntState
-import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableIntStateOf
-import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.saveable.rememberSaveable
-import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.res.vectorResource
 import com.android.settings.R
 import com.android.settings.network.SimOnboardingService
 import com.android.settingslib.spa.framework.theme.SettingsDimension
 import com.android.settingslib.spa.widget.preference.ListPreference
 import com.android.settingslib.spa.widget.preference.ListPreferenceModel
 import com.android.settingslib.spa.widget.preference.ListPreferenceOption
-import com.android.settingslib.spa.widget.preference.SwitchPreference
-import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
 import com.android.settingslib.spa.widget.scaffold.BottomAppBarButton
 import com.android.settingslib.spa.widget.scaffold.SuwScaffold
 import com.android.settingslib.spa.widget.ui.SettingsBody
@@ -68,84 +61,54 @@
             cancelAction
         ),
     ) {
-        primarySimBody(onboardingService)
-    }
-}
-
-@Composable
-private fun primarySimBody(onboardingService: SimOnboardingService) {
-    //TODO: Load the status from the frameworks
-    var callsSelectedId = rememberSaveable { mutableIntStateOf(1) }
-    var textsSelectedId = rememberSaveable { mutableIntStateOf(1) }
-    var mobileDataSelectedId = rememberSaveable { mutableIntStateOf(1) }
-    var automaticDataChecked by rememberSaveable { mutableStateOf(true) }
-
-    Column(Modifier.padding(SettingsDimension.itemPadding)) {
-        SettingsBody(stringResource(id = R.string.sim_onboarding_primary_sim_msg))
-    }
-    var selectableSubscriptionInfo = onboardingService.getSelectableSubscriptionInfo()
-    var list = listOf(ListPreferenceOption(id = -1, text = "Loading"))
-    if (selectableSubscriptionInfo.size >= 2) {
-        list = listOf(
-            ListPreferenceOption(
-                id = selectableSubscriptionInfo[0].subscriptionId,
-                text = "${selectableSubscriptionInfo[0].displayName}"
-            ),
-            ListPreferenceOption(
-                id = selectableSubscriptionInfo[1].subscriptionId,
-                text = "${selectableSubscriptionInfo[1].displayName}"
-            ),
-            ListPreferenceOption(
-                id = -1,
-                text = stringResource(id = R.string.sim_calls_ask_first_prefs_title)
-            ),
-        )
-    } else {
-        // set all of primary sim items' enable as false and showing that sim.
-    }
-    createPrimarySimListPreference(
-        stringResource(id = R.string.primary_sim_calls_title),
-        list,
-        callsSelectedId,
-        ImageVector.vectorResource(R.drawable.ic_phone),
-        onIdSelected = { callsSelectedId.intValue = it }
-    )
-    createPrimarySimListPreference(
-        stringResource(id = R.string.primary_sim_texts_title),
-        list,
-        textsSelectedId,
-        Icons.AutoMirrored.Outlined.Message,
-        onIdSelected = { textsSelectedId.intValue = it }
-    )
-
-    createPrimarySimListPreference(
-            stringResource(id = R.string.mobile_data_settings_title),
-            list,
-            mobileDataSelectedId,
-        Icons.Outlined.DataUsage,
-            onIdSelected = { mobileDataSelectedId.intValue = it }
-    )
-
-    val autoDataTitle = stringResource(id = R.string.primary_sim_automatic_data_title)
-    val autoDataSummary = stringResource(id = R.string.primary_sim_automatic_data_msg)
-    SwitchPreference(remember {
-        object : SwitchPreferenceModel {
-            override val title = autoDataTitle
-            override val summary = { autoDataSummary }
-            override val checked = { automaticDataChecked }
-            override val onCheckedChange =
-                { newChecked: Boolean -> automaticDataChecked = newChecked }
+        val callsSelectedId = rememberSaveable {
+            mutableIntStateOf(SubscriptionManager.INVALID_SUBSCRIPTION_ID)
         }
-    })
+        val textsSelectedId = rememberSaveable {
+            mutableIntStateOf(SubscriptionManager.INVALID_SUBSCRIPTION_ID)
+        }
+        val mobileDataSelectedId = rememberSaveable {
+            mutableIntStateOf(SubscriptionManager.INVALID_SUBSCRIPTION_ID)
+        }
+        val nonDdsRemember = rememberSaveable {
+            mutableIntStateOf(SubscriptionManager.INVALID_SUBSCRIPTION_ID)
+        }
+
+        Column(Modifier.padding(SettingsDimension.itemPadding)) {
+            SettingsBody(stringResource(id = R.string.sim_onboarding_primary_sim_msg))
+        }
+
+        var selectedSubscriptionInfoList = onboardingService.getSelectedSubscriptionInfoList()
+        callsSelectedId.intValue = onboardingService.targetPrimarySimCalls
+        textsSelectedId.intValue = onboardingService.targetPrimarySimTexts
+        mobileDataSelectedId.intValue = onboardingService.targetPrimarySimMobileData
+        PrimarySimSectionImpl(
+            subscriptionInfoList = selectedSubscriptionInfoList,
+            callsSelectedId = callsSelectedId,
+            textsSelectedId = textsSelectedId,
+            mobileDataSelectedId = mobileDataSelectedId,
+            nonDds = nonDdsRemember,
+            actionSetCalls = {
+                callsSelectedId.intValue = it
+                onboardingService.targetPrimarySimCalls = it},
+            actionSetTexts = {
+                textsSelectedId.intValue = it
+                onboardingService.targetPrimarySimTexts = it},
+            actionSetMobileData = {
+                mobileDataSelectedId.intValue = it
+                onboardingService.targetPrimarySimMobileData = it},
+            actionSetAutoDataSwitch = {
+                onboardingService.targetPrimarySimAutoDataSwitch = it},
+        )
+    }
 }
 
 @Composable
-fun createPrimarySimListPreference(
+fun CreatePrimarySimListPreference(
         title: String,
         list: List<ListPreferenceOption>,
         selectedId: MutableIntState,
         icon: ImageVector,
-        enable: Boolean = true,
         onIdSelected: (id: Int) -> Unit
 ) = ListPreference(remember {
     object : ListPreferenceModel {
@@ -156,7 +119,5 @@
         override val icon = @Composable {
             SettingsIcon(icon)
         }
-        override val enabled: () -> Boolean
-            get() = { enable }
     }
 })
\ No newline at end of file
diff --git a/src/com/android/settings/spa/network/SimOnboardingSelectSim.kt b/src/com/android/settings/spa/network/SimOnboardingSelectSim.kt
index 1955d13..5e71b12 100644
--- a/src/com/android/settings/spa/network/SimOnboardingSelectSim.kt
+++ b/src/com/android/settings/spa/network/SimOnboardingSelectSim.kt
@@ -16,24 +16,23 @@
 
 package com.android.settings.spa.network
 
+import android.util.Log
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.padding
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.outlined.SignalCellularAlt
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.saveable.rememberSaveable
-import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.res.stringResource
 import com.android.settings.R
 import com.android.settings.network.SimOnboardingService
+import com.android.settings.sim.SimDialogActivity
 import com.android.settingslib.spa.framework.theme.SettingsDimension
 import com.android.settingslib.spa.widget.preference.CheckboxPreference
 import com.android.settingslib.spa.widget.preference.CheckboxPreferenceModel
-
 import com.android.settingslib.spa.widget.scaffold.BottomAppBarButton
 import com.android.settingslib.spa.widget.scaffold.SuwScaffold
 import com.android.settingslib.spa.widget.ui.SettingsBody
@@ -68,22 +67,38 @@
     Column(Modifier.padding(SettingsDimension.itemPadding)) {
         SettingsBody(stringResource(id = R.string.sim_onboarding_select_sim_msg))
     }
-    for (subInfo in onboardingService.getSelectableSubscriptionInfo()) {
+    var isFinished = rememberSaveable { mutableStateOf(false) }
+    isFinished.value = onboardingService.isSimSelectionFinished
+    for (subInfo in onboardingService.getSelectableSubscriptionInfoList()) {
         var title = onboardingService.getSubscriptionInfoDisplayName(subInfo)
         var summaryNumber =
             subInfo.number // TODO using the SubscriptionUtil.getFormattedPhoneNumber
-        var changeable = subInfo.isActive
-        var checked by rememberSaveable { mutableStateOf(!subInfo.isActive) }
+        var checked = rememberSaveable {
+            mutableStateOf(
+                onboardingService.getSelectedSubscriptionInfoList().contains(subInfo)
+            )
+        }
 
         CheckboxPreference(remember {
             object : CheckboxPreferenceModel {
                 override val title = title
                 override val summary: () -> String
                     get() = { summaryNumber }
-                override val checked = { checked }
-                override val changeable = { changeable }
-                override val onCheckedChange = { newChecked: Boolean -> checked = newChecked }
+                override val checked = { checked.value }
+                override val onCheckedChange = { newChecked: Boolean ->
+                    checked.value = newChecked
+                    if (newChecked) {
+                        onboardingService.addItemForSelectedSim(subInfo)
+                    } else {
+                        onboardingService.removeItemForSelectedSim(subInfo)
+                    }
+                    isFinished.value = onboardingService.isSimSelectionFinished
+                }
+                override val changeable = {
+                    subInfo.isActive
+                        && (!isFinished.value || (isFinished.value && checked.value))
+                }
             }
         })
     }
-}
\ No newline at end of file
+}
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index d39d980..70d8ed3 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -1771,6 +1771,9 @@
                             .updateNonIndexableKeys(niks);
                     new AutoSyncWorkDataPreferenceController(context, null /* parent */)
                             .updateNonIndexableKeys(niks);
+                    if (suppressAllPage) {
+                        niks.add(KEY_ALLOW_MULTIPLE_USERS);
+                    }
                     return niks;
                 }
             };
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragmentTest.java
index 335bbe3..966a695 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragmentTest.java
@@ -18,15 +18,18 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.when;
 import static org.robolectric.shadows.ShadowLooper.shadowMainLooper;
 
 import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothStatusCodes;
 import android.platform.test.annotations.RequiresFlagsDisabled;
 import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.view.View;
+import android.widget.Button;
 
 import androidx.appcompat.app.AlertDialog;
 import androidx.fragment.app.Fragment;
@@ -37,11 +40,13 @@
 import com.android.settings.flags.Flags;
 import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 import org.robolectric.RobolectricTestRunner;
@@ -50,6 +55,7 @@
 import org.robolectric.shadows.androidx.fragment.FragmentController;
 
 import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 @RunWith(RobolectricTestRunner.class)
 @Config(
@@ -67,38 +73,68 @@
     private static final String TEST_DEVICE_NAME1 = "test1";
     private static final String TEST_DEVICE_NAME2 = "test2";
     private static final String TEST_DEVICE_NAME3 = "test3";
+    private static final int TEST_GROUP_ID1 = 1;
+    private static final int TEST_GROUP_ID2 = 2;
+    private static final int TEST_GROUP_ID3 = 3;
     private static final AudioSharingDeviceItem TEST_DEVICE_ITEM1 =
-            new AudioSharingDeviceItem(TEST_DEVICE_NAME1, /* groupId= */ 1, /* isActive= */ true);
+            new AudioSharingDeviceItem(TEST_DEVICE_NAME1, TEST_GROUP_ID1, /* isActive= */ true);
     private static final AudioSharingDeviceItem TEST_DEVICE_ITEM2 =
-            new AudioSharingDeviceItem(TEST_DEVICE_NAME2, /* groupId= */ 2, /* isActive= */ false);
+            new AudioSharingDeviceItem(TEST_DEVICE_NAME2, TEST_GROUP_ID2, /* isActive= */ false);
+    private static final AudioSharingDeviceItem TEST_DEVICE_ITEM3 =
+            new AudioSharingDeviceItem(TEST_DEVICE_NAME3, TEST_GROUP_ID3, /* isActive= */ false);
 
+    @Mock private BluetoothDevice mDevice1;
+    @Mock private BluetoothDevice mDevice2;
+    @Mock private BluetoothDevice mDevice3;
+
+    @Mock private CachedBluetoothDevice mCachedDevice1;
+    @Mock private CachedBluetoothDevice mCachedDevice2;
+    @Mock private CachedBluetoothDevice mCachedDevice3;
     private Fragment mParent;
     private AudioSharingDisconnectDialogFragment mFragment;
     private ShadowBluetoothAdapter mShadowBluetoothAdapter;
+    private ArrayList<AudioSharingDeviceItem> mDeviceItems = new ArrayList<>();
 
     @Before
     public void setUp() {
-        ShadowAlertDialogCompat.reset();
+        AlertDialog latestAlertDialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+        if (latestAlertDialog != null) {
+            latestAlertDialog.dismiss();
+            ShadowAlertDialogCompat.reset();
+        }
         mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
         mShadowBluetoothAdapter.setEnabled(true);
         mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
                 BluetoothStatusCodes.FEATURE_SUPPORTED);
         mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
                 BluetoothStatusCodes.FEATURE_SUPPORTED);
+        when(mCachedDevice1.getName()).thenReturn(TEST_DEVICE_NAME1);
+        when(mCachedDevice1.getDevice()).thenReturn(mDevice1);
+        when(mCachedDevice1.getGroupId()).thenReturn(TEST_GROUP_ID1);
+        when(mCachedDevice2.getName()).thenReturn(TEST_DEVICE_NAME2);
+        when(mCachedDevice2.getDevice()).thenReturn(mDevice2);
+        when(mCachedDevice2.getGroupId()).thenReturn(TEST_GROUP_ID2);
+        when(mCachedDevice3.getName()).thenReturn(TEST_DEVICE_NAME3);
+        when(mCachedDevice3.getDevice()).thenReturn(mDevice3);
+        when(mCachedDevice3.getGroupId()).thenReturn(TEST_GROUP_ID3);
         mFragment = new AudioSharingDisconnectDialogFragment();
         mParent = new Fragment();
         FragmentController.setupFragment(
                 mParent, FragmentActivity.class, /* containerViewId= */ 0, /* bundle= */ null);
-        ArrayList<AudioSharingDeviceItem> list = new ArrayList<>();
-        list.add(TEST_DEVICE_ITEM1);
-        list.add(TEST_DEVICE_ITEM2);
-        mFragment.show(mParent, list, TEST_DEVICE_NAME3, (item) -> {});
+        mDeviceItems.add(TEST_DEVICE_ITEM1);
+        mDeviceItems.add(TEST_DEVICE_ITEM2);
+        mFragment.show(mParent, mDeviceItems, mCachedDevice3, (item) -> {});
         shadowMainLooper().idle();
     }
 
     @Test
     @RequiresFlagsDisabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
     public void onCreateDialog_flagOff_dialogNotExist() {
+        ArrayList<AudioSharingDeviceItem> list = new ArrayList<>();
+        list.add(TEST_DEVICE_ITEM1);
+        list.add(TEST_DEVICE_ITEM2);
+        mFragment.show(mParent, list, mCachedDevice3, (item) -> {});
+        shadowMainLooper().idle();
         AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
         assertThat(dialog).isNull();
     }
@@ -107,6 +143,7 @@
     @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
     public void onCreateDialog_flagOn_dialogShowBtnForTwoDevices() {
         AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+        assertThat(dialog.isShowing()).isTrue();
         ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog);
         View rootView = shadowDialog.getView();
         RecyclerView view = rootView.findViewById(R.id.device_btn_list);
@@ -115,8 +152,70 @@
 
     @Test
     @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
+    public void onCreateDialog_dialogIsShowingForSameGroup_updateDialog() {
+        String prefix = "Disconnect ";
+        AtomicBoolean isItemBtnClicked = new AtomicBoolean(false);
+        AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+        assertThat(dialog.isShowing()).isTrue();
+        ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog);
+        View rootView = shadowDialog.getView();
+        RecyclerView view = rootView.findViewById(R.id.device_btn_list);
+        assertThat(view.getAdapter().getItemCount()).isEqualTo(2);
+        Button btn1 =
+                view.findViewHolderForAdapterPosition(0).itemView.findViewById(R.id.device_button);
+        assertThat(btn1.getText().toString()).isEqualTo(prefix + TEST_DEVICE_NAME1);
+        Button btn2 =
+                view.findViewHolderForAdapterPosition(1).itemView.findViewById(R.id.device_button);
+        assertThat(btn2.getText().toString()).isEqualTo(prefix + TEST_DEVICE_NAME2);
+        btn1.performClick();
+        assertThat(isItemBtnClicked.get()).isFalse();
+
+        // Update dialog content with same group
+        mFragment.show(mParent, mDeviceItems, mCachedDevice3, (item) -> isItemBtnClicked.set(true));
+        shadowMainLooper().idle();
+        dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+        assertThat(dialog.isShowing()).isTrue();
+        btn1 = view.findViewHolderForAdapterPosition(0).itemView.findViewById(R.id.device_button);
+        btn1.performClick();
+        assertThat(isItemBtnClicked.get()).isTrue();
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
+    public void onCreateDialog_dialogIsShowingForNewGroup_updateDialog() {
+        String prefix = "Disconnect ";
+        AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+        assertThat(dialog.isShowing()).isTrue();
+        ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog);
+        View rootView = shadowDialog.getView();
+        RecyclerView view = rootView.findViewById(R.id.device_btn_list);
+        assertThat(view.getAdapter().getItemCount()).isEqualTo(2);
+
+        // Update dialog content with new group
+        ArrayList<AudioSharingDeviceItem> newDeviceItems = new ArrayList<>();
+        newDeviceItems.add(TEST_DEVICE_ITEM2);
+        newDeviceItems.add(TEST_DEVICE_ITEM3);
+        mFragment.show(mParent, newDeviceItems, mCachedDevice1, (item) -> {});
+        shadowMainLooper().idle();
+        dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+        assertThat(dialog.isShowing()).isTrue();
+        shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog);
+        rootView = shadowDialog.getView();
+        view = rootView.findViewById(R.id.device_btn_list);
+        assertThat(view.getAdapter().getItemCount()).isEqualTo(2);
+        Button btn1 =
+                view.findViewHolderForAdapterPosition(0).itemView.findViewById(R.id.device_button);
+        assertThat(btn1.getText().toString()).isEqualTo(prefix + TEST_DEVICE_NAME2);
+        Button btn2 =
+                view.findViewHolderForAdapterPosition(1).itemView.findViewById(R.id.device_button);
+        assertThat(btn2.getText().toString()).isEqualTo(prefix + TEST_DEVICE_NAME3);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
     public void onCreateDialog_clickCancel_dialogDismiss() {
         AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+        assertThat(dialog.isShowing()).isTrue();
         ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog);
         View rootView = shadowDialog.getView();
         rootView.findViewById(R.id.cancel_btn).performClick();
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragmentTest.java
index 38f80e0..56951c2 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragmentTest.java
@@ -18,6 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.when;
 import static org.robolectric.shadows.ShadowLooper.shadowMainLooper;
 
 import android.bluetooth.BluetoothAdapter;
@@ -27,7 +28,6 @@
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.view.View;
-import android.widget.TextView;
 
 import androidx.appcompat.app.AlertDialog;
 import androidx.fragment.app.Fragment;
@@ -37,11 +37,13 @@
 import com.android.settings.flags.Flags;
 import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 import org.robolectric.RobolectricTestRunner;
@@ -67,22 +69,32 @@
 
     private static final String TEST_DEVICE_NAME1 = "test1";
     private static final String TEST_DEVICE_NAME2 = "test2";
-    private static final AudioSharingDeviceItem TEST_DEVICE_ITEM =
+    private static final AudioSharingDeviceItem TEST_DEVICE_ITEM1 =
             new AudioSharingDeviceItem(TEST_DEVICE_NAME1, /* groupId= */ 1, /* isActive= */ true);
+    private static final AudioSharingDeviceItem TEST_DEVICE_ITEM2 =
+            new AudioSharingDeviceItem(TEST_DEVICE_NAME2, /* groupId= */ 2, /* isActive= */ false);
 
+    @Mock private CachedBluetoothDevice mCachedDevice1;
+    @Mock private CachedBluetoothDevice mCachedDevice2;
     private Fragment mParent;
     private AudioSharingJoinDialogFragment mFragment;
     private ShadowBluetoothAdapter mShadowBluetoothAdapter;
 
     @Before
     public void setUp() {
-        ShadowAlertDialogCompat.reset();
+        AlertDialog latestAlertDialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+        if (latestAlertDialog != null) {
+            latestAlertDialog.dismiss();
+            ShadowAlertDialogCompat.reset();
+        }
         mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
         mShadowBluetoothAdapter.setEnabled(true);
         mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
                 BluetoothStatusCodes.FEATURE_SUPPORTED);
         mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
                 BluetoothStatusCodes.FEATURE_SUPPORTED);
+        when(mCachedDevice1.getName()).thenReturn(TEST_DEVICE_NAME1);
+        when(mCachedDevice2.getName()).thenReturn(TEST_DEVICE_NAME2);
         mFragment = new AudioSharingJoinDialogFragment();
         mParent = new Fragment();
         FragmentController.setupFragment(
@@ -92,7 +104,7 @@
     @Test
     @RequiresFlagsDisabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
     public void onCreateDialog_flagOff_dialogNotExist() {
-        mFragment.show(mParent, new ArrayList<>(), TEST_DEVICE_NAME2, () -> {});
+        mFragment.show(mParent, new ArrayList<>(), mCachedDevice2, () -> {});
         shadowMainLooper().idle();
         AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
         assertThat(dialog).isNull();
@@ -101,37 +113,58 @@
     @Test
     @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
     public void onCreateDialog_flagOn_dialogShowTextForSingleDevice() {
-        mFragment.show(mParent, new ArrayList<>(), TEST_DEVICE_NAME2, () -> {});
+        mFragment.show(mParent, new ArrayList<>(), mCachedDevice2, () -> {});
         shadowMainLooper().idle();
         AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
         assertThat(dialog).isNotNull();
         assertThat(dialog.isShowing()).isTrue();
         ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog);
-        View rootView = shadowDialog.getView();
-        TextView subtitle1 = rootView.findViewById(R.id.share_audio_subtitle1);
-        assertThat(subtitle1.getText()).isEqualTo(TEST_DEVICE_NAME2);
+        assertThat(shadowDialog.getMessage().toString()).isEqualTo(TEST_DEVICE_NAME2);
     }
 
     @Test
     @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
     public void onCreateDialog_flagOn_dialogShowTextForTwoDevice() {
         ArrayList<AudioSharingDeviceItem> list = new ArrayList<>();
-        list.add(TEST_DEVICE_ITEM);
-        mFragment.show(mParent, list, TEST_DEVICE_NAME2, () -> {});
+        list.add(TEST_DEVICE_ITEM1);
+        mFragment.show(mParent, list, mCachedDevice2, () -> {});
         shadowMainLooper().idle();
         AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
         assertThat(dialog).isNotNull();
         assertThat(dialog.isShowing()).isTrue();
         ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog);
-        View rootView = shadowDialog.getView();
-        TextView subtitle1 = rootView.findViewById(R.id.share_audio_subtitle1);
-        assertThat(subtitle1.getText()).isEqualTo(TEST_DEVICE_NAME1 + " and " + TEST_DEVICE_NAME2);
+        assertThat(shadowDialog.getMessage().toString())
+                .isEqualTo(TEST_DEVICE_NAME1 + " and " + TEST_DEVICE_NAME2);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
+    public void onCreateDialog_dialogIsShowing_updateDialog() {
+        ArrayList<AudioSharingDeviceItem> list = new ArrayList<>();
+        list.add(TEST_DEVICE_ITEM1);
+        mFragment.show(mParent, list, mCachedDevice2, () -> {});
+        shadowMainLooper().idle();
+        AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+        assertThat(dialog).isNotNull();
+        assertThat(dialog.isShowing()).isTrue();
+
+        // Update the content
+        ArrayList<AudioSharingDeviceItem> list2 = new ArrayList<>();
+        list2.add(TEST_DEVICE_ITEM2);
+        mFragment.show(mParent, list2, mCachedDevice1, () -> {});
+        shadowMainLooper().idle();
+        dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+        assertThat(dialog).isNotNull();
+        assertThat(dialog.isShowing()).isTrue();
+        ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog);
+        assertThat(shadowDialog.getMessage().toString())
+                .isEqualTo(TEST_DEVICE_NAME2 + " and " + TEST_DEVICE_NAME1);
     }
 
     @Test
     @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
     public void onCreateDialog_clickCancel_dialogDismiss() {
-        mFragment.show(mParent, new ArrayList<>(), TEST_DEVICE_NAME2, () -> {});
+        mFragment.show(mParent, new ArrayList<>(), mCachedDevice2, () -> {});
         shadowMainLooper().idle();
         AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
         ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog);
@@ -145,7 +178,7 @@
     public void onCreateDialog_clickShare_callbackTriggered() {
         AtomicBoolean isShareBtnClicked = new AtomicBoolean(false);
         mFragment.show(
-                mParent, new ArrayList<>(), TEST_DEVICE_NAME2, () -> isShareBtnClicked.set(true));
+                mParent, new ArrayList<>(), mCachedDevice2, () -> isShareBtnClicked.set(true));
         shadowMainLooper().idle();
         AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
         ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog);
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragmentTest.java
index 61bc88a..d93105d 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragmentTest.java
@@ -18,6 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.when;
 import static org.robolectric.shadows.ShadowLooper.shadowMainLooper;
 
 import android.bluetooth.BluetoothAdapter;
@@ -34,11 +35,13 @@
 import com.android.settings.flags.Flags;
 import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 import org.robolectric.RobolectricTestRunner;
@@ -61,21 +64,30 @@
     @Rule
     public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
 
-    private static final String TEST_DEVICE_NAME = "test";
+    private static final String TEST_DEVICE_NAME1 = "test1";
+    private static final String TEST_DEVICE_NAME2 = "test2";
 
+    @Mock private CachedBluetoothDevice mCachedDevice1;
+    @Mock private CachedBluetoothDevice mCachedDevice2;
     private Fragment mParent;
     private AudioSharingStopDialogFragment mFragment;
     private ShadowBluetoothAdapter mShadowBluetoothAdapter;
 
     @Before
     public void setUp() {
-        ShadowAlertDialogCompat.reset();
+        AlertDialog latestAlertDialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+        if (latestAlertDialog != null) {
+            latestAlertDialog.dismiss();
+            ShadowAlertDialogCompat.reset();
+        }
         mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
         mShadowBluetoothAdapter.setEnabled(true);
         mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
                 BluetoothStatusCodes.FEATURE_SUPPORTED);
         mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
                 BluetoothStatusCodes.FEATURE_SUPPORTED);
+        when(mCachedDevice1.getName()).thenReturn(TEST_DEVICE_NAME1);
+        when(mCachedDevice2.getName()).thenReturn(TEST_DEVICE_NAME2);
         mFragment = new AudioSharingStopDialogFragment();
         mParent = new Fragment();
         FragmentController.setupFragment(
@@ -85,7 +97,7 @@
     @Test
     @RequiresFlagsDisabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
     public void onCreateDialog_flagOff_dialogNotExist() {
-        mFragment.show(mParent, TEST_DEVICE_NAME, () -> {});
+        mFragment.show(mParent, mCachedDevice1, () -> {});
         shadowMainLooper().idle();
         AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
         assertThat(dialog).isNull();
@@ -93,8 +105,30 @@
 
     @Test
     @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
+    public void onCreateDialog_dialogIsShowing_updateDialog() {
+        String postMessage = " wants to connect, headphones in audio sharing will disconnect.";
+        mFragment.show(mParent, mCachedDevice1, () -> {});
+        shadowMainLooper().idle();
+        AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+        assertThat(dialog).isNotNull();
+        assertThat(dialog.isShowing()).isTrue();
+        ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog);
+        assertThat(shadowDialog.getMessage().toString()).isEqualTo(TEST_DEVICE_NAME1 + postMessage);
+
+        // Update the content
+        mFragment.show(mParent, mCachedDevice2, () -> {});
+        shadowMainLooper().idle();
+        dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+        assertThat(dialog).isNotNull();
+        assertThat(dialog.isShowing()).isTrue();
+        shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog);
+        assertThat(shadowDialog.getMessage().toString()).isEqualTo(TEST_DEVICE_NAME2 + postMessage);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
     public void onCreateDialog_clickCancel_dialogDismiss() {
-        mFragment.show(mParent, TEST_DEVICE_NAME, () -> {});
+        mFragment.show(mParent, mCachedDevice1, () -> {});
         shadowMainLooper().idle();
         AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
         dialog.findViewById(android.R.id.button2).performClick();
@@ -106,7 +140,7 @@
     @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
     public void onCreateDialog_clickShare_callbackTriggered() {
         AtomicBoolean isStopBtnClicked = new AtomicBoolean(false);
-        mFragment.show(mParent, TEST_DEVICE_NAME, () -> isStopBtnClicked.set(true));
+        mFragment.show(mParent, mCachedDevice1, () -> isStopBtnClicked.set(true));
         shadowMainLooper().idle();
         AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
         dialog.findViewById(android.R.id.button1).performClick();
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsMigrateCheckerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsMigrateCheckerTest.java
index ba7e9cc..0738ebf 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsMigrateCheckerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsMigrateCheckerTest.java
@@ -98,7 +98,7 @@
 
     @Test
     public void onReceive_validScheduledLevel_notResetScheduledValue() {
-        final int validScheduledLevel = 12;
+        final int validScheduledLevel = BatterySaverScheduleRadioButtonsController.TRIGGER_LEVEL_MIN;
         setScheduledLevel(validScheduledLevel);
 
         mBatterySettingsMigrateChecker.onReceive(mContext, BOOT_COMPLETED_INTENT);
diff --git a/tests/spa_unit/src/com/android/settings/development/SensitiveContentProtectionPreferenceControllerTest.kt b/tests/spa_unit/src/com/android/settings/development/SensitiveContentProtectionPreferenceControllerTest.kt
new file mode 100644
index 0000000..bb30619
--- /dev/null
+++ b/tests/spa_unit/src/com/android/settings/development/SensitiveContentProtectionPreferenceControllerTest.kt
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2024 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.development
+
+import android.content.Context
+import android.platform.test.annotations.RequiresFlagsDisabled
+import android.platform.test.annotations.RequiresFlagsEnabled
+import android.platform.test.flag.junit.DeviceFlagsValueProvider
+import android.provider.Settings
+import android.provider.Settings.Global.DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS
+import androidx.preference.Preference
+import androidx.preference.PreferenceScreen
+import androidx.preference.SwitchPreference
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.server.notification.Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING
+import com.android.server.notification.Flags.FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION
+import com.android.settings.development.SensitiveContentProtectionPreferenceController.Companion.SETTING_VALUE_OFF
+import com.android.settings.development.SensitiveContentProtectionPreferenceController.Companion.SETTING_VALUE_ON
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.junit.MockitoJUnit
+import org.mockito.Mockito.`when` as whenever
+
+@RunWith(AndroidJUnit4::class)
+class SensitiveContentProtectionPreferenceControllerTest {
+    @get:Rule
+    val mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
+
+    @get:Rule
+    val mocks = MockitoJUnit.rule()
+
+    @Mock
+    private lateinit var preference: SwitchPreference
+
+    @Mock
+    private lateinit var screen: PreferenceScreen
+
+    private val context: Context = InstrumentationRegistry.getInstrumentation().targetContext
+    private lateinit var controller: SensitiveContentProtectionPreferenceController
+
+    @Before
+    fun setUp() {
+        controller = SensitiveContentProtectionPreferenceController(context)
+        whenever(screen.findPreference<Preference>(controller.getPreferenceKey()))
+            .thenReturn(preference)
+        controller.displayPreference(screen)
+    }
+
+    @Test
+    fun onPreferenceChange_settingEnabled_shouldDisableSensitiveContentProtection() {
+        controller.onPreferenceChange(preference, true /* new value */)
+        val mode = Settings.Global.getInt(
+            context.contentResolver,
+            DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS,
+            -1 /* default */
+        )
+
+        assertEquals(mode, SETTING_VALUE_ON)
+    }
+
+    @Test
+    fun onPreferenceChange_settingDisabled_shouldEnableSensitiveContentProtection() {
+        controller.onPreferenceChange(preference, false /* new value */)
+        val mode = Settings.Global.getInt(
+            context.contentResolver,
+            DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS,
+            -1 /* default */
+        )
+
+        assertEquals(mode, SETTING_VALUE_OFF)
+    }
+
+    @Test
+    fun updateState_settingEnabled_preferenceShouldBeChecked() {
+        Settings.Global.putInt(
+            context.contentResolver,
+            DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS,
+            SETTING_VALUE_ON
+        )
+        controller.updateState(preference)
+
+        verify(preference).isChecked = true
+    }
+
+    @Test
+    fun updateState_settingDisabled_preferenceShouldNotBeChecked() {
+        Settings.Global.putInt(
+            context.contentResolver,
+            DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS,
+            SETTING_VALUE_OFF
+        )
+        controller.updateState(preference)
+
+        verify(preference).isChecked = false
+    }
+
+    @Test
+    fun onDeveloperOptionsSwitchDisabled_preferenceShouldBeDisabled() {
+        controller.onDeveloperOptionsSwitchDisabled()
+        val mode = Settings.Global.getInt(
+            context.contentResolver,
+            DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS,
+            -1 /* default */
+        )
+
+        assertEquals(mode, SETTING_VALUE_OFF)
+        verify(preference).isChecked = false
+        verify(preference).isEnabled = false
+    }
+
+    @Test
+    @RequiresFlagsDisabled(
+        FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION,
+        FLAG_SCREENSHARE_NOTIFICATION_HIDING)
+    fun isAvailable_flagsDisabled_returnFalse() {
+        assertFalse(controller.isAvailable)
+    }
+
+    @Test
+    @RequiresFlagsEnabled(FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION)
+    fun isAvailable_sensitiveNotificationAppProtectionEnabled_returnTrue() {
+        assertTrue(controller.isAvailable)
+    }
+
+    @Test
+    @RequiresFlagsEnabled(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
+    fun isAvailable_screenshareNotificationHidingEnabled_returnTrue() {
+        assertTrue(controller.isAvailable)
+    }
+}
\ No newline at end of file
diff --git a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/HibernationSwitchPreferenceTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/HibernationSwitchPreferenceTest.kt
index cc2c1e1..b61e3a9 100644
--- a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/HibernationSwitchPreferenceTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/HibernationSwitchPreferenceTest.kt
@@ -24,8 +24,9 @@
 import android.apphibernation.AppHibernationManager
 import android.content.Context
 import android.content.pm.ApplicationInfo
-import android.content.pm.Flags
+import android.content.pm.Flags as PmFlags
 import android.os.Build
+import android.os.SystemProperties
 import android.permission.PermissionControllerManager
 import android.permission.PermissionControllerManager.HIBERNATION_ELIGIBILITY_ELIGIBLE
 import android.permission.PermissionControllerManager.HIBERNATION_ELIGIBILITY_EXEMPT_BY_SYSTEM
@@ -48,6 +49,7 @@
 import com.android.settings.R
 import com.android.settings.Utils.PROPERTY_APP_HIBERNATION_ENABLED
 import com.android.settings.Utils.PROPERTY_HIBERNATION_TARGETS_PRE_S_APPS
+import com.android.settings.flags.Flags
 import com.android.settings.testutils.TestDeviceConfig
 import com.android.settings.testutils.mockAsUser
 import com.android.settingslib.spaprivileged.framework.common.appHibernationManager
@@ -161,8 +163,8 @@
     }
 
     private fun isArchivingEnabled() =
-            Flags.archiving() || "true" == System.getProperty("pm.archiving.enabled")
-
+            PmFlags.archiving() || SystemProperties.getBoolean("pm.archiving.enabled", false)
+                    || Flags.appArchiving()
     @Test
     fun `An app targets Q with ops mode default when hibernation targets pre S - not exempted`() {
         mockOpsMode(MODE_DEFAULT)
diff --git a/tests/spa_unit/src/com/android/settings/spa/network/SimOnboardingLabelSimTest.kt b/tests/spa_unit/src/com/android/settings/spa/network/SimOnboardingLabelSimTest.kt
index dace5e9..8e12b20 100644
--- a/tests/spa_unit/src/com/android/settings/spa/network/SimOnboardingLabelSimTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/network/SimOnboardingLabelSimTest.kt
@@ -108,7 +108,7 @@
             on { targetSubInfo }.doReturn(SUB_INFO_1)
             on { availableSubInfoList }.doReturn(listOf(SUB_INFO_1, SUB_INFO_2, SUB_INFO_3))
             on { activeSubInfoList }.doReturn(listOf(SUB_INFO_2, SUB_INFO_3))
-            on { getSelectableSubscriptionInfo() }.doReturn(
+            on { getSelectableSubscriptionInfoList() }.doReturn(
                 listOf(
                     SUB_INFO_1,
                     SUB_INFO_2,
@@ -139,7 +139,7 @@
             on { targetSubInfo }.doReturn(SUB_INFO_1)
             on { availableSubInfoList }.doReturn(listOf(SUB_INFO_1, SUB_INFO_2, SUB_INFO_3))
             on { activeSubInfoList }.doReturn(listOf(SUB_INFO_2, SUB_INFO_3))
-            on { getSelectableSubscriptionInfo() }.doReturn(
+            on { getSelectableSubscriptionInfoList() }.doReturn(
                 listOf(
                     SUB_INFO_1,
                     SUB_INFO_2,
diff --git a/tests/spa_unit/src/com/android/settings/spa/network/SimOnboardingPageProviderTest.kt b/tests/spa_unit/src/com/android/settings/spa/network/SimOnboardingPageProviderTest.kt
index 35f1968..82dba76 100644
--- a/tests/spa_unit/src/com/android/settings/spa/network/SimOnboardingPageProviderTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/network/SimOnboardingPageProviderTest.kt
@@ -91,6 +91,7 @@
     fun simOnboardingPage_nextAction_fromLabelSimToSelectSim() {
         mockSimOnboardingService.stub {
             on { isMultipleEnabledProfilesSupported }.thenReturn(true)
+            on { isAllOfSlotAssigned }.thenReturn(true)
         }
 
         composeTestRule.setContent {
diff --git a/tests/spa_unit/src/com/android/settings/spa/network/SimOnboardingSelectSimTest.kt b/tests/spa_unit/src/com/android/settings/spa/network/SimOnboardingSelectSimTest.kt
index 5d7465f..45667ef 100644
--- a/tests/spa_unit/src/com/android/settings/spa/network/SimOnboardingSelectSimTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/network/SimOnboardingSelectSimTest.kt
@@ -108,7 +108,7 @@
             on { targetSubInfo }.doReturn(SUB_INFO_1)
             on { availableSubInfoList }.doReturn(listOf(SUB_INFO_1, SUB_INFO_2, SUB_INFO_3))
             on { activeSubInfoList }.doReturn(listOf(SUB_INFO_2, SUB_INFO_3))
-            on { getSelectableSubscriptionInfo() }.doReturn(
+            on { getSelectableSubscriptionInfoList() }.doReturn(
                 listOf(
                     SUB_INFO_1,
                     SUB_INFO_2,
diff --git a/tests/unit/src/com/android/settings/applications/credentials/CredentialsPickerActivityTest.java b/tests/unit/src/com/android/settings/applications/credentials/CredentialsPickerActivityTest.java
new file mode 100644
index 0000000..044c23d
--- /dev/null
+++ b/tests/unit/src/com/android/settings/applications/credentials/CredentialsPickerActivityTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications.credentials;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.UserInfo;
+import android.os.UserHandle;
+import android.os.UserManager;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.google.common.collect.Lists;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class CredentialsPickerActivityTest {
+
+    @Mock private UserManager mUserManager;
+
+    private Context mMockContext;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mMockContext = spy(ApplicationProvider.getApplicationContext());
+        when(mMockContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
+    }
+
+    @Test
+    public void testInjectFragmentIntoIntent_normalProfile() {
+        Intent intent = new Intent();
+        CredentialsPickerActivity.injectFragmentIntoIntent(mMockContext, intent);
+        assertThat(intent.getStringExtra(CredentialsPickerActivity.EXTRA_SHOW_FRAGMENT))
+                .isEqualTo(DefaultCombinedPicker.class.getName());
+    }
+
+    @Test
+    public void testInjectFragmentIntoIntent_workProfile() {
+        Intent intent = new Intent();
+
+        // Simulate managed / work profile.
+        when(mUserManager.isManagedProfile(anyInt())).thenReturn(true);
+        assertThat(DefaultCombinedPickerWork.isUserHandledByFragment(mUserManager, 10)).isTrue();
+
+        CredentialsPickerActivity.injectFragmentIntoIntent(mMockContext, intent);
+        assertThat(intent.getStringExtra(CredentialsPickerActivity.EXTRA_SHOW_FRAGMENT))
+                .isEqualTo(DefaultCombinedPickerWork.class.getName());
+    }
+
+    @Test
+    public void testInjectFragmentIntoIntent_privateProfile() {
+        Intent intent = new Intent();
+
+        // Simulate private profile.
+        UserHandle privateUser = new UserHandle(100);
+        when(mUserManager.getUserInfo(100))
+                .thenReturn(new UserInfo(100, "", "", 0, UserManager.USER_TYPE_PROFILE_PRIVATE));
+        when(mUserManager.getUserProfiles()).thenReturn(Lists.newArrayList(privateUser));
+        assertThat(DefaultCombinedPickerPrivate.isUserHandledByFragment(mUserManager)).isTrue();
+
+        CredentialsPickerActivity.injectFragmentIntoIntent(mMockContext, intent);
+        assertThat(intent.getStringExtra(CredentialsPickerActivity.EXTRA_SHOW_FRAGMENT))
+                .isEqualTo(DefaultCombinedPickerPrivate.class.getName());
+    }
+}
diff --git a/tests/unit/src/com/android/settings/applications/credentials/DefaultCombinedPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/credentials/DefaultCombinedPreferenceControllerTest.java
index 301fcfa..d02240e 100644
--- a/tests/unit/src/com/android/settings/applications/credentials/DefaultCombinedPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/applications/credentials/DefaultCombinedPreferenceControllerTest.java
@@ -87,16 +87,14 @@
 
     @Test
     public void ensureSettingsActivityIntentCreatedSuccessfully() {
-        DefaultCombinedPreferenceController dcpc =
-                new DefaultCombinedPreferenceController(mContext);
-
         // Ensure that the settings activity is only created if we haved the right combination
         // of package and class name.
-        assertThat(dcpc.createSettingsActivityIntent(null, null)).isNull();
-        assertThat(dcpc.createSettingsActivityIntent("", null)).isNull();
-        assertThat(dcpc.createSettingsActivityIntent("", "")).isNull();
-        assertThat(dcpc.createSettingsActivityIntent("com.test", "")).isNull();
-        assertThat(dcpc.createSettingsActivityIntent("com.test", "ClassName")).isNotNull();
+        assertThat(CombinedProviderInfo.createSettingsActivityIntent(null, null)).isNull();
+        assertThat(CombinedProviderInfo.createSettingsActivityIntent("", null)).isNull();
+        assertThat(CombinedProviderInfo.createSettingsActivityIntent("", "")).isNull();
+        assertThat(CombinedProviderInfo.createSettingsActivityIntent("com.test", "")).isNull();
+        assertThat(CombinedProviderInfo.createSettingsActivityIntent("com.test", "ClassName"))
+                .isNotNull();
     }
 
     @Test
@@ -112,13 +110,13 @@
 
         // Update the preference to use the provider and make sure the view
         // was updated.
-        dcpc.updatePreferenceForProvider(ppp, "App Name", "Subtitle", appIcon, null);
+        dcpc.updatePreferenceForProvider(ppp, "App Name", "Subtitle", appIcon, null, null);
         assertThat(ppp.getTitle().toString()).isEqualTo("App Name");
         assertThat(ppp.getSummary().toString()).isEqualTo("Subtitle");
         assertThat(ppp.getIcon()).isEqualTo(appIcon);
 
         // Set the preference back to none and make sure the view was updated.
-        dcpc.updatePreferenceForProvider(ppp, null, null, null, null);
+        dcpc.updatePreferenceForProvider(ppp, null, null, null, null, null);
         assertThat(ppp.getTitle().toString()).isEqualTo("None");
         assertThat(ppp.getSummary()).isNull();
         assertThat(ppp.getIcon()).isNull();
diff --git a/tests/unit/src/com/android/settings/safetycenter/BiometricsSafetySourceTest.java b/tests/unit/src/com/android/settings/safetycenter/BiometricsSafetySourceTest.java
index f6356bc..71d419e 100644
--- a/tests/unit/src/com/android/settings/safetycenter/BiometricsSafetySourceTest.java
+++ b/tests/unit/src/com/android/settings/safetycenter/BiometricsSafetySourceTest.java
@@ -114,7 +114,7 @@
 
     @Test
     public void setSafetySourceData_whenSafetyCenterIsEnabled_withoutBiometrics_setsNullData() {
-        when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(false);
+        when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
         when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
         when(mFaceManager.isHardwareDetected()).thenReturn(false);
 
diff --git a/tests/unit/src/com/android/settings/safetycenter/LockScreenSafetySourceTest.java b/tests/unit/src/com/android/settings/safetycenter/LockScreenSafetySourceTest.java
index 3538727..e528c4e 100644
--- a/tests/unit/src/com/android/settings/safetycenter/LockScreenSafetySourceTest.java
+++ b/tests/unit/src/com/android/settings/safetycenter/LockScreenSafetySourceTest.java
@@ -413,6 +413,8 @@
         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
         when(mScreenLockPreferenceDetailsUtils.isPasswordQualityManaged(anyInt(), any()))
                 .thenReturn(false);
+        when(mScreenLockPreferenceDetailsUtils.isLockPatternSecure()).thenReturn(true);
+        when(mScreenLockPreferenceDetailsUtils.shouldShowGearMenu()).thenReturn(true);
 
         LockScreenSafetySource.setSafetySourceData(
                 mApplicationContext, mScreenLockPreferenceDetailsUtils, EVENT_SOURCE_STATE_CHANGED);
diff --git a/tests/unit/src/com/android/settings/security/SecurityAdvancedSettingsTest.java b/tests/unit/src/com/android/settings/security/SecurityAdvancedSettingsTest.java
index 9851a1a..31f7878 100644
--- a/tests/unit/src/com/android/settings/security/SecurityAdvancedSettingsTest.java
+++ b/tests/unit/src/com/android/settings/security/SecurityAdvancedSettingsTest.java
@@ -107,7 +107,7 @@
 
     @Test
     public void whenSafetyCenterIsEnabled_pageIndexExcluded() throws Exception {
-        when(mSafetyCenterManagerWrapper.isEnabled(any())).thenReturn(false);
+        when(mSafetyCenterManagerWrapper.isEnabled(any())).thenReturn(true);
         BaseSearchIndexProvider indexProvider = SecurityAdvancedSettings.SEARCH_INDEX_DATA_PROVIDER;
 
         List<String> allXmlKeys = TestUtils.getAllXmlKeys(mContext, indexProvider);