Merge "Fixed AutoDataSwitchPreferenceControllerTest" into main
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index cbc0d8e..11bf4c1 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -818,6 +818,10 @@
                   android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"
                   android:theme="@style/Theme.AlertDialog.SimConfirmDialog"/>
 
+        <activity android:name=".network.telephony.EuiccRacConnectivityDialogActivity"
+                  android:exported="false"
+                  android:theme="@style/Theme.AlertDialog.SimConfirmDialog"/>
+
         <activity
             android:name="Settings$TetherSettingsActivity"
             android:label="@string/tether_settings_title_all"
diff --git a/res/layout/sim_warning_dialog_wifi_connectivity.xml b/res/layout/sim_warning_dialog_wifi_connectivity.xml
new file mode 100644
index 0000000..c6cdbc7
--- /dev/null
+++ b/res/layout/sim_warning_dialog_wifi_connectivity.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+        <ImageView
+            android:src="@drawable/ic_warning_24dp"
+            android:contentDescription="@null"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingTop="16dp"
+            android:gravity="center"
+            android:tint="?android:attr/textColorSecondary"/>
+
+        <TextView
+            android:id="@+id/title"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingEnd="24dp"
+            android:paddingTop="16dp"
+            android:paddingLeft="24dp"
+            android:gravity="center"
+            style="?android:attr/textAppearanceLarge"/>
+
+        <TextView
+            android:id="@+id/msg"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingEnd="24dp"
+            android:paddingTop="16dp"
+            android:paddingStart="24dp"
+            android:paddingBottom="32dp"
+            android:gravity="center"
+            android:textAppearance="@style/TextAppearance.DialogMessage"
+            android:visibility="gone"/>
+</LinearLayout>
diff --git a/res/values/accessibility_shortcut_keys.xml b/res/values/accessibility_shortcut_keys.xml
index 0d409a8..4992a54 100644
--- a/res/values/accessibility_shortcut_keys.xml
+++ b/res/values/accessibility_shortcut_keys.xml
@@ -16,6 +16,7 @@
   -->
 
 <resources>
+    <string name="accessibility_shortcut_description_pref" translatable="false">shortcut_description</string>
     <string name="accessibility_shortcut_volume_keys_pref" translatable="false">shortcut_volume_keys_pref</string>
     <string name="accessibility_shortcut_gesture_pref" translatable="false">shortcut_gesture_pref</string>
     <string name="accessibility_shortcut_nav_button_pref" translatable="false">shortcut_nav_button_pref</string>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 76c7106..73a3b55 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -5112,6 +5112,10 @@
     <string name="accessibility_shortcut_type_hardware">Hold volume keys</string>
     <!-- Summary for accessibility shortcut preference for magnification triple tap shortcut type. [CHAR LIMIT=NONE] -->
     <string name="accessibility_shortcut_type_triple_tap">Triple tap screen</string>
+    <!-- Generic title for editing the shortcuts of multiple accessibility features. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_shortcut_edit_screen_title">Edit accessibility shortcuts</string>
+    <!-- Prompt for editing the shortcuts of multiple accessibility features. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_shortcut_edit_screen_prompt">Chose your shortcut for %1$s</string>
 
     <!-- Button text for the accessibility dialog continue to the next screen for hearing aid. [CHAR LIMIT=32] -->
     <string name="accessibility_hearingaid_instruction_continue_button">Continue</string>
@@ -11697,6 +11701,16 @@
     <!-- Body text of error message indicating the device could not erase the SIM due to an error. [CHAR_LIMIT=NONE] -->
     <string name="erase_sim_fail_text">Something went wrong and this eSIM wasn\'t erased.\n\nRestart your device and try again.</string>
 
+    <!-- Strings for to use Wi-Fi before deleting eUICC subscriptions -->
+    <!-- Title on confirmation dialog asking the user to have Wi-Fi. [CHAR_LIMIT=NONE] -->
+    <string name="wifi_warning_dialog_title">Connect to Wi\u2011Fi before erasing</string>
+    <!-- Body text in confirmation dialog indicating why having Wi-Fi is recommended. [CHAR_LIMIT=NONE] -->
+    <string name="wifi_warning_dialog_text">This makes it easier to use your eSIM again in the future without needing to contact your carrier</string>
+    <!-- Button label to continue with erasing [CHAR_LIMIT=20] -->
+    <string name="wifi_warning_continue_button">Erase anyway</string>
+    <!-- Button label to return to settings [CHAR_LIMIT=20] -->
+    <string name="wifi_warning_return_button">OK</string>
+
     <!-- Title for Network connection request Dialog [CHAR LIMIT=60] -->
     <string name="network_connection_request_dialog_title">Connect to device</string>
     <!-- Summary for Network connection request Dialog [CHAR LIMIT=NONE] -->
diff --git a/res/xml/accessibility_edit_shortcuts.xml b/res/xml/accessibility_edit_shortcuts.xml
index 06cbedd..8be0ee5 100644
--- a/res/xml/accessibility_edit_shortcuts.xml
+++ b/res/xml/accessibility_edit_shortcuts.xml
@@ -18,62 +18,66 @@
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:settings="http://schemas.android.com/apk/res-auto">
 
-    <com.android.settings.accessibility.shortcuts.ShortcutOptionPreference
-        android:key="@string/accessibility_shortcut_fab_pref"
-        android:persistent="false"
-        android:selectable="true"
-        settings:allowDividerAbove="false"
-        settings:allowDividerBelow="false"
-        settings:controller="com.android.settings.accessibility.shortcuts.FloatingButtonShortcutOptionController" />
+    <PreferenceCategory
+        android:key="@string/accessibility_shortcut_description_pref">
 
-    <com.android.settings.accessibility.shortcuts.ShortcutOptionPreference
-        android:key="@string/accessibility_shortcut_gesture_pref"
-        android:persistent="false"
-        android:selectable="true"
-        settings:allowDividerAbove="false"
-        settings:allowDividerBelow="false"
-        settings:controller="com.android.settings.accessibility.shortcuts.GestureShortcutOptionController" />
+        <com.android.settings.accessibility.shortcuts.ShortcutOptionPreference
+            android:key="@string/accessibility_shortcut_fab_pref"
+            android:persistent="false"
+            android:selectable="true"
+            settings:allowDividerAbove="false"
+            settings:allowDividerBelow="false"
+            settings:controller="com.android.settings.accessibility.shortcuts.FloatingButtonShortcutOptionController" />
 
-    <com.android.settings.accessibility.shortcuts.ShortcutOptionPreference
-        android:key="@string/accessibility_shortcut_nav_button_pref"
-        android:persistent="false"
-        android:selectable="true"
-        settings:allowDividerAbove="false"
-        settings:allowDividerBelow="false"
-        settings:controller="com.android.settings.accessibility.shortcuts.NavButtonShortcutOptionController" />
+        <com.android.settings.accessibility.shortcuts.ShortcutOptionPreference
+            android:key="@string/accessibility_shortcut_gesture_pref"
+            android:persistent="false"
+            android:selectable="true"
+            settings:allowDividerAbove="false"
+            settings:allowDividerBelow="false"
+            settings:controller="com.android.settings.accessibility.shortcuts.GestureShortcutOptionController" />
 
-    <com.android.settings.accessibility.shortcuts.ShortcutOptionPreference
-        android:key="@string/accessibility_shortcut_volume_keys_pref"
-        android:persistent="false"
-        android:selectable="true"
-        settings:allowDividerAbove="false"
-        settings:allowDividerBelow="false"
-        settings:controller="com.android.settings.accessibility.shortcuts.VolumeKeysShortcutOptionController" />
+        <com.android.settings.accessibility.shortcuts.ShortcutOptionPreference
+            android:key="@string/accessibility_shortcut_nav_button_pref"
+            android:persistent="false"
+            android:selectable="true"
+            settings:allowDividerAbove="false"
+            settings:allowDividerBelow="false"
+            settings:controller="com.android.settings.accessibility.shortcuts.NavButtonShortcutOptionController" />
 
-    <com.android.settings.accessibility.shortcuts.ShortcutOptionPreference
-        android:key="@string/accessibility_shortcut_two_fingers_double_tap_pref"
-        android:persistent="false"
-        android:selectable="true"
-        settings:allowDividerAbove="false"
-        settings:allowDividerBelow="false"
-        settings:controller="com.android.settings.accessibility.shortcuts.TwoFingersDoubleTapShortcutOptionController" />
+        <com.android.settings.accessibility.shortcuts.ShortcutOptionPreference
+            android:key="@string/accessibility_shortcut_volume_keys_pref"
+            android:persistent="false"
+            android:selectable="true"
+            settings:allowDividerAbove="false"
+            settings:allowDividerBelow="false"
+            settings:controller="com.android.settings.accessibility.shortcuts.VolumeKeysShortcutOptionController" />
 
-    <Preference
-        android:icon="@drawable/ic_keyboard_arrow_down"
-        android:key="@string/accessibility_shortcuts_advanced_collapsed"
-        android:persistent="false"
-        android:selectable="true"
-        android:title="@string/accessibility_shortcut_edit_dialog_title_advance"
-        settings:allowDividerAbove="false"
-        settings:allowDividerBelow="false"
-        settings:controller="com.android.settings.accessibility.shortcuts.AdvancedShortcutsPreferenceController" />
+        <com.android.settings.accessibility.shortcuts.ShortcutOptionPreference
+            android:key="@string/accessibility_shortcut_two_fingers_double_tap_pref"
+            android:persistent="false"
+            android:selectable="true"
+            settings:allowDividerAbove="false"
+            settings:allowDividerBelow="false"
+            settings:controller="com.android.settings.accessibility.shortcuts.TwoFingersDoubleTapShortcutOptionController" />
 
