Merge "Disable nfc foreground setting ui when the wallet role is enabled." into main
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index c8f35ae..96b798a 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -3232,7 +3232,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"/>
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_connecteddevice_flag_declarations.aconfig b/aconfig/settings_connecteddevice_flag_declarations.aconfig
index 5ba2129..0fc164e 100644
--- a/aconfig/settings_connecteddevice_flag_declarations.aconfig
+++ b/aconfig/settings_connecteddevice_flag_declarations.aconfig
@@ -33,4 +33,11 @@
   namespace: "pixel_cross_device_control"
   description: "Order the saved bluetooth devices by most recently connected."
   bug: "306160434"
+}
+
+flag {
+  name: "enable_hide_exclusively_managed_bluetooth_device"
+  namespace: "dck_framework"
+  description: "Hide exclusively managed Bluetooth devices in BT settings menu."
+  bug: "322285078"
 }
\ No newline at end of file
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/values/strings.xml b/res/values/strings.xml
index 78900bc..965daf6 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>
 
@@ -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>
 
@@ -11370,7 +11370,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 +11378,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 +11502,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 +11516,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 +11598,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 +11614,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 +11979,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/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/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/bluetooth/ConnectedBluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java
index 489c095..012220c 100644
--- a/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java
@@ -24,6 +24,8 @@
 import androidx.preference.Preference;
 
 import com.android.settings.connecteddevice.DevicePreferenceCallback;