-    <com.android.settings.accessibility.shortcuts.ShortcutOptionPreference
-        android:key="@string/accessibility_shortcut_triple_tap_pref"
-        android:persistent="false"
-        android:selectable="true"
-        settings:allowDividerAbove="false"
-        settings:allowDividerBelow="false"
-        settings:controller="com.android.settings.accessibility.shortcuts.TripleTapShortcutOptionController" />
+        <Preference
+            android:icon="@drawable/ic_keyboard_arrow_down"
+            android:key="@string/accessibility_shortcuts_advanced_collapsed"
+            android:persistent="false"
+            android:selectable="true"
+            android:title="@string/accessibility_shortcut_edit_dialog_title_advance"
+            settings:allowDividerAbove="false"
+            settings:allowDividerBelow="false"
+            settings:controller="com.android.settings.accessibility.shortcuts.AdvancedShortcutsPreferenceController" />
+
+        <com.android.settings.accessibility.shortcuts.ShortcutOptionPreference
+            android:key="@string/accessibility_shortcut_triple_tap_pref"
+            android:persistent="false"
+            android:selectable="true"
+            settings:allowDividerAbove="false"
+            settings:allowDividerBelow="false"
+            settings:controller="com.android.settings.accessibility.shortcuts.TripleTapShortcutOptionController" />
+    </PreferenceCategory>
 
 </PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/connected_devices.xml b/res/xml/connected_devices.xml
index 34a5798..e9ec19e 100644
--- a/res/xml/connected_devices.xml
+++ b/res/xml/connected_devices.xml
@@ -41,8 +41,7 @@
 
     <PreferenceCategory
         android:key="available_device_list"
-        android:title="@string/connected_device_media_device_title"
-        settings:controller="com.android.settings.connecteddevice.AvailableMediaDeviceGroupController" />
+        android:title="@string/connected_device_media_device_title"/>
 
     <PreferenceCategory
         android:key="connected_device_list"
diff --git a/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragment.java b/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragment.java
index a3cbb57..5a3b13a 100644
--- a/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragment.java
@@ -27,16 +27,21 @@
 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
 import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE;
 
+import android.app.Activity;
 import android.app.settings.SettingsEnums;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.Resources;
 import android.database.ContentObserver;
+import android.icu.text.ListFormatter;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.provider.Settings;
 import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.Pair;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -48,9 +53,12 @@
 import androidx.preference.Preference;
 import androidx.recyclerview.widget.RecyclerView;
 
+import com.android.internal.accessibility.dialog.AccessibilityTarget;
+import com.android.internal.accessibility.dialog.AccessibilityTargetHelper;
 import com.android.settings.R;
 import com.android.settings.SetupWizardUtils;
 import com.android.settings.accessibility.AccessibilitySetupWizardUtils;
+import com.android.settings.accessibility.Flags;
 import com.android.settings.accessibility.PreferredShortcuts;
 import com.android.settings.core.SubSettingLauncher;
 import com.android.settings.dashboard.DashboardFragment;
@@ -60,7 +68,10 @@
 import com.google.android.setupcompat.util.WizardManagerHelper;
 import com.google.android.setupdesign.GlifPreferenceLayout;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -171,6 +182,36 @@
         registerSettingsObserver();
     }
 
+    @Override
+    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+        super.onCreatePreferences(savedInstanceState, rootKey);
+
+        Activity activity = getActivity();
+
+        if (!activity.getIntent().getAction().equals(
+                Settings.ACTION_ACCESSIBILITY_SHORTCUT_SETTINGS)
+                || !Flags.editShortcutsInFullScreen()) {
+            return;
+        }
+
+        // TODO(b/325664350): Implement shortcut type for "all shortcuts"
+        List<AccessibilityTarget> accessibilityTargets =
+                AccessibilityTargetHelper.getInstalledTargets(
+                        activity.getBaseContext(), AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY);
+
+        Pair<String, String> titles = getTitlesFromAccessibilityTargetList(
+                mShortcutTargets,
+                accessibilityTargets,
+                activity.getResources()
+        );
+
+        activity.setTitle(titles.first);
+
+        String categoryKey = activity.getResources().getString(
+                R.string.accessibility_shortcut_description_pref);
+        findPreference(categoryKey).setTitle(titles.second);
+    }
+
     @NonNull
     @Override
     public RecyclerView onCreateRecyclerView(
@@ -275,7 +316,6 @@
         }
 
         mShortcutTargets = Set.of(targets);
-        // TODO(318748373): use 'targets' to populate title when no title is given
     }
 
     @Override
@@ -356,4 +396,52 @@
         // A11y Nav Button
         refreshPreferenceController(NavButtonShortcutOptionController.class);
     }
+
+    /**
+     * Generates a title & subtitle pair describing the features whose shortcuts are being edited.
+     *
+     * @param shortcutTargets string list of component names corresponding to
+     *                        the relevant shortcut targets.
+     * @param accessibilityTargets list of accessibility targets
+     *                             to try and find corresponding labels in.
+     * @return pair of strings to be used as page title and subtitle.
+     * If there is only one shortcut label, It is displayed in the title and the subtitle is null.
+     * Otherwise, the title is a generic prompt and the subtitle lists all shortcut labels.
+     */
+    @VisibleForTesting
+    static Pair<String, String> getTitlesFromAccessibilityTargetList(
+            Set<String> shortcutTargets,
+            List<AccessibilityTarget> accessibilityTargets,
+            Resources resources) {
+        ArrayList<CharSequence> featureLabels = new ArrayList<>();
+
+        Map<String, CharSequence> accessibilityTargetLabels = new ArrayMap<>();
+        accessibilityTargets.forEach((target) -> accessibilityTargetLabels.put(
+                target.getId(), target.getLabel()));
+
+        for (String target: shortcutTargets) {
+            if (accessibilityTargetLabels.containsKey(target)) {
+                featureLabels.add(accessibilityTargetLabels.get(target));
+            } else {
+                throw new IllegalStateException("Shortcut target does not have a label: " + target);
+            }
+        }
+
+        if (featureLabels.size() == 1) {
+            return new Pair<>(
+                    resources.getString(
+                            R.string.accessibility_shortcut_title, featureLabels.get(0)),
+                    null
+            );
+        } else if (featureLabels.size() == 0) {
+            throw new IllegalStateException("Found no labels for any shortcut targets.");
+        } else {
+            return new Pair<>(
+                    resources.getString(R.string.accessibility_shortcut_edit_screen_title),
+                    resources.getString(
+                            R.string.accessibility_shortcut_edit_screen_prompt,
+                            ListFormatter.getInstance().format(featureLabels))
+            );
+        }
+    }
 }
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java
index 797364b..ae5b62b 100644
--- a/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java
+++ b/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java
@@ -29,7 +29,9 @@
 import android.view.View;
 import android.widget.Button;
 import android.widget.Toast;
+import android.window.OnBackInvokedCallback;
 
+import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 import androidx.preference.Preference;
 
@@ -57,9 +59,14 @@
     private static final String TAG = "FaceSettings/Remove";
     static final String KEY = "security_settings_face_delete_faces_container";
 
-    public static class ConfirmRemoveDialog extends InstrumentedDialogFragment {
+    public static class ConfirmRemoveDialog extends InstrumentedDialogFragment
+            implements OnBackInvokedCallback {
         private static final String KEY_IS_CONVENIENCE = "is_convenience";
         private DialogInterface.OnClickListener mOnClickListener;
+        @Nullable
+        private AlertDialog mDialog = null;
+        @Nullable
+        private Preference mFaceUnlockPreference = null;
 
         /** Returns the new instance of the class */
         public static ConfirmRemoveDialog newInstance(boolean isConvenience) {
@@ -99,14 +106,41 @@
                     .setMessage(dialogMessageRes)
                     .setPositiveButton(R.string.delete, mOnClickListener)
                     .setNegativeButton(R.string.cancel, mOnClickListener);
-            AlertDialog dialog = builder.create();
-            dialog.setCanceledOnTouchOutside(false);
-            return dialog;
+            mDialog = builder.create();
+            mDialog.setCanceledOnTouchOutside(false);
+            mDialog.getOnBackInvokedDispatcher().registerOnBackInvokedCallback(0, this);
+            return mDialog;
         }
 
         public void setOnClickListener(DialogInterface.OnClickListener listener) {
             mOnClickListener = listener;
         }
+
+        public void setPreference(@Nullable Preference preference) {
+            mFaceUnlockPreference = preference;
+        }
+
+        public void unregisterOnBackInvokedCallback() {
+            if (mDialog != null) {
+                mDialog.getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(this);
+            }
+        }
+
+        @Override
+        public void onBackInvoked() {
+            if (mDialog != null) {
+                mDialog.cancel();
+            }
+            unregisterOnBackInvokedCallback();
+
+            if (mFaceUnlockPreference != null) {
+                final Button removeButton = ((LayoutPreference) mFaceUnlockPreference)
+                        .findViewById(R.id.security_settings_face_settings_remove_button);
+                if (removeButton != null) {
+                    removeButton.setEnabled(true);
+                }
+            }
+        }
     }
 
     interface Listener {
@@ -171,6 +205,13 @@
                 mButton.setEnabled(true);
                 mRemoving = false;
             }
+
+            final ConfirmRemoveDialog removeDialog =
+                    (ConfirmRemoveDialog) mActivity.getSupportFragmentManager()
+                            .findFragmentByTag(ConfirmRemoveDialog.class.getName());
+            if (removeDialog != null) {
+                removeDialog.unregisterOnBackInvokedCallback();
+            }
         }
     };
 
@@ -210,6 +251,7 @@
                 (ConfirmRemoveDialog) mActivity.getSupportFragmentManager()
                         .findFragmentByTag(ConfirmRemoveDialog.class.getName());
         if (removeDialog != null) {
+            removeDialog.setPreference(mPreference);
             mRemoving = true;
             removeDialog.setOnClickListener(mOnConfirmDialogClickListener);
         }
diff --git a/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupController.java b/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupController.java
index fc3493c..0535d15 100644
--- a/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupController.java
+++ b/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupController.java
@@ -17,18 +17,17 @@
 
 import static com.android.settingslib.Utils.isAudioModeOngoingCall;
 
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothLeBroadcastAssistant;
-import android.bluetooth.BluetoothLeBroadcastMetadata;
-import android.bluetooth.BluetoothLeBroadcastReceiveState;
 import android.bluetooth.BluetoothProfile;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.util.Log;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 import androidx.fragment.app.FragmentManager;
+import androidx.lifecycle.DefaultLifecycleObserver;
+import androidx.lifecycle.LifecycleOwner;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceGroup;
 import androidx.preference.PreferenceScreen;
@@ -38,138 +37,66 @@
 import com.android.settings.bluetooth.AvailableMediaBluetoothDeviceUpdater;
 import com.android.settings.bluetooth.BluetoothDeviceUpdater;
 import com.android.settings.bluetooth.Utils;
-import com.android.settings.connecteddevice.audiosharing.AudioSharingUtils;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settingslib.bluetooth.BluetoothCallback;
 import com.android.settingslib.bluetooth.BluetoothUtils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
-import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnStart;
-import com.android.settingslib.core.lifecycle.events.OnStop;
-
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
+import com.android.settingslib.core.lifecycle.Lifecycle;
 
 /**
  * Controller to maintain the {@link androidx.preference.PreferenceGroup} for all available media
  * devices. It uses {@link DevicePreferenceCallback} to add/remove {@link Preference}
  */
 public class AvailableMediaDeviceGroupController extends BasePreferenceController
-        implements LifecycleObserver, OnStart, OnStop, DevicePreferenceCallback, BluetoothCallback {
+        implements DefaultLifecycleObserver, DevicePreferenceCallback, BluetoothCallback {
     private static final boolean DEBUG = BluetoothUtils.D;
 
     private static final String TAG = "AvailableMediaDeviceGroupController";
     private static final String KEY = "available_device_list";
 
-    @VisibleForTesting PreferenceGroup mPreferenceGroup;
+    @VisibleForTesting @Nullable PreferenceGroup mPreferenceGroup;
     @VisibleForTesting LocalBluetoothManager mLocalBluetoothManager;
-    private final Executor mExecutor;
-    private BluetoothDeviceUpdater mBluetoothDeviceUpdater;
-    private FragmentManager mFragmentManager;
-    private BluetoothLeBroadcastAssistant.Callback mAssistantCallback =
-            new BluetoothLeBroadcastAssistant.Callback() {
-                @Override
-                public void onSearchStarted(int reason) {}
+    @Nullable private BluetoothDeviceUpdater mBluetoothDeviceUpdater;
+    @Nullable private FragmentManager mFragmentManager;
 
-                @Override
-                public void onSearchStartFailed(int reason) {}
-
-                @Override
-                public void onSearchStopped(int reason) {}
-
-                @Override
-                public void onSearchStopFailed(int reason) {}
-
-                @Override
-                public void onSourceFound(@NonNull BluetoothLeBroadcastMetadata source) {}
-
-                @Override
-                public void onSourceAdded(@NonNull BluetoothDevice sink, int sourceId, int reason) {
-                    mBluetoothDeviceUpdater.forceUpdate();
-                }
-
-                @Override
-                public void onSourceAddFailed(
-                        @NonNull BluetoothDevice sink,
-                        @NonNull BluetoothLeBroadcastMetadata source,
-                        int reason) {}
-
-                @Override
-                public void onSourceModified(
-                        @NonNull BluetoothDevice sink, int sourceId, int reason) {}
-
-                @Override
-                public void onSourceModifyFailed(
-                        @NonNull BluetoothDevice sink, int sourceId, int reason) {}
-
-                @Override
-                public void onSourceRemoved(
-                        @NonNull BluetoothDevice sink, int sourceId, int reason) {
-                    mBluetoothDeviceUpdater.forceUpdate();
-                }
-
-                @Override
-                public void onSourceRemoveFailed(
-                        @NonNull BluetoothDevice sink, int sourceId, int reason) {}
-
-                @Override
-                public void onReceiveStateChanged(
-                        BluetoothDevice sink,
-                        int sourceId,
-                        BluetoothLeBroadcastReceiveState state) {}
-            };
-
-    public AvailableMediaDeviceGroupController(Context context) {
+    public AvailableMediaDeviceGroupController(
+            Context context,
+            @Nullable DashboardFragment fragment,
+            @Nullable Lifecycle lifecycle) {
         super(context, KEY);
+        if (fragment != null) {
+            init(fragment);
+        }
+        if (lifecycle != null) {
+            lifecycle.addObserver(this);
+        }
         mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
-        mExecutor = Executors.newSingleThreadExecutor();
     }
 
     @Override
-    public void onStart() {
+    public void onStart(@NonNull LifecycleOwner owner) {
         if (mLocalBluetoothManager == null) {
             Log.e(TAG, "onStart() Bluetooth is not supported on this device");
             return;
         }
-        if (AudioSharingUtils.isFeatureEnabled()) {
-            LocalBluetoothLeBroadcastAssistant assistant =
-                    mLocalBluetoothManager
-                            .getProfileManager()
-                            .getLeAudioBroadcastAssistantProfile();
-            if (assistant != null) {
-                if (DEBUG) {
-                    Log.d(TAG, "onStart() Register callbacks for assistant.");
-                }
-                assistant.registerServiceCallBack(mExecutor, mAssistantCallback);
-            }
-        }
-        mBluetoothDeviceUpdater.registerCallback();
         mLocalBluetoothManager.getEventManager().registerCallback(this);
-        mBluetoothDeviceUpdater.refreshPreference();
+        if (mBluetoothDeviceUpdater != null) {
+            mBluetoothDeviceUpdater.registerCallback();
+            mBluetoothDeviceUpdater.refreshPreference();
+        }
     }
 
     @Override
-    public void onStop() {
+    public void onStop(@NonNull LifecycleOwner owner) {
         if (mLocalBluetoothManager == null) {
             Log.e(TAG, "onStop() Bluetooth is not supported on this device");
             return;
         }
-        if (AudioSharingUtils.isFeatureEnabled()) {
-            LocalBluetoothLeBroadcastAssistant assistant =
-                    mLocalBluetoothManager
-                            .getProfileManager()
-                            .getLeAudioBroadcastAssistantProfile();
-            if (assistant != null) {
-                if (DEBUG) {
-                    Log.d(TAG, "onStop() Register callbacks for assistant.");
-                }
-                assistant.unregisterServiceCallBack(mAssistantCallback);
-            }
+        if (mBluetoothDeviceUpdater != null) {
+            mBluetoothDeviceUpdater.unregisterCallback();
         }
-        mBluetoothDeviceUpdater.unregisterCallback();
         mLocalBluetoothManager.getEventManager().unregisterCallback(this);
     }
 
@@ -178,12 +105,16 @@
         super.displayPreference(screen);
 
         mPreferenceGroup = screen.findPreference(KEY);
-        mPreferenceGroup.setVisible(false);
+        if (mPreferenceGroup != null) {
+            mPreferenceGroup.setVisible(false);
+        }
 
         if (isAvailable()) {
             updateTitle();
-            mBluetoothDeviceUpdater.setPrefContext(screen.getContext());
-            mBluetoothDeviceUpdater.forceUpdate();
+            if (mBluetoothDeviceUpdater != null) {
+                mBluetoothDeviceUpdater.setPrefContext(screen.getContext());
+                mBluetoothDeviceUpdater.forceUpdate();
+            }
         }
     }
 
@@ -201,17 +132,21 @@
 
     @Override
     public void onDeviceAdded(Preference preference) {
-        if (mPreferenceGroup.getPreferenceCount() == 0) {
-            mPreferenceGroup.setVisible(true);
+        if (mPreferenceGroup != null) {
+            if (mPreferenceGroup.getPreferenceCount() == 0) {
+                mPreferenceGroup.setVisible(true);
+            }
+            mPreferenceGroup.addPreference(preference);
         }
-        mPreferenceGroup.addPreference(preference);
     }
 
     @Override
     public void onDeviceRemoved(Preference preference) {
-        mPreferenceGroup.removePreference(preference);
-        if (mPreferenceGroup.getPreferenceCount() == 0) {
-            mPreferenceGroup.setVisible(false);
+        if (mPreferenceGroup != null) {
+            mPreferenceGroup.removePreference(preference);
+            if (mPreferenceGroup.getPreferenceCount() == 0) {
+                mPreferenceGroup.setVisible(false);
+            }
         }
     }
 
@@ -253,14 +188,16 @@
     }
 
     private void updateTitle() {
-        if (isAudioModeOngoingCall(mContext)) {
-            // in phone call
-            mPreferenceGroup.setTitle(
-                    mContext.getString(R.string.connected_device_call_device_title));
-        } else {
-            // without phone call
-            mPreferenceGroup.setTitle(
-                    mContext.getString(R.string.connected_device_media_device_title));
+        if (mPreferenceGroup != null) {
+            if (isAudioModeOngoingCall(mContext)) {
+                // in phone call
+                mPreferenceGroup.setTitle(
+                        mContext.getString(R.string.connected_device_call_device_title));
+            } else {
+                // without phone call
+                mPreferenceGroup.setTitle(
+                        mContext.getString(R.string.connected_device_media_device_title));
+            }
         }
     }
 }
diff --git a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java
index 2798be4..04ba5d2 100644
--- a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java
@@ -24,12 +24,10 @@
 
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
-import androidx.lifecycle.Lifecycle;
 
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.Utils;
-import com.android.settings.connecteddevice.audiosharing.AudioSharingUtils;
 import com.android.settings.core.SettingsUIDeviceConfig;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.overlay.FeatureFactory;
@@ -38,6 +36,7 @@
 import com.android.settings.slices.SlicePreferenceController;
 import com.android.settingslib.bluetooth.HearingAidStatsLogUtils;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.search.SearchIndexable;
 
 import java.util.ArrayList;
@@ -92,7 +91,6 @@
                             + ", action : "
                             + action);
         }
-        use(AvailableMediaDeviceGroupController.class).init(this);
         use(ConnectedDeviceGroupController.class).init(this);
         use(PreviouslyConnectedDevicePreferenceController.class).init(this);
         use(SlicePreferenceController.class)
@@ -124,15 +122,17 @@
             @Nullable ConnectedDeviceDashboardFragment fragment,
             @Nullable Lifecycle lifecycle) {
         final List<AbstractPreferenceController> controllers = new ArrayList<>();
-        if (AudioSharingUtils.isFeatureEnabled()) {
-            AbstractPreferenceController audioSharingController =
-                    FeatureFactory.getFeatureFactory()
-                            .getAudioSharingFeatureProvider()
-                            .createAudioSharingDevicePreferenceController(
-                                    context, fragment, lifecycle);
-            if (audioSharingController != null) {
-                controllers.add(audioSharingController);
-            }
+        AbstractPreferenceController availableMediaController =
+                FeatureFactory.getFeatureFactory()
+                        .getAudioSharingFeatureProvider()
+                        .createAvailableMediaDeviceGroupController(context, fragment, lifecycle);
+        controllers.add(availableMediaController);
+        AbstractPreferenceController audioSharingController =
+                FeatureFactory.getFeatureFactory()
+                        .getAudioSharingFeatureProvider()
+                        .createAudioSharingDevicePreferenceController(context, fragment, lifecycle);
+        if (audioSharingController != null) {
+            controllers.add(audioSharingController);
         }
         return controllers;
     }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProvider.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProvider.java
index c71a368..9fe4d50 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProvider.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProvider.java
@@ -20,12 +20,12 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.lifecycle.Lifecycle;
 
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
 
 /** Feature provider for the audio sharing related features, */
 public interface AudioSharingFeatureProvider {
@@ -37,6 +37,12 @@
             @Nullable DashboardFragment fragment,
             @Nullable Lifecycle lifecycle);
 
+    /** Create available media device preference controller. */
+    AbstractPreferenceController createAvailableMediaDeviceGroupController(
+            @NonNull Context context,
+            @Nullable DashboardFragment fragment,
+            @Nullable Lifecycle lifecycle);
+
     /**
      * Check if the device match the audio sharing filter.
      *
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProviderImpl.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProviderImpl.java
index 05a6a63..259ed7a 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProviderImpl.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProviderImpl.java
@@ -20,12 +20,13 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.lifecycle.Lifecycle;
 
+import com.android.settings.connecteddevice.AvailableMediaDeviceGroupController;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
 
 public class AudioSharingFeatureProviderImpl implements AudioSharingFeatureProvider {
 
@@ -39,6 +40,14 @@
     }
 
     @Override
+    public AbstractPreferenceController createAvailableMediaDeviceGroupController(
+            @NonNull Context context,
+            @Nullable DashboardFragment fragment,
+            @Nullable Lifecycle lifecycle) {
+        return new AvailableMediaDeviceGroupController(context, fragment, lifecycle);
+    }
+
+    @Override
     public boolean isAudioSharingFilterMatched(
             @NonNull CachedBluetoothDevice cachedDevice, LocalBluetoothManager localBtManager) {
         return false;
diff --git a/src/com/android/settings/development/ForcePeakRefreshRatePreferenceController.java b/src/com/android/settings/development/ForcePeakRefreshRatePreferenceController.java
index abeb949..455f74f 100644
--- a/src/com/android/settings/development/ForcePeakRefreshRatePreferenceController.java
+++ b/src/com/android/settings/development/ForcePeakRefreshRatePreferenceController.java
@@ -17,6 +17,7 @@
 package com.android.settings.development;
 
 import static com.android.internal.display.RefreshRateSettingsUtils.DEFAULT_REFRESH_RATE;
+import static com.android.internal.display.RefreshRateSettingsUtils.findHighestRefreshRateAmongAllDisplays;
 import static com.android.internal.display.RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay;
 
 import android.content.Context;
@@ -47,7 +48,9 @@
 
     public ForcePeakRefreshRatePreferenceController(Context context) {
         super(context);
-        mPeakRefreshRate = findHighestRefreshRateForDefaultDisplay(context);
+        mPeakRefreshRate = Flags.backUpSmoothDisplayAndForcePeakRefreshRate()
+                ? findHighestRefreshRateAmongAllDisplays(context)
+                : findHighestRefreshRateForDefaultDisplay(context);
         Log.d(TAG, "DEFAULT_REFRESH_RATE : " + DEFAULT_REFRESH_RATE
             + " mPeakRefreshRate : " + mPeakRefreshRate);
     }
diff --git a/src/com/android/settings/development/SensitiveContentProtectionPreferenceController.kt b/src/com/android/settings/development/SensitiveContentProtectionPreferenceController.kt
index e627f81..8acd700 100644
--- a/src/com/android/settings/development/SensitiveContentProtectionPreferenceController.kt
+++ b/src/com/android/settings/development/SensitiveContentProtectionPreferenceController.kt
@@ -18,6 +18,7 @@
 import android.content.Context
 import android.permission.flags.Flags.sensitiveNotificationAppProtection
 import android.provider.Settings
+import android.view.flags.Flags.sensitiveContentAppProtection
 import androidx.annotation.VisibleForTesting
 import androidx.preference.Preference
 import androidx.preference.TwoStatePreference
@@ -64,6 +65,7 @@
 
     override fun isAvailable(): Boolean {
         return sensitiveNotificationAppProtection() || screenshareNotificationHiding()
+            || sensitiveContentAppProtection()
     }
 
     companion object {
diff --git a/src/com/android/settings/display/PeakRefreshRatePreferenceController.java b/src/com/android/settings/display/PeakRefreshRatePreferenceController.java
index 17d763a..261eaf1 100644
--- a/src/com/android/settings/display/PeakRefreshRatePreferenceController.java
+++ b/src/com/android/settings/display/PeakRefreshRatePreferenceController.java
@@ -17,6 +17,7 @@
 package com.android.settings.display;
 
 import static com.android.internal.display.RefreshRateSettingsUtils.DEFAULT_REFRESH_RATE;
+import static com.android.internal.display.RefreshRateSettingsUtils.findHighestRefreshRateAmongAllDisplays;
 import static com.android.internal.display.RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay;
 
 import android.content.Context;
@@ -66,7 +67,9 @@
                         updateState(mPreference);
                     }
                 };
-        mPeakRefreshRate = Math.round(findHighestRefreshRateForDefaultDisplay(context));
+        mPeakRefreshRate = Math.round(Flags.backUpSmoothDisplayAndForcePeakRefreshRate()
+                ? findHighestRefreshRateAmongAllDisplays(context)
+                : findHighestRefreshRateForDefaultDisplay(context));
         Log.d(
                 TAG,
                 "DEFAULT_REFRESH_RATE : "
diff --git a/src/com/android/settings/network/SubscriptionUtil.java b/src/com/android/settings/network/SubscriptionUtil.java
index 84e4e75..2498ec9 100644
--- a/src/com/android/settings/network/SubscriptionUtil.java
+++ b/src/com/android/settings/network/SubscriptionUtil.java
@@ -17,13 +17,15 @@
 package com.android.settings.network;
 
 import static android.telephony.SubscriptionManager.INVALID_SIM_SLOT_INDEX;
-import static android.telephony.UiccSlotInfo.CARD_STATE_INFO_PRESENT;
 import static android.telephony.SubscriptionManager.PROFILE_CLASS_PROVISIONING;
+import static android.telephony.UiccSlotInfo.CARD_STATE_INFO_PRESENT;
 
 import static com.android.internal.util.CollectionUtils.emptyIfNull;
 
 import android.content.Context;
 import android.content.SharedPreferences;
+import android.net.ConnectivityManager;
+import android.net.NetworkCapabilities;
 import android.os.ParcelUuid;
 import android.provider.Settings;
 import android.telephony.PhoneNumberUtils;
@@ -560,6 +562,7 @@
             Log.i(TAG, "Unable to delete subscription due to invalid subscription ID.");
             return;
         }
+        // TODO(b/325693582): Add verification if carrier is RAC and logic for new dialog
         context.startActivity(DeleteEuiccSubscriptionDialogActivity.getIntent(context, subId));
     }
 
@@ -832,4 +835,29 @@
         }
         return true;
     }
+
+    /**
+     * Returns {@code true} if device is connected to Wi-Fi or mobile data provided by a different
+     * subId.
+     *
+     * @param context context
+     * @param targetSubId subscription that is going to be deleted
+     */
+    @VisibleForTesting
+    static boolean isConnectedToWifiOrDifferentSubId(@NonNull Context context, int targetSubId) {
+        ConnectivityManager connectivityManager =
+                context.getSystemService(ConnectivityManager.class);
+        NetworkCapabilities capabilities =
+                connectivityManager.getNetworkCapabilities(connectivityManager.getActiveNetwork());
+
+        if (capabilities != null) {
+            if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
+                // Connected to WiFi
+                return true;
+            } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
+                return targetSubId != SubscriptionManager.getActiveDataSubscriptionId();
+            }
+        }
+        return false;
+    }
 }
diff --git a/src/com/android/settings/network/telephony/EuiccRacConnectivityDialogActivity.java b/src/com/android/settings/network/telephony/EuiccRacConnectivityDialogActivity.java
new file mode 100644
index 0000000..cb4ab18
--- /dev/null
+++ b/src/com/android/settings/network/telephony/EuiccRacConnectivityDialogActivity.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network.telephony;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.telephony.SubscriptionManager;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import com.android.settings.R;
+
+/** This dialog activity advise the user to have connectivity if the eSIM uses a RAC. */
+public class EuiccRacConnectivityDialogActivity extends SubscriptionActionDialogActivity
+        implements WarningDialogFragment.OnConfirmListener {
+
+    private static final String TAG = "EuiccRacConnectivityDialogActivity";
+    // Dialog tags
+    private static final int DIALOG_TAG_ERASE_ANYWAY_CONFIRMATION = 1;
+
+    private int mSubId;
+
+    /**
+     * Returns an intent of EuiccRacConnectivityDialogActivity.
+     *
+     * @param context The context used to start the EuiccRacConnectivityDialogActivity.
+     * @param subId The subscription ID of the subscription needs to be deleted. If the subscription
+     *     belongs to a group of subscriptions, all subscriptions from the group will be deleted.
+     */
+    @NonNull
+    public static Intent getIntent(@NonNull Context context, int subId) {
+        Intent intent = new Intent(context, EuiccRacConnectivityDialogActivity.class);
+        intent.putExtra(ARG_SUB_ID, subId);
+        return intent;
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        Intent intent = getIntent();
+        mSubId = intent.getIntExtra(ARG_SUB_ID, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+
+        if (savedInstanceState == null) {
+            showConnectivityWarningDialog();
+        }
+    }
+
+    @Override
+    public void onConfirm(int tag, boolean confirmed) {
+        if (!confirmed) {
+            finish();
+            return;
+        }
+
+        switch (tag) {
+            case DIALOG_TAG_ERASE_ANYWAY_CONFIRMATION:
+                finish();
+                Log.i(TAG, "Show dialogue activity that handles deleting eSIM profiles");
+                startActivity(DeleteEuiccSubscriptionDialogActivity.getIntent(this, mSubId));
+                break;
+            default:
+                Log.e(TAG, "Unrecognized confirmation dialog tag: " + tag);
+                break;
+        }
+    }
+
+    /* Displays warning to have connectivity because subscription is RAC dialog. */
+    private void showConnectivityWarningDialog() {
+        WarningDialogFragment.show(
+                this,
+                WarningDialogFragment.OnConfirmListener.class,
+                DIALOG_TAG_ERASE_ANYWAY_CONFIRMATION,
+                getString(R.string.wifi_warning_dialog_title),
+                getString(R.string.wifi_warning_dialog_text),
+                getString(R.string.wifi_warning_continue_button),
+                getString(R.string.wifi_warning_return_button));
+    }
+}
diff --git a/src/com/android/settings/network/telephony/WarningDialogFragment.java b/src/com/android/settings/network/telephony/WarningDialogFragment.java
new file mode 100644
index 0000000..58bc1da
--- /dev/null
+++ b/src/com/android/settings/network/telephony/WarningDialogFragment.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network.telephony;
+
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.FragmentActivity;
+
+import com.android.settings.R;
+
+/** Fragment to show a warning dialog. The caller should implement onConfirmListener. */
+public class WarningDialogFragment extends BaseDialogFragment
+        implements DialogInterface.OnClickListener {
+    private static final String TAG = "WarningDialogFragment";
+    private static final String ARG_TITLE = "title";
+    private static final String ARG_MSG = "msg";
+    private static final String ARG_POS_BUTTON_STRING = "pos_button_string";
+    private static final String ARG_NEG_BUTTON_STRING = "neg_button_string";
+
+    /**
+     * Interface defining the method that will be invoked when the user has done with the dialog.
+     */
+    public interface OnConfirmListener {
+        /**
+         * @param tag The tag in the caller.
+         * @param confirmed True if the user has clicked the positive button. False if the user has
+         *     clicked the negative button or cancel the dialog.
+         */
+        void onConfirm(int tag, boolean confirmed);
+    }
+
+    /** Displays a confirmation dialog which has confirm and cancel buttons. */
+    static <T> void show(
+            FragmentActivity activity,
+            Class<T> callbackInterfaceClass,
+            int tagInCaller,
+            String title,
+            String msg,
+            String posButtonString,
+            String negButtonString) {
+        WarningDialogFragment fragment = new WarningDialogFragment();
+        Bundle arguments = new Bundle();
+        arguments.putString(ARG_TITLE, title);
+        arguments.putCharSequence(ARG_MSG, msg);
+        arguments.putString(ARG_POS_BUTTON_STRING, posButtonString);
+        arguments.putString(ARG_NEG_BUTTON_STRING, negButtonString);
+        setListener(activity, null, callbackInterfaceClass, tagInCaller, arguments);
+        fragment.setArguments(arguments);
+        fragment.show(activity.getSupportFragmentManager(), TAG);
+    }
+
+    @Override
+    @NonNull
+    public final Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+        String title = getArguments().getString(ARG_TITLE);
+        String message = getArguments().getString(ARG_MSG);
+        String leftButton = getArguments().getString(ARG_POS_BUTTON_STRING);
+        String rightButton = getArguments().getString(ARG_NEG_BUTTON_STRING);
+
+        Log.i(TAG, "Showing dialog with title =" + title);
+        AlertDialog.Builder builder =
+                new AlertDialog.Builder(getContext())
+                        .setPositiveButton(rightButton, this)
+                        .setNegativeButton(leftButton, this);
+
+        View content =
+                LayoutInflater.from(getContext())
+                        .inflate(R.layout.sim_warning_dialog_wifi_connectivity, null);
+
+        if (content != null) {
+            TextView dialogTitle = content.findViewById(R.id.title);
+            if (!TextUtils.isEmpty(title) && dialogTitle != null) {
+                dialogTitle.setText(title);
+                dialogTitle.setVisibility(View.VISIBLE);
+            }
+            TextView dialogMessage = content.findViewById(R.id.msg);
+            if (!TextUtils.isEmpty(message) && dialogMessage != null) {
+                dialogMessage.setText(message);
+                dialogMessage.setVisibility(View.VISIBLE);
+            }
+
+            builder.setView(content);
+        } else {
+            if (!TextUtils.isEmpty(title)) {
+                builder.setTitle(title);
+            }
+            if (!TextUtils.isEmpty(message)) {
+                builder.setMessage(message);
+            }
+        }
+
+        AlertDialog dialog = builder.create();
+        dialog.setCanceledOnTouchOutside(false);
+        return dialog;
+    }
+
+    @Override
+    public void onClick(@NonNull DialogInterface dialog, int which) {
+        Log.i(TAG, "dialog onClick =" + which);
+
+        // Positions of the buttons have been switch:
+        // negative button = left button = the button to continue
+        informCaller(which == DialogInterface.BUTTON_NEGATIVE);
+    }
+
+    @Override
+    public void onCancel(@NonNull DialogInterface dialog) {
+        informCaller(false);
+    }
+
+    private void informCaller(boolean confirmed) {
+        OnConfirmListener listener;
+        try {
+            listener = getListener(OnConfirmListener.class);
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, "Do nothing and return.", e);
+            return;
+        }
+        if (listener == null) {
+            return;
+        }
+        listener.onConfirm(getTagInCaller(), confirmed);
+    }
+}
diff --git a/src/com/android/settings/widget/CardPreference.kt b/src/com/android/settings/widget/CardPreference.kt
index 7122ac6..010d7de 100644
--- a/src/com/android/settings/widget/CardPreference.kt
+++ b/src/com/android/settings/widget/CardPreference.kt
@@ -61,6 +61,9 @@
     /** The visibility of secondary button on tips card. The default value is `false`. */
     var secondaryButtonVisibility: Boolean = false
 