+import com.android.settings.flags.Flags;
+import com.android.settingslib.bluetooth.BluetoothUtils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 
 /**
@@ -95,6 +97,15 @@
                         cachedDevice.getName() + ", isFilterMatched : " + isFilterMatched);
             }
         }
+        if (Flags.enableHideExclusivelyManagedBluetoothDevice()) {
+            if (BluetoothUtils.isExclusivelyManagedBluetoothDevice(mContext,
+                    cachedDevice.getDevice())) {
+                if (DBG) {
+                    Log.d(TAG, "isFilterMatched() hide BluetoothDevice with exclusive manager");
+                }
+                return false;
+            }
+        }
         return isFilterMatched;
     }
 
diff --git a/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java
index bfd4221..1db90fa 100644
--- a/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java
@@ -25,6 +25,8 @@
 import androidx.preference.Preference;
 
 import com.android.settings.connecteddevice.DevicePreferenceCallback;
+import com.android.settings.flags.Flags;
+import com.android.settingslib.bluetooth.BluetoothUtils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
 
@@ -99,12 +101,22 @@
     @Override
     public boolean isFilterMatched(CachedBluetoothDevice cachedDevice) {
         final BluetoothDevice device = cachedDevice.getDevice();
-        Log.d(TAG, "isFilterMatched() device name : " + cachedDevice.getName() +
-                ", is connected : " + device.isConnected() + ", is profile connected : "
-                + cachedDevice.isConnected());
-        return device.getBondState() == BluetoothDevice.BOND_BONDED
-                && (mShowConnectedDevice || (!device.isConnected() && isDeviceInCachedDevicesList(
-                cachedDevice)));
+        boolean isExclusivelyManaged = BluetoothUtils.isExclusivelyManagedBluetoothDevice(mContext,
+                cachedDevice.getDevice());
+        Log.d(TAG, "isFilterMatched() device name : " + cachedDevice.getName()
+                + ", is connected : " + device.isConnected() + ", is profile connected : "
+                + cachedDevice.isConnected() + ", is exclusively managed : "
+                + isExclusivelyManaged);
+        if (Flags.enableHideExclusivelyManagedBluetoothDevice()) {
+            return device.getBondState() == BluetoothDevice.BOND_BONDED
+                    && (mShowConnectedDevice || (!device.isConnected()
+                    && isDeviceInCachedDevicesList(cachedDevice)))
+                    && !isExclusivelyManaged;
+        } else {
+            return device.getBondState() == BluetoothDevice.BOND_BONDED
+                    && (mShowConnectedDevice || (!device.isConnected()
+                    && isDeviceInCachedDevicesList(cachedDevice)));
+        }
     }
 
     @Override
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/gestures/SystemNavigationGestureSettings.java b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
index c6b1bdb..c40212b 100644
--- a/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
+++ b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
@@ -41,7 +41,6 @@
 import androidx.annotation.VisibleForTesting;
 import androidx.preference.PreferenceScreen;
 
-import com.android.internal.accessibility.common.ShortcutConstants;
 import com.android.settings.R;
 import com.android.settings.accessibility.AccessibilityGestureNavigationTutorial;
 import com.android.settings.core.SubSettingLauncher;
@@ -354,7 +353,7 @@
     private boolean isAnyServiceSupportAccessibilityButton() {
         final AccessibilityManager ams = getContext().getSystemService(AccessibilityManager.class);
         final List<String> targets = ams.getAccessibilityShortcutTargets(
-                ShortcutConstants.UserShortcutType.SOFTWARE);
+                AccessibilityManager.ACCESSIBILITY_BUTTON);
         return !targets.isEmpty();
     }
 
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/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/app/specialaccess/InstallUnknownApps.kt b/src/com/android/settings/spa/app/specialaccess/InstallUnknownApps.kt
index dc98330..3e9058f 100644
--- a/src/com/android/settings/spa/app/specialaccess/InstallUnknownApps.kt
+++ b/src/com/android/settings/spa/app/specialaccess/InstallUnknownApps.kt
@@ -26,7 +26,7 @@
 import android.os.UserManager
 import androidx.compose.runtime.Composable
 import com.android.settings.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.userId
@@ -81,7 +81,7 @@
 
     @Composable
     override fun isAllowed(record: InstallUnknownAppsRecord) =
-        record.appOpsController.isAllowed.observeAsCallback()
+        record.appOpsController.isAllowed.collectAsCallbackWithLifecycle()
 
     override fun isChangeable(record: InstallUnknownAppsRecord) =
         isChangeable(record, getPotentialPackageNames(record.app.userId))
diff --git a/src/com/android/settings/spa/app/specialaccess/PictureInPicture.kt b/src/com/android/settings/spa/app/specialaccess/PictureInPicture.kt
index fe8f103..7885b86 100644
--- a/src/com/android/settings/spa/app/specialaccess/PictureInPicture.kt
+++ b/src/com/android/settings/spa/app/specialaccess/PictureInPicture.kt
@@ -27,7 +27,7 @@
 import android.util.Log
 import androidx.compose.runtime.Composable
 import com.android.settings.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.installed
@@ -92,7 +92,7 @@
 
     @Composable
     override fun isAllowed(record: PictureInPictureRecord) =
-        record.appOpsController.isAllowed.observeAsCallback()
+        record.appOpsController.isAllowed.collectAsCallbackWithLifecycle()
 
     override fun isChangeable(record: PictureInPictureRecord) = record.isSupport
 
diff --git a/src/com/android/settings/wifi/WifiScanModeActivity.java b/src/com/android/settings/wifi/WifiScanModeActivity.java
index c10ee27..446891a 100644
--- a/src/com/android/settings/wifi/WifiScanModeActivity.java
+++ b/src/com/android/settings/wifi/WifiScanModeActivity.java
@@ -39,26 +39,24 @@
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
 import com.android.settingslib.wifi.WifiPermissionChecker;
 
-/**
- * This activity requests users permission to allow scanning even when Wi-Fi is turned off
- */
+/** This activity requests users permission to allow scanning even when Wi-Fi is turned off */
 public class WifiScanModeActivity extends FragmentActivity {
     private static final String TAG = "WifiScanModeActivity";
     private DialogFragment mDialog;
-    @VisibleForTesting
-    String mApp;
-    @VisibleForTesting
-    WifiPermissionChecker mWifiPermissionChecker;
+    @VisibleForTesting String mApp;
+    @VisibleForTesting WifiPermissionChecker mWifiPermissionChecker;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        getWindow().addSystemFlags(
-                WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+        getWindow()
+                .addSystemFlags(
+                        WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
         Intent intent = getIntent();
         if (savedInstanceState == null) {
-            if (intent != null && WifiManager.ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE
-                    .equals(intent.getAction())) {
+            if (intent != null
+                    && WifiManager.ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE.equals(
+                            intent.getAction())) {
                 refreshAppLabel();
             } else {
                 finish();
@@ -92,6 +90,12 @@
             return;
         }
 
+        if (!isWifiScanModeConfigAllowed(getApplicationContext())) {
+            Log.e(TAG, "This user is not allowed to configure Wi-Fi Scan Mode!");
+            finish();
+            return;
+        }
+
         if (mDialog == null) {
             mDialog = AlertDialogFragment.newInstance(mApp);
             mDialog.show(getSupportFragmentManager(), "dialog");
@@ -140,6 +144,7 @@
         }
 
         private final String mApp;
+
         public AlertDialogFragment(String app) {
             super();
             mApp = app;
@@ -158,25 +163,27 @@
         @Override
         public Dialog onCreateDialog(Bundle savedInstanceState) {
             return new AlertDialog.Builder(getActivity())
-                    .setMessage(TextUtils.isEmpty(mApp) ?
-                        getString(R.string.wifi_scan_always_turn_on_message_unknown) :
-                        getString(R.string.wifi_scan_always_turnon_message, mApp))
-                    .setPositiveButton(R.string.wifi_scan_always_confirm_allow,
+                    .setMessage(
+                            TextUtils.isEmpty(mApp)
+                                    ? getString(R.string.wifi_scan_always_turn_on_message_unknown)
+                                    : getString(R.string.wifi_scan_always_turnon_message, mApp))
+                    .setPositiveButton(
+                            R.string.wifi_scan_always_confirm_allow,
                             new DialogInterface.OnClickListener() {
                                 public void onClick(DialogInterface dialog, int whichButton) {
                                     ((WifiScanModeActivity) getActivity()).doPositiveClick();
                                 }
-                            }
-                    )
-                    .setNegativeButton(R.string.wifi_scan_always_confirm_deny,
+                            })
+                    .setNegativeButton(
+                            R.string.wifi_scan_always_confirm_deny,
                             new DialogInterface.OnClickListener() {
                                 public void onClick(DialogInterface dialog, int whichButton) {
                                     ((WifiScanModeActivity) getActivity()).doNegativeClick();
                                 }
-                            }
-                    )
+                            })
                     .create();
         }
+
         @Override
         public void onCancel(DialogInterface dialog) {
             ((WifiScanModeActivity) getActivity()).doNegativeClick();
@@ -184,9 +191,14 @@
     }
 
     private static boolean isGuestUser(Context context) {
-        if (context == null) return false;
         final UserManager userManager = context.getSystemService(UserManager.class);
         if (userManager == null) return false;
         return userManager.isGuestUser();
     }
+
+    private static boolean isWifiScanModeConfigAllowed(Context context) {
+        final UserManager userManager = context.getSystemService(UserManager.class);
+        if (userManager == null) return true;
+        return !userManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_LOCATION);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java
index 00115d7..cd48bf1 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java
@@ -20,6 +20,8 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -28,18 +30,26 @@
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothProfile;
 import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.graphics.drawable.Drawable;
 import android.media.AudioManager;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.util.Pair;
 
 import com.android.settings.connecteddevice.DevicePreferenceCallback;
 import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.flags.Flags;
 import com.android.settings.testutils.shadow.ShadowAudioManager;
 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
 import com.android.settings.testutils.shadow.ShadowCachedBluetoothDeviceManager;
+import com.android.settingslib.bluetooth.BluetoothUtils;
 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;
@@ -58,6 +68,10 @@
 public class ConnectedBluetoothDeviceUpdaterTest {
 
     private static final String MAC_ADDRESS = "04:52:C7:0B:D8:3C";
+    private static final String FAKE_EXCLUSIVE_MANAGER_NAME = "com.fake.name";
+
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
 
     @Mock
     private DashboardFragment mDashboardFragment;
@@ -69,6 +83,8 @@
     private BluetoothDevice mBluetoothDevice;
     @Mock
     private Drawable mDrawable;
+    @Mock
+    private PackageManager mPackageManager;
 
     private Context mContext;
     private ConnectedBluetoothDeviceUpdater mBluetoothDeviceUpdater;
@@ -82,7 +98,7 @@
         MockitoAnnotations.initMocks(this);
 
         Pair<Drawable, String> pairs = new Pair<>(mDrawable, "fake_device");
-        mContext = RuntimeEnvironment.application;
+        mContext = spy(RuntimeEnvironment.application);
         mAudioManager = mContext.getSystemService(AudioManager.class);
         mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
         mShadowBluetoothAdapter.setEnabled(true);
@@ -92,6 +108,7 @@
         mCachedDevices = new ArrayList<>();
         mCachedDevices.add(mCachedBluetoothDevice);
 
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
         when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
         when(mCachedBluetoothDevice.getAddress()).thenReturn(MAC_ADDRESS);
         when(mCachedBluetoothDevice.getDrawableWithDescription()).thenReturn(pairs);
@@ -320,4 +337,97 @@
 
         assertThat(btPreference.shouldHideSecondTarget()).isTrue();
     }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
+    public void update_notExclusiveManagedDevice_addDevice() {
+        mAudioManager.setMode(AudioManager.MODE_NORMAL);
+        when(mBluetoothDeviceUpdater
+                .isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
+        when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true);
+        when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
+                null);
+
+        mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
+
+        verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
+    public void update_notAllowedExclusiveManagedDevice_addDevice() {
+        mAudioManager.setMode(AudioManager.MODE_NORMAL);
+        when(mBluetoothDeviceUpdater
+                .isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
+        when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true);
+        when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
+                FAKE_EXCLUSIVE_MANAGER_NAME.getBytes());
+
+        mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
+
+        verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
+    public void update_existingExclusivelyManagedDeviceWithPackageInstalled_removePreference()
+            throws Exception {
+        final String exclusiveManagerName =
+                BluetoothUtils.getExclusiveManagers().stream().findAny().orElse(
+                        FAKE_EXCLUSIVE_MANAGER_NAME);
+        mAudioManager.setMode(AudioManager.MODE_NORMAL);
+        when(mBluetoothDeviceUpdater
+                .isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
+        when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true);
+        when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
+                exclusiveManagerName.getBytes());
+        doReturn(new PackageInfo()).when(mPackageManager).getPackageInfo(exclusiveManagerName, 0);
+
+        mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
+
+        verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
+        verify(mBluetoothDeviceUpdater, never()).addPreference(mCachedBluetoothDevice);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
+    public void update_newExclusivelyManagedDeviceWithPackageInstalled_doNotAddPreference()
+            throws Exception {
+        final String exclusiveManagerName =
+                BluetoothUtils.getExclusiveManagers().stream().findAny().orElse(
+                        FAKE_EXCLUSIVE_MANAGER_NAME);
+        mAudioManager.setMode(AudioManager.MODE_NORMAL);
+        when(mBluetoothDeviceUpdater
+                .isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
+        when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true);
+        when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
+                exclusiveManagerName.getBytes());
+        doReturn(new PackageInfo()).when(mPackageManager).getPackageInfo(exclusiveManagerName, 0);
+
+        mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
+
+        verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
+        verify(mBluetoothDeviceUpdater, never()).addPreference(mCachedBluetoothDevice);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
+    public void update_exclusivelyManagedDeviceWithoutPackageInstalled_addDevice()
+            throws Exception {
+        final String exclusiveManagerName =
+                BluetoothUtils.getExclusiveManagers().stream().findAny().orElse(
+                        FAKE_EXCLUSIVE_MANAGER_NAME);
+        mAudioManager.setMode(AudioManager.MODE_NORMAL);
+        when(mBluetoothDeviceUpdater
+                .isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
+        when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true);
+        when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
+                exclusiveManagerName.getBytes());
+        doThrow(new PackageManager.NameNotFoundException()).when(mPackageManager).getPackageInfo(
+                exclusiveManagerName, 0);
+
+        mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
+
+        verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdaterTest.java
index c229449..349391d 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdaterTest.java
@@ -18,6 +18,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
@@ -28,17 +29,26 @@
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothProfile;
 import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.graphics.drawable.Drawable;
+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.util.Pair;
 
 import com.android.settings.connecteddevice.DevicePreferenceCallback;
 import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.flags.Flags;
 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
+import com.android.settingslib.bluetooth.BluetoothUtils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -56,6 +66,10 @@
 public class SavedBluetoothDeviceUpdaterTest {
 
     private static final String MAC_ADDRESS = "04:52:C7:0B:D8:3C";
+    private static final String FAKE_EXCLUSIVE_MANAGER_NAME = "com.fake.name";
+
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
 
     @Mock
     private DashboardFragment mDashboardFragment;
@@ -73,6 +87,8 @@
     private LocalBluetoothManager mBluetoothManager;
     @Mock
     private Drawable mDrawable;
+    @Mock
+    private PackageManager mPackageManager;
 
     private Context mContext;
     private SavedBluetoothDeviceUpdater mBluetoothDeviceUpdater;
@@ -84,12 +100,13 @@
         MockitoAnnotations.initMocks(this);
 
         Pair<Drawable, String> pairs = new Pair<>(mDrawable, "fake_device");
-        mContext = RuntimeEnvironment.application;
+        mContext = spy(RuntimeEnvironment.application);
         doReturn(mContext).when(mDashboardFragment).getContext();
         when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
         when(mCachedBluetoothDevice.getAddress()).thenReturn(MAC_ADDRESS);
         when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
         when(mCachedBluetoothDevice.getDrawableWithDescription()).thenReturn(pairs);
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
 
         mBluetoothDeviceUpdater = spy(new SavedBluetoothDeviceUpdater(mContext,
                 mDevicePreferenceCallback, false, /* metricsCategory= */ 0));
@@ -103,10 +120,10 @@
         mCachedDevices.add(mCachedBluetoothDevice);
         when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
         when(mDeviceManager.getCachedDevicesCopy()).thenReturn(mCachedDevices);
-
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
     public void update_filterMatch_addPreference() {
         doReturn(BluetoothDevice.BOND_BONDED).when(mBluetoothDevice).getBondState();
         doReturn(false).when(mBluetoothDevice).isConnected();
@@ -118,6 +135,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
     public void update_filterNotMatch_removePreference() {
         doReturn(BluetoothDevice.BOND_NONE).when(mBluetoothDevice).getBondState();
         doReturn(true).when(mBluetoothDevice).isConnected();
@@ -298,4 +316,125 @@
         verify(mBluetoothDeviceUpdater, never()).addPreference(mCachedBluetoothDevice,
                 BluetoothDevicePreference.SortType.TYPE_NO_SORT);
     }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
+    public void update_notExclusivelyManagedDevice_addDevice() {
+        final Collection<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
+        cachedDevices.add(mCachedBluetoothDevice);
+
+        when(mBluetoothAdapter.isEnabled()).thenReturn(true);
+        when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
+        when(mDeviceManager.getCachedDevicesCopy()).thenReturn(cachedDevices);
+        when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+        when(mBluetoothDevice.isConnected()).thenReturn(false);
+        when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
+                null);
+
+        mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
+
+        verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice,
+                BluetoothDevicePreference.SortType.TYPE_NO_SORT);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
+    public void update_notAllowedExclusivelyManagedDevice_addDevice() {
+        final Collection<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
+        cachedDevices.add(mCachedBluetoothDevice);
+
+        when(mBluetoothAdapter.isEnabled()).thenReturn(true);
+        when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
+        when(mDeviceManager.getCachedDevicesCopy()).thenReturn(cachedDevices);
+        when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+        when(mBluetoothDevice.isConnected()).thenReturn(false);
+        when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
+                FAKE_EXCLUSIVE_MANAGER_NAME.getBytes());
+
+        mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
+
+        verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice,
+                BluetoothDevicePreference.SortType.TYPE_NO_SORT);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
+    public void update_existingExclusivelyManagedDeviceWithPackageInstalled_removePreference()
+            throws Exception {
+        final Collection<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
+        final String exclusiveManagerName =
+                BluetoothUtils.getExclusiveManagers().stream().findAny().orElse(
+                        FAKE_EXCLUSIVE_MANAGER_NAME);
+
+        when(mBluetoothAdapter.isEnabled()).thenReturn(true);
+        when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
+        when(mDeviceManager.getCachedDevicesCopy()).thenReturn(cachedDevices);
+        when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+        when(mBluetoothDevice.isConnected()).thenReturn(false);
+        when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
+                exclusiveManagerName.getBytes());
+
+        doReturn(new PackageInfo()).when(mPackageManager).getPackageInfo(exclusiveManagerName, 0);
+        mBluetoothDeviceUpdater.mPreferenceMap.put(mBluetoothDevice, mPreference);
+
+        mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
+
+        verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
+        verify(mBluetoothDeviceUpdater, never()).addPreference(mCachedBluetoothDevice,
+                BluetoothDevicePreference.SortType.TYPE_NO_SORT);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
+    public void update_newExclusivelyManagedDeviceWithPackageInstalled_doNotAddPreference()
+            throws Exception {
+        final Collection<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
+        final String exclusiveManagerName =
+                BluetoothUtils.getExclusiveManagers().stream().findAny().orElse(
+                        FAKE_EXCLUSIVE_MANAGER_NAME);
+        cachedDevices.add(mCachedBluetoothDevice);
+
+        when(mBluetoothAdapter.isEnabled()).thenReturn(true);
+        when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
+        when(mDeviceManager.getCachedDevicesCopy()).thenReturn(cachedDevices);
+        when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+        when(mBluetoothDevice.isConnected()).thenReturn(false);
+        when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
+                exclusiveManagerName.getBytes());
+
+        doReturn(new PackageInfo()).when(mPackageManager).getPackageInfo(exclusiveManagerName, 0);
+
+        mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
+
+        verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
+        verify(mBluetoothDeviceUpdater, never()).addPreference(mCachedBluetoothDevice,
+                BluetoothDevicePreference.SortType.TYPE_NO_SORT);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
+    public void update_exclusivelyManagedDeviceWithoutPackageInstalled_addDevice()
+            throws Exception {
+        final Collection<CachedBluetoothDevice> cachedDevices = new ArrayList<>();
+        final String exclusiveManagerName =
+                BluetoothUtils.getExclusiveManagers().stream().findAny().orElse(
+                        FAKE_EXCLUSIVE_MANAGER_NAME);
+        cachedDevices.add(mCachedBluetoothDevice);
+
+        when(mBluetoothAdapter.isEnabled()).thenReturn(true);
+        when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
+        when(mDeviceManager.getCachedDevicesCopy()).thenReturn(cachedDevices);
+        when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+        when(mBluetoothDevice.isConnected()).thenReturn(false);
+        when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_EXCLUSIVE_MANAGER)).thenReturn(
+                exclusiveManagerName.getBytes());
+
+        doThrow(new PackageManager.NameNotFoundException()).when(mPackageManager).getPackageInfo(
+                exclusiveManagerName, 0);
+
+        mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
+
+        verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice,
+                BluetoothDevicePreference.SortType.TYPE_NO_SORT);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsPreferenceControllerTest.java
index aa10517..4cdd364 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsPreferenceControllerTest.java
@@ -171,6 +171,7 @@
         mShadowBluetoothAdapter.setEnabled(false);
         mController.displayPreference(mScreen);
         mController.updateVisibility();
+        shadowOf(Looper.getMainLooper()).idle();
         assertThat(mPreference.isVisible()).isFalse();
     }
 
@@ -180,6 +181,7 @@
         mShadowBluetoothAdapter.setEnabled(false);
         mController.displayPreference(mScreen);
         mController.updateVisibility();
+        shadowOf(Looper.getMainLooper()).idle();
         assertThat(mPreference.isVisible()).isFalse();
     }
 