+    var onClick: (() -> Unit)? = null
+
+    /** The callback for click on card preference itself. */
     private var onDismiss: (() -> Unit)? = null
 
     /** Enable the dismiss button on tips card. */
@@ -84,9 +87,10 @@
                     buttons = listOfNotNull(configPrimaryButton(), configSecondaryButton()),
                     onDismiss = onDismiss,
                     imageVector =
-                        iconResId
-                            ?.takeIf { it != Resources.ID_NULL }
-                            ?.let { ImageVector.vectorResource(it) },
+                    iconResId
+                        ?.takeIf { it != Resources.ID_NULL }
+                        ?.let { ImageVector.vectorResource(it) },
+                    onClick = onClick,
                 )
             )
         }
diff --git a/tests/robotests/Android.bp b/tests/robotests/Android.bp
index 5648290..1c6794d 100644
--- a/tests/robotests/Android.bp
+++ b/tests/robotests/Android.bp
@@ -71,10 +71,12 @@
         "Settings-testutils2",
         "notification_flags_lib",
         "com_android_server_accessibility_flags_lib",
+        "testables",
     ],
 
     libs: [
         "ims-common",
+        "android.test.mock",
     ],
 
     java_resource_dirs: [
diff --git a/tests/robotests/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragmentTest.java
index 13f0b24..b2ddb6c 100644
--- a/tests/robotests/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragmentTest.java
@@ -28,6 +28,9 @@
 import static com.google.android.setupcompat.util.WizardManagerHelper.EXTRA_IS_SETUP_FLOW;
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.assertThrows;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 import static org.robolectric.Shadows.shadowOf;
 
 import android.content.ComponentName;
@@ -35,7 +38,9 @@
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.Settings;
+import android.util.Pair;
 import android.view.accessibility.AccessibilityManager;
 
 import androidx.fragment.app.FragmentActivity;
@@ -46,6 +51,7 @@
 import androidx.test.core.app.ApplicationProvider;
 
 import com.android.internal.accessibility.common.ShortcutConstants;
+import com.android.internal.accessibility.dialog.AccessibilityTarget;
 import com.android.internal.accessibility.util.ShortcutUtils;
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
@@ -60,6 +66,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.Robolectric;
@@ -89,6 +96,9 @@
     private static final String TARGET = MAGNIFICATION_CONTROLLER_NAME;
     private static final Set<String> TARGETS = Set.of(TARGET);
 
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
     private final Context mContext = ApplicationProvider.getApplicationContext();
     private FragmentActivity mActivity;
     private FragmentScenario<EditShortcutsPreferenceFragment> mFragmentScenario;
@@ -414,6 +424,60 @@
 
     }
 
+    @Test
+    public void findTitles_withSingleTarget_hasNullSubtitle() {
+        final String fake_label = "FAKE";
+        List<AccessibilityTarget> accessibilityTargets = List.of(
+                generateAccessibilityTargetMock(TARGET_FAKE_COMPONENT, fake_label));
+
+        Pair<String, String> titles = EditShortcutsPreferenceFragment
+                .getTitlesFromAccessibilityTargetList(
+                        Set.of(TARGET_FAKE_COMPONENT.flattenToString()),
+                        accessibilityTargets, mActivity.getResources()
+                );
+
+        assertThat(titles.first).isNotNull();
+        assertThat(titles.first).contains(fake_label);
+        assertThat(titles.second).isNull();
+    }
+
+    @Test
+    public void findTitles_withMoreTargets_hasSubtitle() {
+        final String fake_label = "FAKE";
+        final String magnification_label = "MAGNIFICATION";
+        List<AccessibilityTarget> accessibilityTargets = List.of(
+                generateAccessibilityTargetMock(TARGET_FAKE_COMPONENT, fake_label),
+                generateAccessibilityTargetMock(MAGNIFICATION_COMPONENT_NAME, magnification_label));
+
+        Pair<String, String> titles = EditShortcutsPreferenceFragment
+                .getTitlesFromAccessibilityTargetList(
+                        Set.of(TARGET_FAKE_COMPONENT.flattenToString(),
+                                MAGNIFICATION_COMPONENT_NAME.flattenToString()),
+                        accessibilityTargets, mActivity.getResources()
+                );
+
+        assertThat(titles.first).isNotNull();
+        assertThat(titles.second).isNotNull();
+        assertThat(titles.second).contains(fake_label);
+        assertThat(titles.second).contains(magnification_label);
+    }
+
+    @Test
+    public void findTitles_targetMissing_labelNotInTitles() {
+        final String fake_label = "FAKE";
+        List<AccessibilityTarget> accessibilityTargets = List.of(
+                generateAccessibilityTargetMock(TARGET_FAKE_COMPONENT, fake_label));
+
+        assertThrows(IllegalStateException.class,
+                () -> EditShortcutsPreferenceFragment
+                        .getTitlesFromAccessibilityTargetList(
+                                Set.of(MAGNIFICATION_COMPONENT_NAME.flattenToString()),
+                                accessibilityTargets, mActivity.getResources()
+                        ));
+    }
+
+
+
     private void assertLaunchSubSettingWithCurrentTargetComponents(
             String componentName, boolean isInSuw) {
         Intent intent = shadowOf(mActivity.getApplication()).getNextStartedActivity();
@@ -480,4 +544,12 @@
         intent.putExtra(EXTRA_IS_DEFERRED_SETUP, isInSuw);
         return intent;
     }