@@ -188,6 +190,7 @@
         when(mBroadcast.isEnabled(any())).thenReturn(false);
         mController.displayPreference(mScreen);
         mController.updateVisibility();
+        shadowOf(Looper.getMainLooper()).idle();
         assertThat(mPreference.isVisible()).isFalse();
     }
 
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceControllerTest.java
index eeedccc..c05d9ed 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceControllerTest.java
@@ -20,30 +20,29 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.os.Bundle;
-import android.text.format.DateUtils;
 
 import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
 
 import com.android.settings.SettingsActivity;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.core.InstrumentedPreferenceFragment;
 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
-import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.widget.CardPreference;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -53,8 +52,8 @@
 
     private static final String KEY_PREF = "battery_tip";
     private static final String KEY_TIP = "key_battery_tip";
-    private static final long AVERAGE_TIME_MS = DateUtils.HOUR_IN_MILLIS;
 
+    @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
     @Mock private BatteryTipPreferenceController.BatteryTipListener mBatteryTipListener;
     @Mock private PreferenceScreen mPreferenceScreen;
     @Mock private BatteryTip mBatteryTip;
@@ -64,21 +63,16 @@
     private Context mContext;
     private CardPreference mCardPreference;
     private BatteryTipPreferenceController mBatteryTipPreferenceController;