+
+    private AccessibilityTarget generateAccessibilityTargetMock(
+            ComponentName componentName, String label) {
+        AccessibilityTarget target = mock(AccessibilityTarget.class);
+        when(target.getComponentName()).thenReturn(componentName);
+        when(target.getLabel()).thenReturn(label);
+        return target;
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/applications/InstalledAppCounterTest.java b/tests/robotests/src/com/android/settings/applications/InstalledAppCounterTest.java
index 1d76806..e2c9573 100644
--- a/tests/robotests/src/com/android/settings/applications/InstalledAppCounterTest.java
+++ b/tests/robotests/src/com/android/settings/applications/InstalledAppCounterTest.java
@@ -41,9 +41,11 @@
 import android.content.pm.UserInfo;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.platform.test.flag.junit.SetFlagsRule;
 
 import org.junit.Before;
 import org.junit.Ignore;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentMatcher;
@@ -85,6 +87,9 @@
     @Mock
     private PackageManager mPackageManager;
 
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
     private int mInstalledAppCount = -1;
     private ApplicationInfo mApp1;
     private ApplicationInfo mApp2;
@@ -218,6 +223,7 @@
                 eq(MAIN_USER_ID))).thenReturn(Arrays.asList(mApp2));
 
         mFakeFeatureFlags.setFlag(Flags.FLAG_ARCHIVING, false);
+        mSetFlagsRule.disableFlags(com.android.settings.flags.Flags.FLAG_APP_ARCHIVING);
         // Count the number of all apps installed, irrespective of install reason.
         count(InstalledAppCounter.IGNORE_INSTALL_REASON, mFakeFeatureFlags);
         assertThat(mInstalledAppCount).isEqualTo(1);
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java
index 4fdf560..46d1cc3 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java
@@ -35,6 +35,7 @@
 import static org.mockito.Mockito.when;
 
 import android.app.admin.DevicePolicyManager;
+import android.app.ecm.EnhancedConfirmationManager;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
@@ -90,7 +91,8 @@
     private DevicePolicyManager mDevicePolicyManager;
     @Mock
     private PackageManager mPackageManager;
-
+    @Mock
+    private EnhancedConfirmationManager mEcManager;
     private AppInfoDashboardFragment mFragment;
     private Context mShadowContext;
 
@@ -102,6 +104,7 @@
         doReturn(mActivity).when(mFragment).getActivity();
         doReturn(mShadowContext).when(mFragment).getContext();
         doReturn(mPackageManager).when(mActivity).getPackageManager();
+        doReturn(mEcManager).when(mActivity).getSystemService(EnhancedConfirmationManager.class);
         when(mUserManager.isAdminUser()).thenReturn(true);
 
         ReflectionHelpers.setField(mFragment, "mUserManager", mUserManager);
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerTestBase.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerTestBase.java
index 8ba0b44..4edf117 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerTestBase.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerTestBase.java
@@ -43,6 +43,7 @@
 @RunWith(RobolectricTestRunner.class)
 @Config(shadows = {
         com.android.settings.testutils.shadow.ShadowFragment.class,
+        com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal.class,
 })
 public abstract class BluetoothDetailsControllerTestBase {
 
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupControllerTest.java
index e5964d0..357420a 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupControllerTest.java
@@ -22,27 +22,23 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.robolectric.shadows.ShadowLooper.shadowMainLooper;
 
-import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothLeBroadcastAssistant;
 import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothStatusCodes;
 import android.content.Context;
 import android.content.pm.PackageManager;
 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 androidx.appcompat.app.AlertDialog;
 import androidx.fragment.app.FragmentActivity;
+import androidx.lifecycle.LifecycleOwner;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceGroup;
 import androidx.preference.PreferenceManager;
@@ -51,19 +47,16 @@
 import com.android.settings.R;
 import com.android.settings.bluetooth.AvailableMediaBluetoothDeviceUpdater;
 import com.android.settings.bluetooth.Utils;
-import com.android.settings.flags.Flags;
 import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
 import com.android.settings.testutils.shadow.ShadowAudioManager;
-import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
 import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
 import com.android.settingslib.bluetooth.BluetoothCallback;
 import com.android.settingslib.bluetooth.BluetoothEventManager;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
 import com.android.settingslib.bluetooth.HearingAidInfo;
-import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
-import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+import com.android.settingslib.core.lifecycle.Lifecycle;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -76,16 +69,12 @@
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
-import org.robolectric.shadow.api.Shadow;
-
-import java.util.concurrent.Executor;
 
 /** Tests for {@link AvailableMediaDeviceGroupController}. */
 @RunWith(RobolectricTestRunner.class)
 @Config(
         shadows = {
             ShadowAudioManager.class,
-            ShadowBluetoothAdapter.class,
             ShadowBluetoothUtils.class,
             ShadowAlertDialogCompat.class,
         })
@@ -105,9 +94,7 @@
     @Mock private PackageManager mPackageManager;
     @Mock private BluetoothEventManager mEventManager;
     @Mock private LocalBluetoothManager mLocalBluetoothManager;
-    @Mock private LocalBluetoothProfileManager mLocalBtProfileManager;
     @Mock private CachedBluetoothDeviceManager mCachedDeviceManager;
-    @Mock private LocalBluetoothLeBroadcastAssistant mAssistant;
     @Mock private CachedBluetoothDevice mCachedBluetoothDevice;
 
     private PreferenceGroup mPreferenceGroup;
@@ -115,13 +102,16 @@
     private Preference mPreference;
     private AvailableMediaDeviceGroupController mAvailableMediaDeviceGroupController;
     private AudioManager mAudioManager;
-    private ShadowBluetoothAdapter mShadowBluetoothAdapter;
+    private LifecycleOwner mLifecycleOwner;
+    private Lifecycle mLifecycle;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
         mContext = spy(RuntimeEnvironment.application);
+        mLifecycleOwner = () -> mLifecycle;
+        mLifecycle = new Lifecycle(mLifecycleOwner);
         mPreference = new Preference(mContext);
         mPreference.setKey(PREFERENCE_KEY_1);
         mPreferenceGroup = spy(new PreferenceScreen(mContext, null));
@@ -130,24 +120,17 @@
         doReturn(mPackageManager).when(mContext).getPackageManager();
         doReturn(true).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
 
-        mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
-        mShadowBluetoothAdapter.setEnabled(true);
-        mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
-                BluetoothStatusCodes.FEATURE_NOT_SUPPORTED);
-        mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
-                BluetoothStatusCodes.FEATURE_NOT_SUPPORTED);
         ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
         mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
         mAudioManager = mContext.getSystemService(AudioManager.class);
         doReturn(mEventManager).when(mLocalBluetoothManager).getEventManager();
-        when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBtProfileManager);
         when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
         when(mCachedDeviceManager.findDevice(any(BluetoothDevice.class)))
                 .thenReturn(mCachedBluetoothDevice);
         when(mCachedBluetoothDevice.getAddress()).thenReturn(TEST_DEVICE_ADDRESS);
 
         mAvailableMediaDeviceGroupController =
-                spy(new AvailableMediaDeviceGroupController(mContext));
+                spy(new AvailableMediaDeviceGroupController(mContext, null, mLifecycle));
         mAvailableMediaDeviceGroupController.setBluetoothDeviceUpdater(
                 mAvailableMediaBluetoothDeviceUpdater);
         mAvailableMediaDeviceGroupController.setFragmentManager(
@@ -197,7 +180,7 @@
     @Test
     public void testRegister() {
         // register the callback in onStart()
-        mAvailableMediaDeviceGroupController.onStart();
+        mAvailableMediaDeviceGroupController.onStart(mLifecycleOwner);
 
         verify(mAvailableMediaBluetoothDeviceUpdater).registerCallback();
         verify(mLocalBluetoothManager.getEventManager())
@@ -206,36 +189,15 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
-    public void testRegister_audioSharingOn() {
-        setUpBroadcast();
-        // register the callback in onStart()
-        mAvailableMediaDeviceGroupController.onStart();
-        verify(mAssistant)
-                .registerServiceCallBack(
-                        any(Executor.class), any(BluetoothLeBroadcastAssistant.Callback.class));
-    }
-
-    @Test
     public void testUnregister() {
         // unregister the callback in onStop()
-        mAvailableMediaDeviceGroupController.onStop();
+        mAvailableMediaDeviceGroupController.onStop(mLifecycleOwner);
         verify(mAvailableMediaBluetoothDeviceUpdater).unregisterCallback();
         verify(mLocalBluetoothManager.getEventManager())
                 .unregisterCallback(any(BluetoothCallback.class));
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
-    public void testUnregister_audioSharingOn() {
-        setUpBroadcast();
-        // unregister the callback in onStop()
-        mAvailableMediaDeviceGroupController.onStop();
-        verify(mAssistant)
-                .unregisterServiceCallBack(any(BluetoothLeBroadcastAssistant.Callback.class));
-    }
-
-    @Test
     public void testGetAvailabilityStatus_noBluetoothFeature_returnUnSupported() {
         doReturn(false).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
 
@@ -274,7 +236,7 @@
         mAvailableMediaDeviceGroupController.mLocalBluetoothManager = null;
 
         // Shouldn't crash
-        mAvailableMediaDeviceGroupController.onStart();
+        mAvailableMediaDeviceGroupController.onStart(mLifecycleOwner);
     }
 
     @Test
@@ -282,7 +244,7 @@
         mAvailableMediaDeviceGroupController.mLocalBluetoothManager = null;
 
         // Shouldn't crash
-        mAvailableMediaDeviceGroupController.onStop();
+        mAvailableMediaDeviceGroupController.onStop(mLifecycleOwner);
     }
 
     @Test
@@ -300,19 +262,4 @@
         final AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
         assertThat(dialog.isShowing()).isTrue();
     }
-
-    private void setUpBroadcast() {
-        mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
-                BluetoothStatusCodes.FEATURE_SUPPORTED);
-        mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
-                BluetoothStatusCodes.FEATURE_SUPPORTED);
-        when(mLocalBtProfileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(mAssistant);
-        doNothing()
-                .when(mAssistant)
-                .registerServiceCallBack(
-                        any(Executor.class), any(BluetoothLeBroadcastAssistant.Callback.class));
-        doNothing()
-                .when(mAssistant)
-                .unregisterServiceCallBack(any(BluetoothLeBroadcastAssistant.Callback.class));
-    }
 }
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentTest.java
index 09f7a38..ee4f952 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentTest.java
@@ -20,19 +20,25 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.SearchIndexableResource;
 
 import com.android.settings.R;
+import com.android.settings.connecteddevice.fastpair.FastPairDeviceUpdater;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.core.PreferenceControllerListHelper;
+import com.android.settings.flags.Flags;
 import com.android.settings.slices.SlicePreferenceController;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
 import com.android.settings.testutils.shadow.ShadowConnectivityManager;
 import com.android.settings.testutils.shadow.ShadowUserManager;
@@ -60,6 +66,8 @@
     @Rule
     public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
 
+    @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
     private static final String KEY_NEARBY_DEVICES = "bt_nearby_slice";
     private static final String KEY_DISCOVERABLE_FOOTER = "discoverable_footer";
     private static final String KEY_SAVED_DEVICE_SEE_ALL = "previously_connected_devices_see_all";
@@ -75,8 +83,11 @@
     private static final String TEST_ACTION = "com.testapp.settings.ACTION_START";
 
     @Mock private PackageManager mPackageManager;
+    @Mock private FastPairDeviceUpdater mFastPairDeviceUpdater;
     private Context mContext;
     private ConnectedDeviceDashboardFragment mFragment;
+    private FakeFeatureFactory mFeatureFactory;
+    private AvailableMediaDeviceGroupController mMediaDeviceGroupController;
 
     @Before
     public void setUp() {
@@ -84,6 +95,22 @@
 
         mContext = spy(RuntimeEnvironment.application);
         mFragment = new ConnectedDeviceDashboardFragment();
+        mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_SUBSEQUENT_PAIR_SETTINGS_INTEGRATION);
+        mFeatureFactory = FakeFeatureFactory.setupForTest();
+        when(mFeatureFactory
+                        .getFastPairFeatureProvider()
+                        .getFastPairDeviceUpdater(
+                                any(Context.class), any(DevicePreferenceCallback.class)))
+                .thenReturn(mFastPairDeviceUpdater);
+        when(mFeatureFactory
+                        .getAudioSharingFeatureProvider()
+                        .createAudioSharingDevicePreferenceController(mContext, null, null))
+                .thenReturn(null);
+        mMediaDeviceGroupController = new AvailableMediaDeviceGroupController(mContext, null, null);
+        when(mFeatureFactory
+                        .getAudioSharingFeatureProvider()
+                        .createAvailableMediaDeviceGroupController(mContext, null, null))
+                .thenReturn(mMediaDeviceGroupController);
         doReturn(mPackageManager).when(mContext).getPackageManager();
         doReturn(true).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
     }
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProviderImplTest.java
index 0edbc77..1965bff 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProviderImplTest.java
@@ -22,6 +22,7 @@
 
 import androidx.test.core.app.ApplicationProvider;
 
+import com.android.settings.connecteddevice.AvailableMediaDeviceGroupController;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
@@ -60,6 +61,14 @@
     }
 
     @Test
+    public void createAvailableMediaDeviceGroupController_returnsNull() {
+        assertThat(
+                        mFeatureProvider.createAvailableMediaDeviceGroupController(
+                                mContext, /* fragment= */ null, /* lifecycle= */ null))
+                .isInstanceOf(AvailableMediaDeviceGroupController.class);
+    }
+
+    @Test
     public void isAudioSharingFilterMatched_returnsFalse() {
         assertThat(mFeatureProvider.isAudioSharingFilterMatched(mCachedDevice, mLocalBtManager))
                 .isFalse();
diff --git a/tests/robotests/src/com/android/settings/development/ForcePeakRefreshRatePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/ForcePeakRefreshRatePreferenceControllerTest.java
index 314120a..c7c76b1 100644
--- a/tests/robotests/src/com/android/settings/development/ForcePeakRefreshRatePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/ForcePeakRefreshRatePreferenceControllerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.development;
 
+import static android.hardware.display.DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED;
+
 import static com.android.internal.display.RefreshRateSettingsUtils.DEFAULT_REFRESH_RATE;
 import static com.android.settings.development.ForcePeakRefreshRatePreferenceController.NO_CONFIG;
 
@@ -24,15 +26,18 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.content.Context;
+import android.hardware.display.DisplayManager;
 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.provider.Settings;
+import android.testing.TestableContext;
+import android.view.Display;
 
 import androidx.preference.PreferenceScreen;
 import androidx.preference.SwitchPreference;
+import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.server.display.feature.flags.Flags;
 
@@ -43,7 +48,6 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 
 @RunWith(RobolectricTestRunner.class)
@@ -53,17 +57,51 @@
     private SwitchPreference mPreference;
     @Mock
     private PreferenceScreen mScreen;
+    @Mock
+    private DisplayManager mDisplayManagerMock;
+    @Mock
+    private Display mDisplayMock;
+    @Mock
+    private Display mDisplayMock2;
 
-    private Context mContext;
     private ForcePeakRefreshRatePreferenceController mController;
 
     @Rule
     public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+    @Rule
+    public final TestableContext mContext = new TestableContext(
+            InstrumentationRegistry.getInstrumentation().getContext());
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
+        mContext.addMockSystemService(DisplayManager.class, mDisplayManagerMock);
+
+        Display.Mode[] modes = new Display.Mode[]{
+                new Display.Mode(/* modeId= */ 0, /* width= */ 800, /* height= */ 600,
+                        /* refreshRate= */ 60),
+                new Display.Mode(/* modeId= */ 0, /* width= */ 800, /* height= */ 600,
+                        /* refreshRate= */ 120),
+                new Display.Mode(/* modeId= */ 0, /* width= */ 800, /* height= */ 600,
+                        /* refreshRate= */ 90)
+        };
+        when(mDisplayManagerMock.getDisplay(Display.DEFAULT_DISPLAY)).thenReturn(mDisplayMock);
+        when(mDisplayMock.getSupportedModes()).thenReturn(modes);
+
+        Display.Mode[] modes2 = new Display.Mode[]{
+                new Display.Mode(/* modeId= */ 0, /* width= */ 800, /* height= */ 600,
+                        /* refreshRate= */ 70),
+                new Display.Mode(/* modeId= */ 0, /* width= */ 800, /* height= */ 600,
+                        /* refreshRate= */ 130),
+                new Display.Mode(/* modeId= */ 0, /* width= */ 800, /* height= */ 600,
+                        /* refreshRate= */ 80)
+        };
+        when(mDisplayManagerMock.getDisplay(Display.DEFAULT_DISPLAY + 1)).thenReturn(mDisplayMock2);
+        when(mDisplayMock2.getSupportedModes()).thenReturn(modes2);
+
+        when(mDisplayManagerMock.getDisplays(DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED))
+                .thenReturn(new Display[]{ mDisplayMock, mDisplayMock2 });
+
         mController = new ForcePeakRefreshRatePreferenceController(mContext);
         when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
         when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
@@ -153,4 +191,16 @@
         assertThat(mPreference.isChecked()).isFalse();
         assertThat(mPreference.isEnabled()).isFalse();
     }