-    private List<BatteryTip> mOldBatteryTips;
     private List<BatteryTip> mNewBatteryTips;
-    private FakeFeatureFactory mFeatureFactory;
 
     @Before
     public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
+        mContext = ApplicationProvider.getApplicationContext();
 
-        mCardPreference = spy(new CardPreference(mContext));
+        mCardPreference = new CardPreference(mContext);
         when(mPreferenceScreen.getContext()).thenReturn(mContext);
         doReturn(mCardPreference).when(mPreferenceScreen).findPreference(KEY_PREF);
-        mFeatureFactory = FakeFeatureFactory.setupForTest();
 
-        mOldBatteryTips = new ArrayList<>();
         mNewBatteryTips = new ArrayList<>();
 
         mBatteryTipPreferenceController = buildBatteryTipPreferenceController();
@@ -87,32 +81,32 @@
     }
 
     @Test
-    public void testDisplayPreference_isInvisible() {
+    public void displayPreference_isInvisible() {
         mBatteryTipPreferenceController.displayPreference(mPreferenceScreen);
 
         assertThat(mCardPreference.isVisible()).isFalse();
     }
 
     @Test
-    public void testUpdateBatteryTips_tipsStateInvisible_isInvisible() {
+    public void updateBatteryTips_tipsStateInvisible_isInvisible() {
         mBatteryTipPreferenceController.updateBatteryTips(mNewBatteryTips);
 
         assertThat(mCardPreference.isVisible()).isFalse();
     }
 
     @Test
-    public void testGetCurrentBatteryTip_noTips_isNull() {
+    public void getCurrentBatteryTip_noTips_isNull() {
         assertThat(mBatteryTipPreferenceController.getCurrentBatteryTip()).isNull();
     }
 
     @Test
-    public void testGetCurrentBatteryTip_tipsInvisible_isNull() {
+    public void getCurrentBatteryTip_tipsInvisible_isNull() {
         mBatteryTipPreferenceController.updateBatteryTips(mNewBatteryTips);
         assertThat(mBatteryTipPreferenceController.getCurrentBatteryTip()).isNull();
     }
 
     @Test
-    public void testRestoreFromNull_shouldNotCrash() {
+    public void restoreFromNull_shouldNotCrash() {
         final Bundle bundle = new Bundle();
         // Battery tip list is null at this time
         mBatteryTipPreferenceController.saveInstanceState(bundle);
@@ -124,7 +118,7 @@
     }
 
     @Test
-    public void testHandlePreferenceTreeClick_noDialog_invokeCallback() {
+    public void handlePreferenceTreeClick_noDialog_invokeCallback() {
         when(mBatteryTip.getType()).thenReturn(SMART_BATTERY_MANAGER);
         List<BatteryTip> batteryTips = new ArrayList<>();
         batteryTips.add(mBatteryTip);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/BatteryDefenderTipTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/BatteryDefenderTipTest.java
index 3f89f9b..4efd850 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/BatteryDefenderTipTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/BatteryDefenderTipTest.java
@@ -17,8 +17,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -27,6 +25,7 @@
 import android.util.Log;
 
 import androidx.preference.Preference;
+import androidx.test.core.app.ApplicationProvider;
 
 import com.android.settings.R;
 import com.android.settings.testutils.FakeFeatureFactory;
@@ -34,12 +33,13 @@
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 import org.robolectric.shadows.ShadowLog;
 
 @RunWith(RobolectricTestRunner.class)
@@ -49,23 +49,22 @@
     private FakeFeatureFactory mFeatureFactory;
     private BatteryDefenderTip mBatteryDefenderTip;
     private MetricsFeatureProvider mMetricsFeatureProvider;
+    private CardPreference mCardPreference;
 
+    @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
     @Mock private BatteryTip mBatteryTip;
     @Mock private Preference mPreference;
-    @Mock private CardPreference mCardPreference;
 
     @Before
     public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
+        mContext = ApplicationProvider.getApplicationContext();
         mFeatureFactory = FakeFeatureFactory.setupForTest();
         mMetricsFeatureProvider = mFeatureFactory.metricsFeatureProvider;
-        mContext = RuntimeEnvironment.application;
         mBatteryDefenderTip =
-                new BatteryDefenderTip(BatteryTip.StateType.NEW, false /* isPluggedIn */);
+                new BatteryDefenderTip(BatteryTip.StateType.NEW, /* isPluggedIn= */ false);
+        mCardPreference = new CardPreference(mContext);
 
         when(mPreference.getContext()).thenReturn(mContext);
-        when(mCardPreference.getContext()).thenReturn(mContext);
     }
 
     @Test
@@ -87,7 +86,7 @@
     }
 
     @Test
-    public void testLog_logMetric() {
+    public void log_logMetric() {
         mBatteryDefenderTip.updateState(mBatteryTip);
         mBatteryDefenderTip.log(mContext, mMetricsFeatureProvider);
 
@@ -108,7 +107,7 @@
 
         mBatteryDefenderTip.updatePreference(mCardPreference);
 
-        verify(mCardPreference).setPrimaryButtonText(expectedText);
+        assertThat(mCardPreference.getPrimaryButtonText()).isEqualTo(expectedText);
     }
 
     @Test
@@ -117,46 +116,31 @@
 
         mBatteryDefenderTip.updatePreference(mCardPreference);
 
-        verify(mCardPreference).setSecondaryButtonText(expected);
+        assertThat(mCardPreference.getSecondaryButtonText()).isEqualTo(expected);
     }
 
     @Test
     public void updatePreference_shouldSetPrimaryButtonVisible() {
         mBatteryDefenderTip.updatePreference(mCardPreference);
 
-        verify(mCardPreference).setPrimaryButtonVisibility(true);
+        assertThat(mCardPreference.getPrimaryButtonVisibility()).isTrue();
     }
 
     @Test
     public void updatePreference_whenCharging_setPrimaryButtonVisibleToBeTrue() {
         mBatteryDefenderTip =
-                new BatteryDefenderTip(BatteryTip.StateType.NEW, true /* isPluggedIn */);
+                new BatteryDefenderTip(BatteryTip.StateType.NEW, /* isPluggedIn= */ true);
 
         mBatteryDefenderTip.updatePreference(mCardPreference);
 
-        verify(mCardPreference).setPrimaryButtonVisibility(true);
+        assertThat(mCardPreference.getPrimaryButtonVisibility()).isTrue();
     }
 
     @Test
     public void updatePreference_whenNotCharging_setSecondaryButtonVisibleToBeFalse() {
         mBatteryDefenderTip.updatePreference(mCardPreference);
 
-        verify(mCardPreference).setSecondaryButtonVisibility(false);
-    }
-
-    @Test
-    public void updatePreference_whenGetChargingStatusFailed_setSecondaryButtonVisibleToBeFalse() {
-        fakeGetChargingStatusFailed();
-
-        mBatteryDefenderTip.updatePreference(mCardPreference);
-
-        verify(mCardPreference).setSecondaryButtonVisibility(false);
-    }
-
-    private void fakeGetChargingStatusFailed() {
-        Context mockContext = mock(Context.class);
-        when(mockContext.getString(anyInt())).thenReturn("fake_string");
-        when(mCardPreference.getContext()).thenReturn(mockContext);
+        assertThat(mCardPreference.getSecondaryButtonVisibility()).isFalse();
     }
 
     private String getLastErrorLog() {
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTipTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTipTest.java
index ea72ff6..097f484 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTipTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTipTest.java
@@ -20,11 +20,10 @@
 import android.content.Context;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.view.View;
 
 import androidx.annotation.DrawableRes;
 import androidx.preference.Preference;
-import androidx.preference.PreferenceViewHolder;
+import androidx.test.core.app.ApplicationProvider;
 
 import com.android.settings.R;
 import com.android.settings.widget.CardPreference;
@@ -32,10 +31,12 @@
 import com.android.settingslib.testutils.DrawableTestHelper;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -47,13 +48,15 @@
     private static final String SUMMARY = "summary";
     @DrawableRes private static final int ICON_ID = R.drawable.ic_fingerprint;
 
+    @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
+
     private Context mContext;
     private TestBatteryTip mBatteryTip;
 
     @Before
     public void setUp() {
-        mContext = RuntimeEnvironment.application;
         mBatteryTip = new TestBatteryTip();
+        mContext = ApplicationProvider.getApplicationContext();
     }
 
     @Test
@@ -84,19 +87,14 @@
 
     @Test
     public void updatePreference_resetLayoutState() {
-        mContext.setTheme(R.style.Theme_Settings);
-        PreferenceViewHolder holder =
-                PreferenceViewHolder.createInstanceForTests(
-                        View.inflate(
-                                mContext, R.layout.card_preference_layout, /* parent= */ null));
         CardPreference cardPreference = new CardPreference(mContext);
-        cardPreference.onBindViewHolder(holder);
         cardPreference.setPrimaryButtonVisibility(true);
+        cardPreference.setSecondaryButtonVisibility(true);
 
         mBatteryTip.updatePreference(cardPreference);
 
-        View view = holder.findViewById(R.id.card_preference_buttons);
-        assertThat(view.getVisibility()).isEqualTo(View.GONE);
+        assertThat(cardPreference.getPrimaryButtonVisibility()).isFalse();
+        assertThat(cardPreference.getSecondaryButtonVisibility()).isFalse();
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/IncompatibleChargerTipTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/IncompatibleChargerTipTest.java
index c66cf37..7a23332 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/IncompatibleChargerTipTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/IncompatibleChargerTipTest.java
@@ -25,6 +25,7 @@
 import android.util.Log;
 
 import androidx.preference.Preference;
+import androidx.test.core.app.ApplicationProvider;
 
 import com.android.settings.R;
 import com.android.settings.testutils.FakeFeatureFactory;
@@ -32,12 +33,13 @@
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 import org.robolectric.shadows.ShadowLog;
 
 @RunWith(RobolectricTestRunner.class)
@@ -47,22 +49,21 @@
     private FakeFeatureFactory mFeatureFactory;
     private IncompatibleChargerTip mIncompatibleChargerTip;
     private MetricsFeatureProvider mMetricsFeatureProvider;
+    private CardPreference mCardPreference;
 
+    @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
     @Mock private BatteryTip mBatteryTip;
     @Mock private Preference mPreference;
-    @Mock private CardPreference mCardPreference;
 
     @Before
     public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
         mFeatureFactory = FakeFeatureFactory.setupForTest();
         mMetricsFeatureProvider = mFeatureFactory.metricsFeatureProvider;
-        mContext = RuntimeEnvironment.application;
+        mContext = ApplicationProvider.getApplicationContext();
         mIncompatibleChargerTip = new IncompatibleChargerTip(BatteryTip.StateType.NEW);
+        mCardPreference = new CardPreference(mContext);
 
         when(mPreference.getContext()).thenReturn(mContext);
-        when(mCardPreference.getContext()).thenReturn(mContext);
     }
 
     @Test
@@ -107,13 +108,13 @@
 
         mIncompatibleChargerTip.updatePreference(mCardPreference);
 
-        verify(mCardPreference).setPrimaryButtonText(expected);
+        assertThat(mCardPreference.getPrimaryButtonText()).isEqualTo(expected);
     }
 
     @Test
     public void updatePreference_shouldSetSecondaryButtonVisible() {
         mIncompatibleChargerTip.updatePreference(mCardPreference);
-        verify(mCardPreference).setPrimaryButtonVisibility(true);
+        assertThat(mCardPreference.getPrimaryButtonVisibility()).isTrue();
     }
 
     private String getLastErrorLog() {
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/WifiControlAppListModelTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/WifiControlAppListModelTest.kt
index 74aa861..537764a 100644
--- a/tests/spa_unit/src/com/android/settings/spa/app/WifiControlAppListModelTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/app/WifiControlAppListModelTest.kt
@@ -21,7 +21,6 @@
 import android.content.Context
 import android.content.pm.ApplicationInfo
 import androidx.compose.ui.test.junit4.createComposeRule
-import androidx.lifecycle.MutableLiveData
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import com.android.settingslib.spa.testutils.firstWithTimeoutOrNull
@@ -270,7 +269,7 @@
 private class FakeAppOpsController(private val fakeMode: Int) : IAppOpsController {
     var setAllowedCalledWith: Boolean? = null
 
-    override val mode = MutableLiveData(fakeMode)
+    override val mode = flowOf(fakeMode)
 
     override fun setAllowed(allowed: Boolean) {
         setAllowedCalledWith = allowed
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/app/specialaccess/MediaRoutingControlTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/MediaRoutingControlTest.kt
index 2f4740e..990ec5c 100644
--- a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/MediaRoutingControlTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/MediaRoutingControlTest.kt
@@ -24,7 +24,6 @@
 import android.content.Context
 import android.content.pm.ApplicationInfo
 import android.platform.test.flag.junit.SetFlagsRule
-import androidx.lifecycle.MutableLiveData
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import com.android.media.flags.Flags
@@ -33,6 +32,7 @@
 import com.android.settingslib.spaprivileged.model.app.IAppOpsController
 import com.android.settingslib.spaprivileged.template.app.AppOpPermissionRecord
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.flow.MutableStateFlow
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
@@ -223,16 +223,13 @@
 
     private class FakeAppOpsController(fakeMode: Int) : IAppOpsController {
 
-        override val mode = MutableLiveData(fakeMode)
+        override val mode = MutableStateFlow(fakeMode)
 
         override fun setAllowed(allowed: Boolean) {
-            if (allowed)
-                mode.postValue(AppOpsManager.MODE_ALLOWED)
-            else
-                mode.postValue(AppOpsManager.MODE_ERRORED)
+            mode.value = if (allowed) AppOpsManager.MODE_ALLOWED else AppOpsManager.MODE_ERRORED
         }
 
-        override fun getMode(): Int = mode.value!!
+        override fun getMode(): Int = mode.value
     }
 
     companion object {
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);