+
+    @Test
+    @RequiresFlagsDisabled(Flags.FLAG_BACK_UP_SMOOTH_DISPLAY_AND_FORCE_PEAK_REFRESH_RATE)
+    public void peakRefreshRate_highestOfDefaultDisplay_featureFlagOff() {
+        assertThat(mController.mPeakRefreshRate).isEqualTo(120);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_BACK_UP_SMOOTH_DISPLAY_AND_FORCE_PEAK_REFRESH_RATE)
+    public void peakRefreshRate_highestOfAllDisplays_featureFlagOn() {
+        assertThat(mController.mPeakRefreshRate).isEqualTo(130);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/display/PeakRefreshRatePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/PeakRefreshRatePreferenceControllerTest.java
index cb0963b..f8e91bd 100644
--- a/tests/robotests/src/com/android/settings/display/PeakRefreshRatePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/PeakRefreshRatePreferenceControllerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.display;
 
+import static android.hardware.display.DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED;
+
 import static com.android.internal.display.RefreshRateSettingsUtils.DEFAULT_REFRESH_RATE;
 import static com.android.settings.core.BasePreferenceController.AVAILABLE;
 import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
@@ -24,14 +26,17 @@
 
 import static org.mockito.Mockito.when;
 
-import android.content.Context;
+import android.hardware.display.DisplayManager;
 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.provider.Settings;
+import android.testing.TestableContext;
+import android.view.Display;
 
 import androidx.preference.SwitchPreference;
+import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.server.display.feature.flags.Flags;
 
@@ -48,21 +53,55 @@
 @RunWith(RobolectricTestRunner.class)
 public class PeakRefreshRatePreferenceControllerTest {
 
-    private Context mContext;
     private PeakRefreshRatePreferenceController mController;
     private SwitchPreference mPreference;
 
     @Mock
     private PeakRefreshRatePreferenceController.DeviceConfigDisplaySettings
             mDeviceConfigDisplaySettings;
+    @Mock
+    private DisplayManager mDisplayManagerMock;
+    @Mock
+    private Display mDisplayMock;
+    @Mock
+    private Display mDisplayMock2;
 
     @Rule
     public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+    @Rule
+    public final TestableContext mContext = new TestableContext(
+            InstrumentationRegistry.getInstrumentation().getContext());
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
+        mContext.addMockSystemService(DisplayManager.class, mDisplayManagerMock);
+
+        Display.Mode[] modes = new Display.Mode[]{
+                new Display.Mode(/* modeId= */ 0, /* width= */ 800, /* height= */ 600,
+                        /* refreshRate= */ 60),
+                new Display.Mode(/* modeId= */ 0, /* width= */ 800, /* height= */ 600,
+                        /* refreshRate= */ 120),
+                new Display.Mode(/* modeId= */ 0, /* width= */ 800, /* height= */ 600,
+                        /* refreshRate= */ 90)
+        };
+        when(mDisplayManagerMock.getDisplay(Display.DEFAULT_DISPLAY)).thenReturn(mDisplayMock);
+        when(mDisplayMock.getSupportedModes()).thenReturn(modes);
+
+        Display.Mode[] modes2 = new Display.Mode[]{
+                new Display.Mode(/* modeId= */ 0, /* width= */ 800, /* height= */ 600,
+                        /* refreshRate= */ 70),
+                new Display.Mode(/* modeId= */ 0, /* width= */ 800, /* height= */ 600,
+                        /* refreshRate= */ 130),
+                new Display.Mode(/* modeId= */ 0, /* width= */ 800, /* height= */ 600,
+                        /* refreshRate= */ 80)
+        };
+        when(mDisplayManagerMock.getDisplay(Display.DEFAULT_DISPLAY + 1)).thenReturn(mDisplayMock2);
+        when(mDisplayMock2.getSupportedModes()).thenReturn(modes2);
+
+        when(mDisplayManagerMock.getDisplays(DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED))
+                .thenReturn(new Display[]{ mDisplayMock, mDisplayMock2 });
+
         mController = new PeakRefreshRatePreferenceController(mContext, "key");
         mController.injectDeviceConfigDisplaySettings(mDeviceConfigDisplaySettings);
         mPreference = new SwitchPreference(RuntimeEnvironment.application);
@@ -152,4 +191,16 @@
 
         assertThat(mController.isChecked()).isFalse();
     }
+
+    @Test
+    @RequiresFlagsDisabled(Flags.FLAG_BACK_UP_SMOOTH_DISPLAY_AND_FORCE_PEAK_REFRESH_RATE)
+    public void peakRefreshRate_highestOfDefaultDisplay_featureFlagOff() {
+        assertThat(mController.mPeakRefreshRate).isEqualTo(120);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_BACK_UP_SMOOTH_DISPLAY_AND_FORCE_PEAK_REFRESH_RATE)
+    public void peakRefreshRate_highestOfAllDisplays_featureFlagOn() {
+        assertThat(mController.mPeakRefreshRate).isEqualTo(130);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/network/SubscriptionUtilRoboTest.java b/tests/robotests/src/com/android/settings/network/SubscriptionUtilRoboTest.java
new file mode 100644
index 0000000..2595510
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/SubscriptionUtilRoboTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+import static org.mockito.ArgumentMatchers.any;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkCapabilities;
+import android.telephony.SubscriptionManager;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.shadows.ShadowSubscriptionManager;
+
+@RunWith(RobolectricTestRunner.class)
+public class SubscriptionUtilRoboTest {
+    private static final int SUBID_1 = 1;
+    private static final int SUBID_2 = 2;
+
+    private Context mContext;
+    private NetworkCapabilities mNetworkCapabilities;
+    private ShadowSubscriptionManager mShadowSubscriptionManager;
+
+    @Mock
+    private ConnectivityManager mConnectivityManager;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        mShadowSubscriptionManager = shadowOf(mContext.getSystemService(SubscriptionManager.class));
+        when(mContext.getSystemService(ConnectivityManager.class)).thenReturn(mConnectivityManager);
+    }
+
+    @Test
+    public void isConnectedToWifiOrDifferentSubId_hasDataOnSubId2_returnTrue() {
+        addNetworkTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+        mShadowSubscriptionManager.setActiveDataSubscriptionId(SUBID_2);
+
+        assertTrue(SubscriptionUtil.isConnectedToWifiOrDifferentSubId(mContext, SUBID_1));
+    }
+
+    @Test
+    public void isConnectedToWifiOrDifferentSubId_hasDataOnSubId1_returnFalse() {
+        addNetworkTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+        mShadowSubscriptionManager.setActiveDataSubscriptionId(SUBID_1);
+
+        assertFalse(SubscriptionUtil.isConnectedToWifiOrDifferentSubId(mContext, SUBID_1));
+    }
+
+    private void addNetworkTransportType(int networkType) {
+        mNetworkCapabilities =
+                new NetworkCapabilities.Builder().addTransportType(networkType).build();
+        when(mConnectivityManager.getNetworkCapabilities(any())).thenReturn(mNetworkCapabilities);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAudioManager.java b/tests/robotests/testutils/com/android/settings/testutils/shadow/ShadowAudioManager.java
similarity index 92%
rename from tests/robotests/src/com/android/settings/testutils/shadow/ShadowAudioManager.java
rename to tests/robotests/testutils/com/android/settings/testutils/shadow/ShadowAudioManager.java
index 9c06665..b465a41 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAudioManager.java
+++ b/tests/robotests/testutils/com/android/settings/testutils/shadow/ShadowAudioManager.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -38,6 +38,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+/** Robolectric shadow for the AudioManager. */
 @Implements(value = AudioManager.class)
 public class ShadowAudioManager extends org.robolectric.shadows.ShadowAudioManager {
     private int mRingerMode;
@@ -58,11 +59,13 @@
         mRingerMode = mode;
     }
 
+    /** Register audio device callback. */
     @Implementation
     public void registerAudioDeviceCallback(AudioDeviceCallback callback, Handler handler) {
         mDeviceCallbacks.add(callback);
     }
 
+    /** Unregister audio device callback. */
     @Implementation
     public void unregisterAudioDeviceCallback(AudioDeviceCallback callback) {
         if (mDeviceCallbacks.contains(callback)) {
@@ -79,10 +82,12 @@
         return mMusicActiveRemotely;
     }
 
+    /** Set output device. */
     public void setOutputDevice(int deviceCodes) {
         mDeviceCodes = deviceCodes;
     }
 
+    /** Get devices for stream. */
     @Implementation
     public int getDevicesForStream(int streamType) {
         switch (streamType) {
diff --git a/tests/spa_unit/src/com/android/settings/development/SensitiveContentProtectionPreferenceControllerTest.kt b/tests/spa_unit/src/com/android/settings/development/SensitiveContentProtectionPreferenceControllerTest.kt
index 18acbba..023572b 100644
--- a/tests/spa_unit/src/com/android/settings/development/SensitiveContentProtectionPreferenceControllerTest.kt
+++ b/tests/spa_unit/src/com/android/settings/development/SensitiveContentProtectionPreferenceControllerTest.kt
@@ -22,6 +22,7 @@
 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 android.view.flags.Flags.FLAG_SENSITIVE_CONTENT_APP_PROTECTION
 import androidx.preference.Preference
 import androidx.preference.PreferenceScreen
 import androidx.preference.SwitchPreference
@@ -132,7 +133,8 @@
     @Test
     @RequiresFlagsDisabled(
         FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION,
-        FLAG_SCREENSHARE_NOTIFICATION_HIDING)
+        FLAG_SCREENSHARE_NOTIFICATION_HIDING,
+        FLAG_SENSITIVE_CONTENT_APP_PROTECTION)
     fun isAvailable_flagsDisabled_returnFalse() {
         assertFalse(controller.isAvailable)
     }
@@ -148,4 +150,10 @@
     fun isAvailable_screenshareNotificationHidingEnabled_returnTrue() {
         assertTrue(controller.isAvailable)
     }
-}
\ No newline at end of file
+
+    @Test
+    @RequiresFlagsEnabled(FLAG_SENSITIVE_CONTENT_APP_PROTECTION)
+    fun isAvailable_screenshareSensitiveContentHidingEnabled_returnTrue() {
+        assertTrue(controller.isAvailable)
+    }
+}
diff --git a/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java b/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java
index 587e734..3b9ac9d 100644
--- a/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java
+++ b/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java
@@ -18,9 +18,13 @@
 
 import static com.android.settings.network.SubscriptionUtil.KEY_UNIQUE_SUBSCRIPTION_DISPLAYNAME;
 import static com.android.settings.network.SubscriptionUtil.SUB_ID;
+
 import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
@@ -30,6 +34,8 @@
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.content.res.Resources;
+import android.net.ConnectivityManager;
+import android.net.NetworkCapabilities;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -61,13 +67,15 @@
     private static final CharSequence CARRIER_2 = "carrier2";
 
     private Context mContext;
+    private NetworkCapabilities mNetworkCapabilities;
+
     @Mock
     private SubscriptionManager mSubMgr;
     @Mock
     private TelephonyManager mTelMgr;
     @Mock
     private Resources mResources;
-
+    @Mock private ConnectivityManager mConnectivityManager;
 
     @Before
     public void setUp() {
@@ -75,6 +83,7 @@
         mContext = spy(ApplicationProvider.getApplicationContext());
         when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubMgr);
         when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelMgr);
+        when(mContext.getSystemService(ConnectivityManager.class)).thenReturn(mConnectivityManager);
         when(mTelMgr.getUiccSlotsInfo()).thenReturn(null);
     }
 
@@ -588,4 +597,24 @@
 
         assertThat(SubscriptionUtil.isValidCachedDisplayName(cacheString, originalName)).isFalse();
     }
+
+    @Test
+    public void isConnectedToWifiOrDifferentSubId_hasWiFi_returnTrue() {
+        addNetworkTransportType(NetworkCapabilities.TRANSPORT_WIFI);
+
+        assertTrue(SubscriptionUtil.isConnectedToWifiOrDifferentSubId(mContext, SUBID_1));
+    }
+
+    @Test
+    public void isConnectedToWifiOrDifferentSubId_noData_and_noWiFi_returnFalse() {
+        addNetworkTransportType(NetworkCapabilities.TRANSPORT_BLUETOOTH);
+
+        assertFalse(SubscriptionUtil.isConnectedToWifiOrDifferentSubId(mContext, SUBID_1));
+    }
+
+    private void addNetworkTransportType(int networkType) {
+        mNetworkCapabilities =
+                new NetworkCapabilities.Builder().addTransportType(networkType).build();
+        when(mConnectivityManager.getNetworkCapabilities(any())).thenReturn(mNetworkCapabilities);
+    }
 }