Merge "Flash Notifications color dialog crashs if configuration changes" into main
diff --git a/res/layout/dialog_custom_body_audio_sharing.xml b/res/layout/dialog_custom_body_audio_sharing.xml
index 528bfbb..ba7f643 100644
--- a/res/layout/dialog_custom_body_audio_sharing.xml
+++ b/res/layout/dialog_custom_body_audio_sharing.xml
@@ -44,6 +44,7 @@
             android:layout_height="wrap_content"
             android:layout_gravity="center"
             android:contentDescription="@null"
+            android:paddingBottom="24dp"
             android:visibility="gone" />
 
         <androidx.recyclerview.widget.RecyclerView
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1d60218..6c018c2 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -937,7 +937,7 @@
     <!-- Message showing that multiple fingerprints, face, and the current watch is set up. Shown for a menu item that launches fingerprint, face,  and active unlock settings or enrollment. [CHAR LIMIT=80]-->
     <string name="security_settings_fingerprint_multiple_face_watch_preference_summary">Face, fingerprints, and <xliff:g id="watch" example="Dani's Watch">%s</xliff:g> added</string>
     <!-- Description for mandatory biometrics prompt-->
-    <string name="mandatory_biometrics_prompt_description">This is needed since Identity Check is on</string>
+    <string name="mandatory_biometrics_prompt_description">Identity Check is on</string>
     <!-- RemoteAuth unlock enrollment and settings --><skip />
     <!-- Title shown for menu item that launches watch unlock settings. [CHAR LIMIT=40] -->
     <string name ="security_settings_remoteauth_preference_title">Remote Authenticator Unlock</string>
diff --git a/res/xml/mobile_network_settings.xml b/res/xml/mobile_network_settings.xml
index 539c145..eb80ac8 100644
--- a/res/xml/mobile_network_settings.xml
+++ b/res/xml/mobile_network_settings.xml
@@ -152,6 +152,7 @@
             android:summary="@string/contact_discovery_opt_in_summary"
             settings:controller="com.android.settings.network.telephony.ContactDiscoveryPreferenceController"/>
 
+        <!-- Settings search is handled by PreferredNetworkModeSearchItem. -->
         <ListPreference
             android:key="preferred_network_mode_key"
             android:title="@string/preferred_network_mode_title"
@@ -159,8 +160,10 @@
             android:entries="@array/preferred_network_mode_choices"
             android:entryValues="@array/preferred_network_mode_values"
             android:dialogTitle="@string/preferred_network_mode_dialogtitle"
+            settings:searchable="false"
             settings:controller="com.android.settings.network.telephony.PreferredNetworkModePreferenceController"/>
 
+        <!-- Settings search is handled by EnabledNetworkModeSearchItem. -->
         <ListPreference
             android:key="enabled_networks_key"
             android:title="@string/preferred_network_mode_title"
@@ -168,6 +171,7 @@
             android:entries="@array/enabled_networks_choices"
             android:entryValues="@array/enabled_networks_values"
             android:dialogTitle="@string/preferred_network_mode_dialogtitle"
+            settings:searchable="false"
             settings:controller="com.android.settings.network.telephony.EnabledNetworkModePreferenceController"/>
 
         <Preference
diff --git a/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragment.java b/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragment.java
index bdf7857..d04b34a 100644
--- a/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragment.java
@@ -20,6 +20,7 @@
 import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE;
 import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
 import static android.provider.Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED;
+import static android.provider.Settings.Secure.ACCESSIBILITY_GESTURE_TARGETS;
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED;
 import static android.provider.Settings.Secure.ACCESSIBILITY_QS_TARGETS;
 import static android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
@@ -93,7 +94,8 @@
             Settings.Secure.getUriFor(ACCESSIBILITY_BUTTON_MODE);
     private static final Uri BUTTON_SHORTCUT_SETTING =
             Settings.Secure.getUriFor(ACCESSIBILITY_BUTTON_TARGETS);
-
+    private static final Uri GESTURE_SHORTCUT_SETTING =
+            Settings.Secure.getUriFor(ACCESSIBILITY_GESTURE_TARGETS);
     private static final Uri TRIPLE_TAP_SHORTCUT_SETTING =
             Settings.Secure.getUriFor(ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED);
     private static final Uri TWO_FINGERS_DOUBLE_TAP_SHORTCUT_SETTING =
@@ -107,6 +109,7 @@
             VOLUME_KEYS_SHORTCUT_SETTING,
             BUTTON_SHORTCUT_MODE_SETTING,
             BUTTON_SHORTCUT_SETTING,
+            GESTURE_SHORTCUT_SETTING,
             TRIPLE_TAP_SHORTCUT_SETTING,
             TWO_FINGERS_DOUBLE_TAP_SHORTCUT_SETTING,
             QUICK_SETTINGS_SHORTCUT_SETTING,
@@ -173,6 +176,8 @@
                 } else if (BUTTON_SHORTCUT_MODE_SETTING.equals(uri)
                         || BUTTON_SHORTCUT_SETTING.equals(uri)) {
                     refreshSoftwareShortcutControllers();
+                } else if (GESTURE_SHORTCUT_SETTING.equals(uri)) {
+                    refreshPreferenceController(GestureShortcutOptionController.class);
                 } else if (TRIPLE_TAP_SHORTCUT_SETTING.equals(uri)) {
                     refreshPreferenceController(TripleTapShortcutOptionController.class);
                 } else if (TWO_FINGERS_DOUBLE_TAP_SHORTCUT_SETTING.equals(uri)) {
diff --git a/src/com/android/settings/accessibility/shortcuts/FloatingButtonShortcutOptionController.java b/src/com/android/settings/accessibility/shortcuts/FloatingButtonShortcutOptionController.java
index 2242cab..20ff12d 100644
--- a/src/com/android/settings/accessibility/shortcuts/FloatingButtonShortcutOptionController.java
+++ b/src/com/android/settings/accessibility/shortcuts/FloatingButtonShortcutOptionController.java
@@ -50,7 +50,14 @@
 
     @Override
     protected boolean isShortcutAvailable() {
-        return AccessibilityUtil.isFloatingMenuEnabled(mContext);
+        if (android.provider.Flags.a11yStandaloneGestureEnabled()) {
+            // FAB should be available when in gesture navigation mode,
+            // or if we're in the FAB button mode while in navbar navigation mode.
+            return AccessibilityUtil.isGestureNavigateEnabled(mContext)
+                    || AccessibilityUtil.isFloatingMenuEnabled(mContext);
+        } else {
+            return AccessibilityUtil.isFloatingMenuEnabled(mContext);
+        }
     }
 
     @Nullable
diff --git a/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionController.java b/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionController.java
index e65aab9..3c19b5d 100644
--- a/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionController.java
+++ b/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionController.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.accessibility.shortcuts;
 
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE;
+
 import android.content.Context;
 import android.text.SpannableStringBuilder;
 
@@ -52,10 +54,21 @@
     }
 
     @Override
+    protected int getShortcutType() {
+        return android.provider.Flags.a11yStandaloneGestureEnabled()
+                ? GESTURE : super.getShortcutType();
+    }
+
+    @Override
     protected boolean isShortcutAvailable() {
-        return !isInSetupWizard()
-                && !AccessibilityUtil.isFloatingMenuEnabled(mContext)
-                && AccessibilityUtil.isGestureNavigateEnabled(mContext);
+        if (android.provider.Flags.a11yStandaloneGestureEnabled()) {
+            return !isInSetupWizard()
+                    && AccessibilityUtil.isGestureNavigateEnabled(mContext);
+        } else {
+            return !isInSetupWizard()
+                    && AccessibilityUtil.isGestureNavigateEnabled(mContext)
+                    && !AccessibilityUtil.isFloatingMenuEnabled(mContext);
+        }
     }
 
     @Override
@@ -68,9 +81,8 @@
 
         final SpannableStringBuilder sb = new SpannableStringBuilder();
         sb.append(instruction);
-        if (!isInSetupWizard()) {
-            sb.append("\n\n");
-            sb.append(getCustomizeAccessibilityButtonLink());
+        if (!isInSetupWizard() && !android.provider.Flags.a11yStandaloneGestureEnabled()) {
+            sb.append("\n\n").append(getCustomizeAccessibilityButtonLink());
         }
 
         return sb;
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
index 65d9366..526ae8f6 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
@@ -42,6 +42,8 @@
 import android.os.Handler;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
 import android.text.InputFilter;
 import android.text.Spanned;
 import android.text.TextUtils;
@@ -109,6 +111,9 @@
     private static final int RESULT_FINISHED = BiometricEnrollBase.RESULT_FINISHED;
     private static final int RESULT_SKIP = BiometricEnrollBase.RESULT_SKIP;
     private static final int RESULT_TIMEOUT = BiometricEnrollBase.RESULT_TIMEOUT;
+    @VisibleForTesting
+    static final VibrationEffect SUCCESS_VIBRATION_EFFECT =
+            VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
 
     @Override
     public Intent getIntent() {
@@ -285,6 +290,7 @@
         private FingerprintAuthenticateSidecar mAuthenticateSidecar;
         private FingerprintRemoveSidecar mRemovalSidecar;
         private HashMap<Integer, String> mFingerprintsRenaming;
+        private Vibrator mVibrator;
 
         @Nullable
         private UdfpsEnrollCalibrator mCalibrator;
@@ -367,8 +373,8 @@
                         break;
                     case MSG_FINGER_AUTH_HELP: {
                         // Not used
+                        break;
                     }
-                    break;
                 }
             }
         };
@@ -511,6 +517,7 @@
                     addFirstFingerprint(null);
                 }
             }
+            mVibrator = getContext().getSystemService(Vibrator.class);
             final PreferenceScreen root = getPreferenceScreen();
             root.removeAll();
             addPreferencesFromResource(getPreferenceScreenResId());
@@ -1095,6 +1102,7 @@
         }
 
         private void highlightFingerprintItem(int fpId) {
+            mVibrator.vibrate(SUCCESS_VIBRATION_EFFECT);
             String prefName = genKey(fpId);
             FingerprintPreference fpref = (FingerprintPreference) findPreference(prefName);
             final Drawable highlight = getHighlightDrawable();
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
index 2b74684..0897a43 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
@@ -89,7 +89,7 @@
     private LocalBluetoothManager mManager;
     private LocalBluetoothProfileManager mProfileManager;
     private CachedBluetoothDevice mCachedDevice;
-    private List<CachedBluetoothDevice> mAllOfCachedDevices;
+    private Set<CachedBluetoothDevice> mCachedDeviceGroup;
     private Map<String, List<CachedBluetoothDevice>> mProfileDeviceMap =
             new HashMap<String, List<CachedBluetoothDevice>>();
     private boolean mIsLeContactSharingEnabled = false;
@@ -105,7 +105,7 @@
         mManager = manager;
         mProfileManager = mManager.getProfileManager();
         mCachedDevice = device;
-        mAllOfCachedDevices = Utils.getAllOfCachedBluetoothDevices(mManager, mCachedDevice);
+        mCachedDeviceGroup = Utils.findAllCachedBluetoothDevicesByGroupId(mManager, mCachedDevice);
     }
 
     @Override
@@ -310,10 +310,10 @@
     private List<LocalBluetoothProfile> getProfiles() {
         List<LocalBluetoothProfile> result = new ArrayList<>();
         mProfileDeviceMap.clear();
-        if (mAllOfCachedDevices == null || mAllOfCachedDevices.isEmpty()) {
+        if (mCachedDeviceGroup == null || mCachedDeviceGroup.isEmpty()) {
             return result;
         }
-        for (CachedBluetoothDevice cachedItem : mAllOfCachedDevices) {
+        for (CachedBluetoothDevice cachedItem : mCachedDeviceGroup) {
             List<LocalBluetoothProfile> tmpResult = cachedItem.getUiAccessibleProfiles();
             for (LocalBluetoothProfile profile : tmpResult) {
                 if (mProfileDeviceMap.containsKey(profile.toString())) {
@@ -514,7 +514,7 @@
 
     @Override
     public void onPause() {
-        for (CachedBluetoothDevice item : mAllOfCachedDevices) {
+        for (CachedBluetoothDevice item : mCachedDeviceGroup) {
             item.unregisterCallback(this);
         }
         mProfileManager.removeServiceListener(this);
@@ -523,7 +523,7 @@
     @Override
     public void onResume() {
         updateLeAudioConfig();
-        for (CachedBluetoothDevice item : mAllOfCachedDevices) {
+        for (CachedBluetoothDevice item : mCachedDeviceGroup) {
             item.registerCallback(this);
         }
         mProfileManager.addServiceListener(this);
@@ -545,11 +545,11 @@
 
     @Override
     public void onDeviceAttributesChanged() {
-        for (CachedBluetoothDevice item : mAllOfCachedDevices) {
+        for (CachedBluetoothDevice item : mCachedDeviceGroup) {
             item.unregisterCallback(this);
         }
-        mAllOfCachedDevices = Utils.getAllOfCachedBluetoothDevices(mManager, mCachedDevice);
-        for (CachedBluetoothDevice item : mAllOfCachedDevices) {
+        mCachedDeviceGroup = Utils.findAllCachedBluetoothDevicesByGroupId(mManager, mCachedDevice);
+        for (CachedBluetoothDevice item : mCachedDeviceGroup) {
             item.registerCallback(this);
         }
 
diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
index ac0c63b..209c900 100644
--- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
@@ -46,6 +46,7 @@
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.widget.GearPreference;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.utils.ThreadUtils;
 
@@ -55,6 +56,7 @@
 import java.util.Set;
 import java.util.concurrent.RejectedExecutionException;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
 
 /**
  * BluetoothDevicePreference is the preference type used to display each remote
@@ -76,7 +78,10 @@
     }
 
     private final CachedBluetoothDevice mCachedDevice;
+    private Set<CachedBluetoothDevice> mCachedDeviceGroup;
+
     private final UserManager mUserManager;
+    private final LocalBluetoothManager mLocalBtManager;
 
     private Set<BluetoothDevice> mBluetoothDevices;
     @VisibleForTesting
@@ -113,6 +118,21 @@
         @Override
         public void onDeviceAttributesChanged() {
             onPreferenceAttributesChanged();
+            Set<CachedBluetoothDevice> newCachedDeviceGroup = new HashSet<>(
+                    Utils.findAllCachedBluetoothDevicesByGroupId(mLocalBtManager, mCachedDevice));
+            if (!mCachedDeviceGroup.equals(newCachedDeviceGroup)) {
+                for (CachedBluetoothDevice cachedBluetoothDevice : mCachedDeviceGroup) {
+                    cachedBluetoothDevice.unregisterCallback(this);
+                }
+                unregisterMetadataChangedListener();
+
+                mCachedDeviceGroup = newCachedDeviceGroup;
+
+                for (CachedBluetoothDevice cachedBluetoothDevice : mCachedDeviceGroup) {
+                    cachedBluetoothDevice.registerCallback(getContext().getMainExecutor(), this);
+                }
+                registerMetadataChangedListener();
+            }
         }
     }
 
@@ -121,6 +141,7 @@
         super(context, null);
         mResources = getContext().getResources();
         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+        mLocalBtManager = Utils.getLocalBluetoothManager(context);
         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
         mShowDevicesWithoutNames = showDeviceWithoutNames;
 
@@ -131,6 +152,8 @@
         }
 
         mCachedDevice = cachedDevice;
+        mCachedDeviceGroup = new HashSet<>(
+                Utils.findAllCachedBluetoothDevicesByGroupId(mLocalBtManager, mCachedDevice));
         mCallback = new BluetoothDevicePreferenceCallback();
         mId = sNextId.getAndIncrement();
         mType = type;
@@ -164,7 +187,9 @@
     protected void onPrepareForRemoval() {
         super.onPrepareForRemoval();
         if (!mIsCallbackRemoved) {
-            mCachedDevice.unregisterCallback(mCallback);
+            for (CachedBluetoothDevice cachedBluetoothDevice : mCachedDeviceGroup) {
+                cachedBluetoothDevice.unregisterCallback(mCallback);
+            }
             unregisterMetadataChangedListener();
             mIsCallbackRemoved = true;
         }
@@ -178,7 +203,9 @@
     public void onAttached() {
         super.onAttached();
         if (mIsCallbackRemoved) {
-            mCachedDevice.registerCallback(mCallback);
+            for (CachedBluetoothDevice cachedBluetoothDevice : mCachedDeviceGroup) {
+                cachedBluetoothDevice.registerCallback(getContext().getMainExecutor(), mCallback);
+            }
             registerMetadataChangedListener();
             mIsCallbackRemoved = false;
         }
@@ -189,7 +216,9 @@
     public void onDetached() {
         super.onDetached();
         if (!mIsCallbackRemoved) {
-            mCachedDevice.unregisterCallback(mCallback);
+            for (CachedBluetoothDevice cachedBluetoothDevice : mCachedDeviceGroup) {
+                cachedBluetoothDevice.unregisterCallback(mCallback);
+            }
             unregisterMetadataChangedListener();
             mIsCallbackRemoved = true;
         }
@@ -200,16 +229,11 @@
             Log.d(TAG, "No mBluetoothAdapter");
             return;
         }
-        if (mBluetoothDevices == null) {
-            mBluetoothDevices = new HashSet<>();
-        }
-        mBluetoothDevices.clear();
-        if (mCachedDevice.getDevice() != null) {
-            mBluetoothDevices.add(mCachedDevice.getDevice());
-        }
-        for (CachedBluetoothDevice cbd : mCachedDevice.getMemberDevice()) {
-            mBluetoothDevices.add(cbd.getDevice());
-        }
+
+        mBluetoothDevices = mCachedDeviceGroup.stream()
+                .map(CachedBluetoothDevice::getDevice)
+                .collect(Collectors.toCollection(HashSet::new));
+
         if (mBluetoothDevices.isEmpty()) {
             Log.d(TAG, "No BT device to register.");
             return;
diff --git a/src/com/android/settings/bluetooth/LeAudioBluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/LeAudioBluetoothDetailsHeaderController.java
index 4be4d63..a5e9cde 100644
--- a/src/com/android/settings/bluetooth/LeAudioBluetoothDetailsHeaderController.java
+++ b/src/com/android/settings/bluetooth/LeAudioBluetoothDetailsHeaderController.java
@@ -47,7 +47,7 @@
 import com.android.settingslib.core.lifecycle.events.OnStop;
 import com.android.settingslib.widget.LayoutPreference;
 
-import java.util.List;
+import java.util.Set;
 
 /**
  * This class adds a header with device name and status (connected/disconnected, etc.).
@@ -90,7 +90,7 @@
     LayoutPreference mLayoutPreference;
     LocalBluetoothManager mManager;
     private CachedBluetoothDevice mCachedDevice;
-    private List<CachedBluetoothDevice> mAllOfCachedDevices;
+    private Set<CachedBluetoothDevice> mCachedDeviceGroup;
     @VisibleForTesting
     Handler mHandler = new Handler(Looper.getMainLooper());
     @VisibleForTesting
@@ -128,7 +128,7 @@
             return;
         }
         mIsRegisterCallback = true;
-        for (CachedBluetoothDevice item : mAllOfCachedDevices) {
+        for (CachedBluetoothDevice item : mCachedDeviceGroup) {
             item.registerCallback(this);
         }
         refresh();
@@ -139,7 +139,7 @@
         if (!mIsRegisterCallback) {
             return;
         }
-        for (CachedBluetoothDevice item : mAllOfCachedDevices) {
+        for (CachedBluetoothDevice item : mCachedDeviceGroup) {
             item.unregisterCallback(this);
         }
 
@@ -155,7 +155,7 @@
         mCachedDevice = cachedBluetoothDevice;
         mManager = bluetoothManager;
         mProfileManager = bluetoothManager.getProfileManager();
-        mAllOfCachedDevices = Utils.getAllOfCachedBluetoothDevices(mManager, mCachedDevice);
+        mCachedDeviceGroup = Utils.findAllCachedBluetoothDevicesByGroupId(mManager, mCachedDevice);
     }
 
     @VisibleForTesting
@@ -230,7 +230,7 @@
         // Init the battery layouts.
         hideAllOfBatteryLayouts();
         LeAudioProfile leAudioProfile = mProfileManager.getLeAudioProfile();
-        if (mAllOfCachedDevices.isEmpty()) {
+        if (mCachedDeviceGroup.isEmpty()) {
             Log.e(TAG, "There is no LeAudioProfile.");
             return;
         }
@@ -244,7 +244,7 @@
             return;
         }
 
-        for (CachedBluetoothDevice cachedDevice : mAllOfCachedDevices) {
+        for (CachedBluetoothDevice cachedDevice : mCachedDeviceGroup) {
             int deviceId = leAudioProfile.getAudioLocation(cachedDevice.getDevice());
             Log.d(TAG, "LeAudioDevices:" + cachedDevice.getDevice().getAnonymizedAddress()
                     + ", deviceId:" + deviceId);
@@ -300,15 +300,15 @@
 
     @Override
     public void onDeviceAttributesChanged() {
-        for (CachedBluetoothDevice item : mAllOfCachedDevices) {
+        for (CachedBluetoothDevice item : mCachedDeviceGroup) {
             item.unregisterCallback(this);
         }
-        mAllOfCachedDevices = Utils.getAllOfCachedBluetoothDevices(mManager, mCachedDevice);
-        for (CachedBluetoothDevice item : mAllOfCachedDevices) {
+        mCachedDeviceGroup = Utils.findAllCachedBluetoothDevicesByGroupId(mManager, mCachedDevice);
+        for (CachedBluetoothDevice item : mCachedDeviceGroup) {
             item.registerCallback(this);
         }
 
-        if (!mAllOfCachedDevices.isEmpty()) {
+        if (!mCachedDeviceGroup.isEmpty()) {
             refresh();
         }
     }
diff --git a/src/com/android/settings/bluetooth/Utils.java b/src/com/android/settings/bluetooth/Utils.java
index f6288b2..b1d9de7 100644
--- a/src/com/android/settings/bluetooth/Utils.java
+++ b/src/com/android/settings/bluetooth/Utils.java
@@ -48,8 +48,9 @@
 
 import com.google.common.base.Supplier;
 
-import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.FutureTask;
 
@@ -239,12 +240,12 @@
      * @param cachedBluetoothDevice The main cachedBluetoothDevice.
      * @return all cachedBluetoothDevices with the same groupId.
      */
-    public static List<CachedBluetoothDevice> getAllOfCachedBluetoothDevices(
+    public static Set<CachedBluetoothDevice> findAllCachedBluetoothDevicesByGroupId(
             LocalBluetoothManager localBtMgr,
             CachedBluetoothDevice cachedBluetoothDevice) {
-        List<CachedBluetoothDevice> cachedBluetoothDevices = new ArrayList<>();
+        Set<CachedBluetoothDevice> cachedBluetoothDevices = new HashSet<>();
         if (cachedBluetoothDevice == null) {
-            Log.e(TAG, "getAllOfCachedBluetoothDevices: no cachedBluetoothDevice");
+            Log.e(TAG, "findAllCachedBluetoothDevicesByGroupId: no cachedBluetoothDevice");
             return cachedBluetoothDevices;
         }
         int deviceGroupId = cachedBluetoothDevice.getGroupId();
@@ -254,7 +255,7 @@
         }
 
         if (localBtMgr == null) {
-            Log.e(TAG, "getAllOfCachedBluetoothDevices: no LocalBluetoothManager");
+            Log.e(TAG, "findAllCachedBluetoothDevicesByGroupId: no LocalBluetoothManager");
             return cachedBluetoothDevices;
         }
         CachedBluetoothDevice mainDevice =
@@ -262,16 +263,14 @@
                         .filter(cachedDevice -> cachedDevice.getGroupId() == deviceGroupId)
                         .findFirst().orElse(null);
         if (mainDevice == null) {
-            Log.e(TAG, "getAllOfCachedBluetoothDevices: groupId = " + deviceGroupId
+            Log.e(TAG, "findAllCachedBluetoothDevicesByGroupId: groupId = " + deviceGroupId
                     + ", no main device.");
             return cachedBluetoothDevices;
         }
         cachedBluetoothDevice = mainDevice;
         cachedBluetoothDevices.add(cachedBluetoothDevice);
-        for (CachedBluetoothDevice member : cachedBluetoothDevice.getMemberDevice()) {
-            cachedBluetoothDevices.add(member);
-        }
-        Log.d(TAG, "getAllOfCachedBluetoothDevices: groupId = " + deviceGroupId
+        cachedBluetoothDevices.addAll(cachedBluetoothDevice.getMemberDevice());
+        Log.d(TAG, "findAllCachedBluetoothDevicesByGroupId: groupId = " + deviceGroupId
                 + " , cachedBluetoothDevice = " + cachedBluetoothDevice
                 + " , deviceList = " + cachedBluetoothDevices);
         return cachedBluetoothDevices;
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java
index 6f62ed9..1ae541c 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java
@@ -30,6 +30,9 @@
 import androidx.fragment.app.FragmentManager;
 
 import com.android.settings.R;
+import com.android.settings.bluetooth.BluetoothPairingDetail;
+import com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsQrCodeFragment;
+import com.android.settings.core.SubSettingLauncher;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
 import com.android.settingslib.bluetooth.BluetoothUtils;
 
@@ -130,9 +133,27 @@
             builder.setTitle(R.string.audio_sharing_share_dialog_title)
                     .setCustomImage(R.drawable.audio_sharing_guidance)
                     .setCustomMessage(R.string.audio_sharing_dialog_connect_device_content)
-                    .setNegativeButton(
-                            R.string.audio_sharing_close_button_label,
-                            (dig, which) -> onCancelClick());
+                    .setCustomPositiveButton(
+                            R.string.audio_sharing_pair_button_label,
+                            v -> {
+                                dismiss();
+                                new SubSettingLauncher(getContext())
+                                        .setDestination(BluetoothPairingDetail.class.getName())
+                                        .setSourceMetricsCategory(getMetricsCategory())
+                                        .launch();
+                                logDialogPositiveBtnClick();
+                            })
+                    .setCustomNegativeButton(
+                            R.string.audio_sharing_qrcode_button_label,
+                            v -> {
+                                dismiss();
+                                new SubSettingLauncher(getContext())
+                                        .setTitleRes(R.string.audio_streams_qr_code_page_title)
+                                        .setDestination(AudioStreamsQrCodeFragment.class.getName())
+                                        .setSourceMetricsCategory(getMetricsCategory())
+                                        .launch();
+                                logDialogNegativeBtnClick();
+                            });
         } else if (deviceItems.size() == 1) {
             AudioSharingDeviceItem deviceItem = Iterables.getOnlyElement(deviceItems);
             builder.setTitle(
@@ -145,11 +166,7 @@
                             v -> {
                                 if (sListener != null) {
                                     sListener.onItemClick(deviceItem);
-                                    mMetricsFeatureProvider.action(
-                                            getContext(),
-                                            SettingsEnums
-                                            .ACTION_AUDIO_SHARING_DIALOG_POSITIVE_BTN_CLICKED,
-                                            sEventData);
+                                    logDialogPositiveBtnClick();
                                 }
                                 dismiss();
                             })
@@ -165,6 +182,7 @@
                                     (AudioSharingDeviceItem item) -> {
                                         if (sListener != null) {
                                             sListener.onItemClick(item);
+                                            logDialogPositiveBtnClick();
                                         }
                                         dismiss();
                                     },
@@ -178,11 +196,22 @@
     private void onCancelClick() {
         if (sListener != null) {
             sListener.onCancelClick();
-            mMetricsFeatureProvider.action(
-                    getContext(),
-                    SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_NEGATIVE_BTN_CLICKED,
-                    sEventData);
+            logDialogNegativeBtnClick();
         }
         dismiss();
     }
+
+    private void logDialogPositiveBtnClick() {
+        mMetricsFeatureProvider.action(
+                getContext(),
+                SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_POSITIVE_BTN_CLICKED,
+                sEventData);
+    }
+
+    private void logDialogNegativeBtnClick() {
+        mMetricsFeatureProvider.action(
+                getContext(),
+                SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_NEGATIVE_BTN_CLICKED,
+                sEventData);
+    }
 }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java
index 4ee405d..14c19de 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java
@@ -499,7 +499,7 @@
     private void removeSourceForGroup(
             int groupId, Map<Integer, List<BluetoothDevice>> groupedDevices) {
         if (mAssistant == null) {
-            Log.d(TAG, "Fail to add source due to null profiles, group = " + groupId);
+            Log.d(TAG, "Fail to remove source due to null profiles, group = " + groupId);
             return;
         }
         if (!groupedDevices.containsKey(groupId)) {
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingReceiver.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingReceiver.java
index b43a544..371613f 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingReceiver.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingReceiver.java
@@ -81,9 +81,15 @@
                 break;
             case ACTION_LE_AUDIO_SHARING_STOP:
                 LocalBluetoothManager manager = Utils.getLocalBtManager(context);
-                AudioSharingUtils.stopBroadcasting(manager);
-                metricsFeatureProvider.action(
-                        context, SettingsEnums.ACTION_STOP_AUDIO_SHARING_FROM_NOTIFICATION);
+                if (BluetoothUtils.isBroadcasting(manager)) {
+                    AudioSharingUtils.stopBroadcasting(manager);
+                    metricsFeatureProvider.action(
+                            context, SettingsEnums.ACTION_STOP_AUDIO_SHARING_FROM_NOTIFICATION);
+                } else {
+                    cancelSharingNotification(context);
+                    metricsFeatureProvider.action(
+                            context, SettingsEnums.ACTION_CANCEL_AUDIO_SHARING_NOTIFICATION);
+                }
                 break;
             default:
                 Log.w(TAG, "Received unexpected intent " + intent.getAction());
diff --git a/src/com/android/settings/datetime/AutoTimePreferenceController.java b/src/com/android/settings/datetime/AutoTimePreferenceController.java
index 434eba9..2942acb 100644
--- a/src/com/android/settings/datetime/AutoTimePreferenceController.java
+++ b/src/com/android/settings/datetime/AutoTimePreferenceController.java
@@ -39,6 +39,11 @@
     public AutoTimePreferenceController(Context context, String preferenceKey) {
         super(context, preferenceKey);
         mTimeManager = context.getSystemService(TimeManager.class);
+        // This is a no-op implementation of UpdateTimeAndDateCallback to avoid a NPE when
+        // setTimeAndDateCallback() isn't called, e.g. for slices and other cases where the
+        // controller is instantiated outside of the context of the real Date & Time settings
+        // screen.
+        mCallback  = (c) -> {};
     }
 
     public void setDateAndTimeCallback(UpdateTimeAndDateCallback callback) {
diff --git a/src/com/android/settings/datetime/AutoTimeZonePreferenceController.java b/src/com/android/settings/datetime/AutoTimeZonePreferenceController.java
index 011cc97..3a1f995 100644
--- a/src/com/android/settings/datetime/AutoTimeZonePreferenceController.java
+++ b/src/com/android/settings/datetime/AutoTimeZonePreferenceController.java
@@ -40,6 +40,11 @@
     public AutoTimeZonePreferenceController(Context context, String preferenceKey) {
         super(context, preferenceKey);
         mTimeManager = context.getSystemService(TimeManager.class);
+        // This is a no-op implementation of UpdateTimeAndDateCallback to avoid a NPE when
+        // setTimeAndDateCallback() isn't called, e.g. for slices and other cases where the
+        // controller is instantiated outside of the context of the real Date & Time settings
+        // screen.
+        mCallback  = (c) -> {};
     }
 
     /**
diff --git a/src/com/android/settings/datetime/TimeFormatPreferenceController.java b/src/com/android/settings/datetime/TimeFormatPreferenceController.java
index 22f7509..19805ad 100644
--- a/src/com/android/settings/datetime/TimeFormatPreferenceController.java
+++ b/src/com/android/settings/datetime/TimeFormatPreferenceController.java
@@ -43,6 +43,11 @@
     public TimeFormatPreferenceController(Context context, String key) {
         super(context, key);
         mDummyDate = Calendar.getInstance();
+        // This is a no-op implementation of UpdateTimeAndDateCallback to avoid a NPE when
+        // setTimeAndDateCallback() isn't called, e.g. for slices and other cases where the
+        // controller is instantiated outside of the context of the real Date & Time settings
+        // screen.
+        mUpdateTimeAndDateCallback  = (c) -> {};
     }
 
     /**
diff --git a/src/com/android/settings/fuelgauge/datasaver/DynamicDenylistManager.java b/src/com/android/settings/fuelgauge/datasaver/DynamicDenylistManager.java
index b77d5eb..ecb2a48 100644
--- a/src/com/android/settings/fuelgauge/datasaver/DynamicDenylistManager.java
+++ b/src/com/android/settings/fuelgauge/datasaver/DynamicDenylistManager.java
@@ -78,6 +78,11 @@
             return;
         }
 
+        if (mNetworkPolicyManager == null) {
+            Log.w(TAG, "syncPolicyIfNeeded: invalid mNetworkPolicyManager");
+            return;
+        }
+
         final SharedPreferences.Editor editor = getManualDenylistPref().edit();
         final int[] existedUids = mNetworkPolicyManager
                 .getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND);
@@ -91,6 +96,11 @@
 
     /** Set policy flags for specific UID. */
     public void setUidPolicyLocked(int uid, int policy) {
+        if (mNetworkPolicyManager == null) {
+            Log.w(TAG, "setUidPolicyLocked: invalid mNetworkPolicyManager");
+            return;
+        }
+
         Log.i(TAG, "setUidPolicyLocked: uid=" + uid + " policy=" + policy);
         synchronized (mLock) {
             mNetworkPolicyManager.setUidPolicy(uid, policy);
@@ -100,7 +110,7 @@
 
     /** Suggest a list of package to set as POLICY_REJECT. */
     public void setDenylist(Set<Integer> denylistTargetUids) {
-        if (denylistTargetUids == null) {
+        if (denylistTargetUids == null || mNetworkPolicyManager == null) {
             return;
         }
         final Set<Integer> manualDenylistUids = getDenylistAllUids(getManualDenylistPref());
@@ -164,6 +174,12 @@
             Log.w(TAG, "resetDenylistIfNeeded: invalid conditions");
             return;
         }
+
+        if (mNetworkPolicyManager == null) {
+            Log.w(TAG, "setUidPolicyLocked: invalid mNetworkPolicyManager");
+            return;
+        }
+
         synchronized (mLock) {
             final int[] uids = mNetworkPolicyManager
                     .getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND);
diff --git a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
index e92d999..7d5230d 100644
--- a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
+++ b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
@@ -19,9 +19,11 @@
 import static androidx.lifecycle.Lifecycle.Event.ON_START;
 import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
 
+import static com.android.settings.network.telephony.EnabledNetworkModePreferenceControllerHelperKt.getNetworkModePreferenceType;
 import static com.android.settings.network.telephony.EnabledNetworkModePreferenceControllerHelperKt.setAllowedNetworkTypes;
 
 import android.content.Context;
+import android.content.res.Resources;
 import android.os.PersistableBundle;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionInfo;
@@ -44,6 +46,7 @@
 
 import com.android.internal.telephony.flags.Flags;
 import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
 import com.android.settings.network.AllowedNetworkTypesListener;
 import com.android.settings.network.CarrierConfigCache;
 import com.android.settings.network.SubscriptionsChangeListener;
@@ -61,16 +64,17 @@
  * Preference controller for "Enabled network mode"
  */
 public class EnabledNetworkModePreferenceController extends
-        TelephonyBasePreferenceController implements
+        BasePreferenceController implements
         ListPreference.OnPreferenceChangeListener, LifecycleObserver,
         SubscriptionsChangeListener.SubscriptionsChangeListenerClient {
 
     private static final String LOG_TAG = "EnabledNetworkMode";
+
+    private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
     private AllowedNetworkTypesListener mAllowedNetworkTypesListener;
     private Preference mPreference;
     private PreferenceScreen mPreferenceScreen;
     private TelephonyManager mTelephonyManager;
-    private CarrierConfigCache mCarrierConfigCache;
     private PreferenceEntriesBuilder mBuilder;
     private SubscriptionsChangeListener mSubscriptionsListener;
     private int mCallState = TelephonyManager.CALL_STATE_IDLE;
@@ -81,36 +85,16 @@
     public EnabledNetworkModePreferenceController(Context context, String key) {
         super(context, key);
         mSubscriptionsListener = new SubscriptionsChangeListener(context, this);
-        mCarrierConfigCache = CarrierConfigCache.getInstance(context);
         if (mTelephonyCallback == null) {
             mTelephonyCallback = new PhoneCallStateTelephonyCallback();
         }
     }
 
     @Override
-    public int getAvailabilityStatus(int subId) {
-        boolean visible;
-
-        final PersistableBundle carrierConfig = mCarrierConfigCache.getConfigForSubId(subId);
-        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            visible = false;
-        } else if (carrierConfig == null
-                || !CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfig)) {
-            visible = false;
-        } else if (carrierConfig.getBoolean(
-                CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL)
-                || carrierConfig.getBoolean(
-                CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL)) {
-            visible = false;
-        } else if (carrierConfig.getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL)) {
-            visible = false;
-        } else if (!isCallStateIdle()) {
-            return AVAILABLE_UNSEARCHABLE;
-        } else {
-            visible = true;
-        }
-
-        return visible ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
+    public int getAvailabilityStatus() {
+        return getNetworkModePreferenceType(mContext, mSubId)
+                == NetworkModePreferenceType.EnabledNetworkMode
+                ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
     }
 
     protected boolean isCallStateIdle() {
@@ -953,9 +937,14 @@
         }
     }
 
+    /**
+     * Returns the resources associated with Subscription.
+     *
+     * @return Resources associated with Subscription.
+     */
     @VisibleForTesting
-    PhoneCallStateTelephonyCallback getTelephonyCallback() {
-        return mTelephonyCallback;
+    Resources getResourcesForSubId() {
+        return SubscriptionManager.getResourcesForSubId(mContext, mSubId);
     }
 
     @Override
diff --git a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerHelper.kt b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerHelper.kt
index eab5d74..d297e1c 100644
--- a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerHelper.kt
+++ b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerHelper.kt
@@ -16,9 +16,15 @@
 
 package com.android.settings.network.telephony
 
+import android.content.Context
+import android.telephony.CarrierConfigManager
+import android.telephony.SubscriptionManager
 import android.telephony.TelephonyManager
 import androidx.lifecycle.LifecycleOwner
 import androidx.lifecycle.lifecycleScope
+import com.android.settings.R
+import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchItem
+import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchResult
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
 
@@ -33,3 +39,62 @@
         )
     }
 }
+
+enum class NetworkModePreferenceType {
+    EnabledNetworkMode,
+    PreferredNetworkMode,
+    None,
+}
+
+fun getNetworkModePreferenceType(context: Context, subId: Int): NetworkModePreferenceType {
+    if (!SubscriptionManager.isValidSubscriptionId(subId)) return NetworkModePreferenceType.None
+    data class Config(
+        val carrierConfigApplied: Boolean,
+        val hideCarrierNetworkSettings: Boolean,
+        val hidePreferredNetworkType: Boolean,
+        val worldPhone: Boolean,
+    )
+
+    val config =
+        CarrierConfigRepository(context).transformConfig(subId) {
+            Config(
+                carrierConfigApplied =
+                    getBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL),
+                hideCarrierNetworkSettings =
+                    getBoolean(CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL),
+                hidePreferredNetworkType =
+                    getBoolean(CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL),
+                worldPhone = getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL),
+            )
+        }
+
+    return when {
+        !config.carrierConfigApplied ||
+            config.hideCarrierNetworkSettings ||
+            config.hidePreferredNetworkType -> NetworkModePreferenceType.None
+        config.worldPhone -> NetworkModePreferenceType.PreferredNetworkMode
+        else -> NetworkModePreferenceType.EnabledNetworkMode
+    }
+}
+
+class PreferredNetworkModeSearchItem(private val context: Context) :
+    MobileNetworkSettingsSearchItem {
+    private val title: String = context.getString(R.string.preferred_network_mode_title)
+
+    override fun getSearchResult(subId: Int): MobileNetworkSettingsSearchResult? =
+        when (getNetworkModePreferenceType(context, subId)) {
+            NetworkModePreferenceType.PreferredNetworkMode ->
+                MobileNetworkSettingsSearchResult(
+                    key = "preferred_network_mode_key",
+                    title = title,
+                )
+
+            NetworkModePreferenceType.EnabledNetworkMode ->
+                MobileNetworkSettingsSearchResult(
+                    key = "enabled_networks_key",
+                    title = title,
+                )
+
+            else -> null
+        }
+}
diff --git a/src/com/android/settings/network/telephony/MmsMessagePreferenceController.kt b/src/com/android/settings/network/telephony/MmsMessagePreferenceController.kt
index c929d5c..220218c 100644
--- a/src/com/android/settings/network/telephony/MmsMessagePreferenceController.kt
+++ b/src/com/android/settings/network/telephony/MmsMessagePreferenceController.kt
@@ -20,11 +20,13 @@
 import android.telephony.SubscriptionManager
 import android.telephony.TelephonyManager
 import android.telephony.data.ApnSetting
+import androidx.annotation.VisibleForTesting
 import androidx.lifecycle.LifecycleOwner
 import androidx.preference.PreferenceScreen
 import com.android.settings.R
 import com.android.settings.Settings.MobileNetworkActivity.EXTRA_MMS_MESSAGE
 import com.android.settings.core.TogglePreferenceController
+import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchResult
 import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchItem
 import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
 import kotlinx.coroutines.flow.combine
@@ -109,7 +111,7 @@
         }
 
         class MmsMessageSearchItem(
-            context: Context,
+            private val context: Context,
             private val getDefaultDataSubId: () -> Int = {
                 SubscriptionManager.getDefaultDataSubscriptionId()
             },
@@ -117,12 +119,18 @@
             private var telephonyManager: TelephonyManager =
                 context.getSystemService(TelephonyManager::class.java)!!
 
-            override val key: String = EXTRA_MMS_MESSAGE
-            override val title: String = context.getString(R.string.mms_message_title)
-
-            override fun isAvailable(subId: Int): Boolean =
+            @VisibleForTesting
+            fun isAvailable(subId: Int): Boolean =
                 getAvailabilityStatus(
                     telephonyManager.createForSubscriptionId(subId), subId, getDefaultDataSubId)
+
+            override fun getSearchResult(subId: Int): MobileNetworkSettingsSearchResult? {
+                if (!isAvailable(subId)) return null
+                return MobileNetworkSettingsSearchResult(
+                    key = EXTRA_MMS_MESSAGE,
+                    title = context.getString(R.string.mms_message_title),
+                )
+            }
         }
     }
 }
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndex.kt b/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndex.kt
index 4e97d31..58661f0 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndex.kt
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndex.kt
@@ -39,15 +39,14 @@
     private val searchItemsFactory: (context: Context) -> List<MobileNetworkSettingsSearchItem> =
         ::createSearchItems,
 ) {
+    data class MobileNetworkSettingsSearchResult(
+        val key: String,
+        val title: String,
+        val keywords: String? = null,
+    )
+
     interface MobileNetworkSettingsSearchItem {
-        val key: String
-
-        val title: String
-
-        val keywords: String?
-            get() = null
-
-        fun isAvailable(subId: Int): Boolean
+        fun getSearchResult(subId: Int): MobileNetworkSettingsSearchResult?
     }
 
     fun createSearchIndexableData(): SearchIndexableData {
@@ -71,13 +70,15 @@
         searchItem: MobileNetworkSettingsSearchItem,
         subInfos: List<SubscriptionInfo>
     ): List<SearchIndexableRaw> =
-        subInfos
-            .filter { searchItem.isAvailable(it.subscriptionId) }
-            .map { subInfo -> searchIndexableRaw(context, searchItem, subInfo) }
+        subInfos.mapNotNull { subInfo ->
+            searchItem.getSearchResult(subInfo.subscriptionId)?.let { searchResult ->
+                searchIndexableRaw(context, searchResult, subInfo)
+            }
+        }
 
     private fun searchIndexableRaw(
         context: Context,
-        searchItem: MobileNetworkSettingsSearchItem,
+        searchResult: MobileNetworkSettingsSearchResult,
         subInfo: SubscriptionInfo,
     ): SearchIndexableRaw {
         val key =
@@ -85,7 +86,7 @@
                 .setFragment(
                     SpaSearchLandingFragment.newBuilder()
                         .setFragmentName(MobileNetworkSettings::class.java.name)
-                        .setPreferenceKey(searchItem.key)
+                        .setPreferenceKey(searchResult.key)
                         .putArguments(
                             Settings.EXTRA_SUB_ID,
                             BundleValue.newBuilder().setIntValue(subInfo.subscriptionId).build()))
@@ -94,8 +95,8 @@
         return createSearchIndexableRaw(
             context = context,
             spaSearchLandingKey = key,
-            itemTitle = searchItem.title,
-            keywords = searchItem.keywords,
+            itemTitle = searchResult.title,
+            keywords = searchResult.keywords,
             indexableClass = MobileNetworkSettings::class.java,
             pageTitle = "$simsTitle > ${subInfo.displayName}",
         )
@@ -115,6 +116,7 @@
             listOf(
                 MmsMessageSearchItem(context),
                 NrAdvancedCallingSearchItem(context),
+                PreferredNetworkModeSearchItem(context),
                 RoamingSearchItem(context),
                 WifiCallingSearchItem(context),
             )
diff --git a/src/com/android/settings/network/telephony/NrAdvancedCallingPreferenceController.kt b/src/com/android/settings/network/telephony/NrAdvancedCallingPreferenceController.kt
index 5c94e84..0d8766e 100644
--- a/src/com/android/settings/network/telephony/NrAdvancedCallingPreferenceController.kt
+++ b/src/com/android/settings/network/telephony/NrAdvancedCallingPreferenceController.kt
@@ -25,6 +25,7 @@
 import androidx.compose.ui.res.stringResource
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.android.settings.R
+import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchResult
 import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchItem
 import com.android.settings.spa.preference.ComposePreferenceController
 import com.android.settingslib.spa.widget.preference.SwitchPreference
@@ -79,12 +80,17 @@
     companion object {
         class NrAdvancedCallingSearchItem(private val context: Context) :
             MobileNetworkSettingsSearchItem {
-            override val key = "nr_advanced_calling"
-            override val title: String = context.getString(R.string.nr_advanced_calling_title)
-            override val keywords: String = context.getString(R.string.keywords_nr_advanced_calling)
 
-            override fun isAvailable(subId: Int): Boolean =
-                VoNrRepository(context, subId).isVoNrAvailable()
+            fun isAvailable(subId: Int): Boolean = VoNrRepository(context, subId).isVoNrAvailable()
+
+            override fun getSearchResult(subId: Int): MobileNetworkSettingsSearchResult? {
+                if (!isAvailable(subId)) return null
+                return MobileNetworkSettingsSearchResult(
+                    key = "nr_advanced_calling",
+                    title = context.getString(R.string.nr_advanced_calling_title),
+                    keywords = context.getString(R.string.keywords_nr_advanced_calling),
+                )
+            }
         }
     }
 }
diff --git a/src/com/android/settings/network/telephony/PreferredNetworkModePreferenceController.java b/src/com/android/settings/network/telephony/PreferredNetworkModePreferenceController.java
index bdfeace..210cd87 100644
--- a/src/com/android/settings/network/telephony/PreferredNetworkModePreferenceController.java
+++ b/src/com/android/settings/network/telephony/PreferredNetworkModePreferenceController.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.network.telephony;
 
+import static com.android.settings.network.telephony.EnabledNetworkModePreferenceControllerHelperKt.getNetworkModePreferenceType;
+
 import android.content.Context;
 import android.os.PersistableBundle;
 import android.telephony.CarrierConfigManager;
@@ -27,16 +29,18 @@
 import androidx.preference.Preference;
 
 import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
 import com.android.settings.network.CarrierConfigCache;
 import com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants;
 
 /**
  * Preference controller for "Preferred network mode"
  */
-public class PreferredNetworkModePreferenceController extends TelephonyBasePreferenceController
+public class PreferredNetworkModePreferenceController extends BasePreferenceController
         implements ListPreference.OnPreferenceChangeListener {
     private static final String TAG = "PrefNetworkModeCtrl";
 
+    private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
     private CarrierConfigCache mCarrierConfigCache;
     private TelephonyManager mTelephonyManager;
     private boolean mIsGlobalCdma;
@@ -47,25 +51,10 @@
     }
 
     @Override
-    public int getAvailabilityStatus(int subId) {
-        final PersistableBundle carrierConfig = mCarrierConfigCache.getConfigForSubId(subId);
-        boolean visible;
-        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            visible = false;
-        } else if (carrierConfig == null) {
-            visible = false;
-        } else if (carrierConfig.getBoolean(
-                CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL)
-                || carrierConfig.getBoolean(
-                CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL)) {
-            visible = false;
-        } else if (carrierConfig.getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL)) {
-            visible = true;
-        } else {
-            visible = false;
-        }
-
-        return visible ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
+    public int getAvailabilityStatus() {
+        return getNetworkModePreferenceType(mContext, mSubId)
+                == NetworkModePreferenceType.PreferredNetworkMode
+                ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
     }
 
     @Override
diff --git a/src/com/android/settings/network/telephony/RoamingPreferenceController.kt b/src/com/android/settings/network/telephony/RoamingPreferenceController.kt
index 7633677..a5ac7d6 100644
--- a/src/com/android/settings/network/telephony/RoamingPreferenceController.kt
+++ b/src/com/android/settings/network/telephony/RoamingPreferenceController.kt
@@ -29,6 +29,7 @@
 import androidx.fragment.app.FragmentManager
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.android.settings.R
+import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchResult
 import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchItem
 import com.android.settings.spa.preference.ComposePreferenceController
 import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
@@ -98,16 +99,21 @@
     companion object {
         private const val DIALOG_TAG = "MobileDataDialog"
 
-        class RoamingSearchItem(context: Context) : MobileNetworkSettingsSearchItem {
-            override val key = "button_roaming_key"
-            override val title: String = context.getString(R.string.roaming)
-
+        class RoamingSearchItem(private val context: Context) : MobileNetworkSettingsSearchItem {
             private val carrierConfigRepository = CarrierConfigRepository(context)
 
-            override fun isAvailable(subId: Int): Boolean =
+            fun isAvailable(subId: Int): Boolean =
                 SubscriptionManager.isValidSubscriptionId(subId) &&
                     !carrierConfigRepository.getBoolean(
                         subId, CarrierConfigManager.KEY_FORCE_HOME_NETWORK_BOOL)
+
+            override fun getSearchResult(subId: Int): MobileNetworkSettingsSearchResult? {
+                if (!isAvailable(subId)) return null
+                return MobileNetworkSettingsSearchResult(
+                    key = "button_roaming_key",
+                    title = context.getString(R.string.roaming),
+                )
+            }
         }
     }
 }
diff --git a/src/com/android/settings/network/telephony/TelephonyBasePreferenceController.java b/src/com/android/settings/network/telephony/TelephonyBasePreferenceController.java
index 3972f39..ee15520 100644
--- a/src/com/android/settings/network/telephony/TelephonyBasePreferenceController.java
+++ b/src/com/android/settings/network/telephony/TelephonyBasePreferenceController.java
@@ -17,9 +17,6 @@
 package com.android.settings.network.telephony;
 
 import android.content.Context;
-import android.content.res.Resources;
-import android.os.PersistableBundle;
-import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
 
 import com.android.settings.core.BasePreferenceController;
@@ -59,29 +56,4 @@
     public void unsetAvailabilityStatus() {
         mSetSessionCount.getAndDecrement();
     }
-
-    /**
-     * Get carrier config based on specific subscription id.
-     *
-     * @param subId is the subscription id
-     * @return {@link PersistableBundle} of carrier config, or {@code null} when carrier config
-     * is not available.
-     */
-    public PersistableBundle getCarrierConfigForSubId(int subId) {
-        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
-            return null;
-        }
-        final CarrierConfigManager carrierConfigMgr =
-                mContext.getSystemService(CarrierConfigManager.class);
-        return carrierConfigMgr.getConfigForSubId(subId);
-    }
-
-    /**
-     * Returns the resources associated with Subscription.
-     *
-     * @return Resources associated with Subscription.
-     */
-    public Resources getResourcesForSubId() {
-        return SubscriptionManager.getResourcesForSubId(mContext, mSubId);
-    }
 }
diff --git a/src/com/android/settings/network/telephony/WifiCallingPreferenceController.kt b/src/com/android/settings/network/telephony/WifiCallingPreferenceController.kt
index 7e8e58c..e04763a 100644
--- a/src/com/android/settings/network/telephony/WifiCallingPreferenceController.kt
+++ b/src/com/android/settings/network/telephony/WifiCallingPreferenceController.kt
@@ -27,6 +27,7 @@
 import androidx.preference.PreferenceScreen
 import com.android.settings.R
 import com.android.settings.core.BasePreferenceController
+import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchResult
 import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchItem
 import com.android.settings.network.telephony.wificalling.WifiCallingRepository
 import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
@@ -132,12 +133,17 @@
         class WifiCallingSearchItem(
             private val context: Context,
         ) : MobileNetworkSettingsSearchItem {
-            override val key: String = "wifi_calling"
-            override val title: String = context.getString(R.string.wifi_calling_settings_title)
-
-            override fun isAvailable(subId: Int): Boolean = runBlocking {
+            private fun isAvailable(subId: Int): Boolean = runBlocking {
                 WifiCallingRepository(context, subId).wifiCallingReadyFlow().first()
             }
+
+            override fun getSearchResult(subId: Int): MobileNetworkSettingsSearchResult? {
+                if (!isAvailable(subId)) return null
+                return MobileNetworkSettingsSearchResult(
+                    key = "wifi_calling",
+                    title = context.getString(R.string.wifi_calling_settings_title),
+                )
+            }
         }
     }
 }
diff --git a/src/com/android/settings/password/BiometricFragment.java b/src/com/android/settings/password/BiometricFragment.java
index a7a039e..5030b6a 100644
--- a/src/com/android/settings/password/BiometricFragment.java
+++ b/src/com/android/settings/password/BiometricFragment.java
@@ -19,7 +19,6 @@
 import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED;
 
 import android.app.settings.SettingsEnums;
-import android.content.ComponentName;
 import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.BiometricPrompt;
 import android.hardware.biometrics.BiometricPrompt.AuthenticationCallback;
@@ -44,7 +43,6 @@
     private static final String TAG = "ConfirmDeviceCredential/BiometricFragment";
 
     private static final String KEY_PROMPT_INFO = "prompt_info";
-    private static final String KEY_CALLING_ACTIVITY = "calling_activity";
 
     // Re-set by the application. Should be done upon orientation changes, etc
     private Executor mClientExecutor;
@@ -94,13 +92,10 @@
      * @param promptInfo
      * @return
      */
-    public static BiometricFragment newInstance(PromptInfo promptInfo,
-            ComponentName callingActivity) {
+    public static BiometricFragment newInstance(PromptInfo promptInfo) {
         BiometricFragment biometricFragment = new BiometricFragment();
         final Bundle bundle = new Bundle();
         bundle.putParcelable(KEY_PROMPT_INFO, promptInfo);
-
-        bundle.putParcelable(KEY_CALLING_ACTIVITY, callingActivity);
         biometricFragment.setArguments(bundle);
         return biometricFragment;
     }
@@ -135,8 +130,6 @@
 
         final Bundle bundle = getArguments();
         final PromptInfo promptInfo = bundle.getParcelable(KEY_PROMPT_INFO);
-        final ComponentName callingActivity = bundle.getParcelable(KEY_CALLING_ACTIVITY);
-
         BiometricPrompt.Builder promptBuilder = new BiometricPrompt.Builder(getContext())
                 .setTitle(promptInfo.getTitle())
                 .setUseDefaultTitle() // use default title if title is null/empty
@@ -152,7 +145,8 @@
                         promptInfo.isDisallowBiometricsIfPolicyExists())
                 .setShowEmergencyCallButton(promptInfo.isShowEmergencyCallButton())
                 .setReceiveSystemEvents(true)
-                .setComponentNameForConfirmDeviceCredentialActivity(callingActivity);
+                .setRealCallerForConfirmDeviceCredentialActivity(
+                        promptInfo.getRealCallerForConfirmDeviceCredentialActivity());
         if (promptInfo.getLogoRes() != 0){
             promptBuilder.setLogoRes(promptInfo.getLogoRes());
         }
diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
index 4f35532..d7d1531 100644
--- a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
+++ b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
@@ -104,6 +104,7 @@
     private boolean mForceVerifyPath = false;
     private boolean mGoingToBackground;
     private boolean mWaitingForBiometricCallback;
+    private int mBiometricsAuthenticators;
 
     private Executor mExecutor = (runnable -> {
         mHandler.post(runnable);
@@ -122,8 +123,14 @@
                     Log.i(TAG, "Finishing, user no longer valid: " + mUserId);
                     finish();
                 } else {
-                    // All other errors go to some version of CC
-                    showConfirmCredentials();
+                    if ((mBiometricsAuthenticators
+                            & BiometricManager.Authenticators.DEVICE_CREDENTIAL) != 0) {
+                        // All other errors go to some version of CC
+                        showConfirmCredentials();
+                    } else {
+                        Log.i(TAG, "Finishing, device credential not requested");
+                        finish();
+                    }
                 }
             } else if (mWaitingForBiometricCallback) { // mGoingToBackground is true
                 mWaitingForBiometricCallback = false;
@@ -188,7 +195,7 @@
         mDetails = intent.getCharSequenceExtra(KeyguardManager.EXTRA_DESCRIPTION);
         String alternateButton = intent.getStringExtra(
                 KeyguardManager.EXTRA_ALTERNATE_BUTTON_LABEL);
-        final int authenticators = intent.getIntExtra(BIOMETRIC_PROMPT_AUTHENTICATORS,
+        mBiometricsAuthenticators = intent.getIntExtra(BIOMETRIC_PROMPT_AUTHENTICATORS,
                 BiometricManager.Authenticators.DEVICE_CREDENTIAL
                         | BiometricManager.Authenticators.BIOMETRIC_WEAK);
         final String negativeButtonText = intent.getStringExtra(
@@ -229,8 +236,9 @@
         promptInfo.setTitle(mTitle);
         promptInfo.setDescription(mDetails);
         promptInfo.setDisallowBiometricsIfPolicyExists(mCheckDevicePolicyManager);
-        promptInfo.setAuthenticators(authenticators);
+        promptInfo.setAuthenticators(mBiometricsAuthenticators);
         promptInfo.setNegativeButtonText(negativeButtonText);
+        promptInfo.setRealCallerForConfirmDeviceCredentialActivity(getCallingActivity());
 
         if (android.multiuser.Flags.enablePrivateSpaceFeatures()
                 && android.multiuser.Flags.usePrivateSpaceIconInBiometricPrompt()
@@ -496,8 +504,7 @@
         boolean newFragment = false;
 
         if (mBiometricFragment == null) {
-            mBiometricFragment = BiometricFragment.newInstance(promptInfo,
-                    getCallingActivity());
+            mBiometricFragment = BiometricFragment.newInstance(promptInfo);
             newFragment = true;
         }
         mBiometricFragment.setCallbacks(mExecutor, mAuthenticationCallback);
diff --git a/src/com/android/settings/password/SetNewPasswordActivity.java b/src/com/android/settings/password/SetNewPasswordActivity.java
index 0ba52ea..36756f9 100644
--- a/src/com/android/settings/password/SetNewPasswordActivity.java
+++ b/src/com/android/settings/password/SetNewPasswordActivity.java
@@ -124,9 +124,7 @@
 
     @Override
     public void launchChooseLock(Bundle chooseLockFingerprintExtras) {
-        final boolean isInSetupWizard = WizardManagerHelper.isAnySetupWizard(getIntent());
-        Intent intent = isInSetupWizard ? new Intent(this, SetupChooseLockGeneric.class)
-                : new Intent(this, ChooseLockGeneric.class);
+        final Intent intent = new Intent(this, SetupChooseLockGeneric.class);
         intent.setAction(mNewPasswordAction);
         intent.putExtras(chooseLockFingerprintExtras);
         intent.putExtra(EXTRA_KEY_CHOOSE_LOCK_SCREEN_TITLE,
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 0cf01e3..c387d9e 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -919,7 +919,7 @@
             d = mCreateUserDialogController.createDialog(
                     getActivity(),
                     this::startActivityForResult,
-                    UserManager.isMultipleAdminEnabled(),
+                    canCreateAdminUser(),
                     (userName, userIcon, isAdmin) -> {
                         mPendingUserIcon = userIcon;
                         mPendingUserName = userName;
@@ -937,6 +937,19 @@
         return d;
     }
 
+    /**
+     * Checks if the creation of a new admin user is allowed.
+     * @return {@code true} if creating a new admin is allowed, {@code false} otherwise.
+     */
+    private boolean canCreateAdminUser() {
+        if (Flags.unicornModeRefactoringForHsumReadOnly()) {
+            return UserManager.isMultipleAdminEnabled()
+                    && !mUserManager.hasUserRestriction(UserManager.DISALLOW_GRANT_ADMIN);
+        } else {
+            return UserManager.isMultipleAdminEnabled();
+        }
+    }
+
     @Override
     public int getDialogMetricsCategory(int dialogId) {
         switch (dialogId) {
diff --git a/src/com/android/settings/wifi/dpp/WifiQrCode.java b/src/com/android/settings/wifi/dpp/WifiQrCode.java
index 9b93480..78e0625 100644
--- a/src/com/android/settings/wifi/dpp/WifiQrCode.java
+++ b/src/com/android/settings/wifi/dpp/WifiQrCode.java
@@ -46,6 +46,7 @@
  *
  */
 public class WifiQrCode {
+    private static final String TAG = "WifiQrCode";
     static final String SCHEME_DPP = "DPP";
     static final String SCHEME_ZXING_WIFI_NETWORK_CONFIG = "WIFI";
     static final String PREFIX_DPP = "DPP:";
@@ -119,13 +120,13 @@
         try {
             wifiQrCode = new WifiQrCode(qrCode);
         } catch(IllegalArgumentException e) {
+            Log.e(TAG, "Failed to create WifiQrCode!", e);
             return null;
         }
-
-        if (SCHEME_DPP.equals(wifiQrCode.getScheme())) {
-            return wifiQrCode;
+        if (wifiQrCode.getScheme() != UriParserResults.URI_SCHEME_DPP) {
+            Log.e(TAG, "wifiQrCode scheme is not DPP!");
+            return null;
         }
-
-        return null;
+        return wifiQrCode;
     }
 }
diff --git a/tests/robotests/src/com/android/settings/accessibility/shortcuts/FloatingButtonShortcutOptionControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/shortcuts/FloatingButtonShortcutOptionControllerTest.java
index 20f5d5d..0952b09 100644
--- a/tests/robotests/src/com/android/settings/accessibility/shortcuts/FloatingButtonShortcutOptionControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/shortcuts/FloatingButtonShortcutOptionControllerTest.java
@@ -16,37 +16,46 @@
 
 package com.android.settings.accessibility.shortcuts;
 
-import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
-import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_GESTURE;
-
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.spy;
+
 import android.content.ComponentName;
 import android.content.Context;
-import android.provider.Settings;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
+import android.provider.Flags;
 
 import androidx.preference.PreferenceManager;
 import androidx.preference.PreferenceScreen;
 import androidx.test.core.app.ApplicationProvider;
 
 import com.android.settings.R;
+import com.android.settings.testutils.AccessibilityTestUtils;
+import com.android.settings.testutils.shadow.SettingsShadowResources;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
 
 import java.util.Set;
 
 /**
  * Tests for {@link FloatingButtonShortcutOptionController}
  */
+@Config(shadows = SettingsShadowResources.class)
 @RunWith(RobolectricTestRunner.class)
 public class FloatingButtonShortcutOptionControllerTest {
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
     private static final String PREF_KEY = "prefKey";
     private static final String TARGET =
             new ComponentName("FakePackage", "FakeClass").flattenToString();
-    private final Context mContext = ApplicationProvider.getApplicationContext();
+    private final Context mContext = spy(ApplicationProvider.getApplicationContext());
     private FloatingButtonShortcutOptionController mController;
     private ShortcutOptionPreference mShortcutOptionPreference;
 
@@ -61,7 +70,6 @@
         mShortcutOptionPreference.setKey(PREF_KEY);
         mPreferenceScreen = new PreferenceManager(mContext).createPreferenceScreen(mContext);
         mPreferenceScreen.addPreference(mShortcutOptionPreference);
-        setFloatingButtonEnabled(true);
     }
 
     @Test
@@ -95,23 +103,26 @@
 
     @Test
     public void isShortcutAvailable_floatingMenuEnabled_returnTrue() {
-        setFloatingButtonEnabled(true);
+        AccessibilityTestUtils.setSoftwareShortcutMode(
+                mContext, /* gestureNavEnabled= */ false, /* floatingButtonEnabled= */ true);
 
         assertThat(mController.isShortcutAvailable()).isTrue();
     }
 
     @Test
     public void isShortcutAvailable_floatingMenuDisabled_returnFalse() {
-        setFloatingButtonEnabled(false);
+        AccessibilityTestUtils.setSoftwareShortcutMode(
+                mContext, /* gestureNavEnabled= */ false, /* floatingButtonEnabled= */ false);
 
         assertThat(mController.isShortcutAvailable()).isFalse();
     }
 
-    private void setFloatingButtonEnabled(boolean enable) {
-        int mode = enable
-                ? ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU : ACCESSIBILITY_BUTTON_MODE_GESTURE;
+    @Test
+    @EnableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
+    public void isShortcutAvailable_gestureNavigationMode_returnsTrue() {
+        AccessibilityTestUtils.setSoftwareShortcutMode(
+                mContext, /* gestureNavEnabled= */ true, /* floatingButtonEnabled= */ false);
 
-        Settings.Secure.putInt(mContext.getContentResolver(),
-                Settings.Secure.ACCESSIBILITY_BUTTON_MODE, mode);
+        assertThat(mController.isShortcutAvailable()).isTrue();
     }
 }
diff --git a/tests/robotests/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionControllerTest.java
index 0149cc3..1d46cae 100644
--- a/tests/robotests/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionControllerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.accessibility.shortcuts;
 
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
 import static com.android.settings.testutils.AccessibilityTestUtils.setupMockAccessibilityManager;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -25,6 +27,10 @@
 
 import android.content.ComponentName;
 import android.content.Context;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
+import android.provider.Flags;
 import android.view.accessibility.AccessibilityManager;
 
 import androidx.preference.PreferenceManager;
@@ -37,6 +43,7 @@
 import com.android.settingslib.utils.StringUtil;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
@@ -50,6 +57,8 @@
 @Config(shadows = SettingsShadowResources.class)
 @RunWith(RobolectricTestRunner.class)
 public class GestureShortcutOptionControllerTest {
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
     private static final String PREF_KEY = "prefKey";
     private static final String TARGET =
             new ComponentName("FakePackage", "FakeClass").flattenToString();
@@ -137,6 +146,18 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
+    public void getSummary_standaloneGestureFlagOn_verifyNoCustomizeA11yButtonTest() {
+        enableTouchExploration(true);
+        String expected = StringUtil.getIcuPluralsString(
+                mContext,
+                /* count= */ 3,
+                R.string.accessibility_shortcut_edit_dialog_summary_gesture);
+
+        assertThat(mController.getSummary().toString()).isEqualTo(expected);
+    }
+
+    @Test
     public void isShortcutAvailable_inSuw_returnFalse() {
         mController.setInSetupWizard(true);
 
@@ -144,6 +165,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
     public void isShortcutAvailable_notInSuwUseGestureNavSystemUseFab_returnFalse() {
         mController.setInSetupWizard(false);
         AccessibilityTestUtils.setSoftwareShortcutMode(
@@ -179,6 +201,28 @@
         assertThat(mController.isShortcutAvailable()).isFalse();
     }
 
+    @EnableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
+    @Test
+    public void isShortcutAvailable_floatingMenuEnabled_gestureNavEnabled_returnsTrue() {
+        mController.setInSetupWizard(false);
+        AccessibilityTestUtils.setSoftwareShortcutMode(
+                mContext, /* gestureNavEnabled= */ true, /* floatingButtonEnabled= */ true);
+
+        assertThat(mController.isShortcutAvailable()).isTrue();
+    }
+
+    @EnableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
+    @Test
+    public void getShortcutType_gesture() {
+        assertThat(mController.getShortcutType()).isEqualTo(GESTURE);
+    }
+
+    @DisableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
+    @Test
+    public void getShortcutType_software() {
+        assertThat(mController.getShortcutType()).isEqualTo(SOFTWARE);
+    }
+
     private void enableTouchExploration(boolean enable) {
         AccessibilityManager am = setupMockAccessibilityManager(mContext);
         when(am.isTouchExplorationEnabled()).thenReturn(enable);
diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsFragmentTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsFragmentTest.java
index b3e1c5d..ca76c1e 100644
--- a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsFragmentTest.java
@@ -54,6 +54,7 @@
 import android.os.CancellationSignal;
 import android.os.Looper;
 import android.os.UserHandle;
+import android.os.Vibrator;
 import android.platform.test.annotations.EnableFlags;
 import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.Settings;
@@ -128,6 +129,9 @@
             mAuthenticationCallbackArgumentCaptor = ArgumentCaptor.forClass(
             FingerprintManager.AuthenticationCallback.class);
 
+    @Mock
+    private Vibrator mVibrator;
+
     private FingerprintAuthenticateSidecar mFingerprintAuthenticateSidecar;
     private FingerprintRemoveSidecar mFingerprintRemoveSidecar;
 
@@ -141,6 +145,7 @@
         doReturn(mContext).when(mFragment).getContext();
         doReturn(mBiometricManager).when(mContext).getSystemService(BiometricManager.class);
         doReturn(true).when(mFingerprintManager).isHardwareDetected();
+        doReturn(mVibrator).when(mContext).getSystemService(Vibrator.class);
         when(mBiometricManager.canAuthenticate(
                 BiometricManager.Authenticators.MANDATORY_BIOMETRICS))
                 .thenReturn(BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE);
@@ -288,6 +293,28 @@
     }
 
     @Test
+    @Ignore("b/353726774")
+    public void fingerprintVibratesOnAuthSuccess() {
+        setUpFragment(false);
+
+        doNothing().when(mFingerprintManager).authenticate(any(),
+                mCancellationSignalArgumentCaptor.capture(),
+                mAuthenticationCallbackArgumentCaptor.capture(), any(), anyInt());
+
+        mFingerprintAuthenticateSidecar.startAuthentication(1);
+
+        assertThat(mAuthenticationCallbackArgumentCaptor.getValue()).isNotNull();
+        assertThat(mCancellationSignalArgumentCaptor.getValue()).isNotNull();
+
+        mAuthenticationCallbackArgumentCaptor.getValue()
+                .onAuthenticationSucceeded(new FingerprintManager.AuthenticationResult(null,
+                        new Fingerprint("finger 1", 1, 1), 0 /* userId */, false));
+
+        shadowOf(Looper.getMainLooper()).idle();
+        verify(mVibrator).vibrate(FingerprintSettings.SUCCESS_VIBRATION_EFFECT);
+    }
+
+    @Test
     public void testNotIndexable_whenDisabled() {
         doReturn(mPackageManager).when(mContext).getPackageManager();
         doReturn(false)
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java
index 03113421..ba90ccf 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java
@@ -18,10 +18,10 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -32,22 +32,31 @@
 import android.graphics.drawable.Drawable;
 import android.os.UserManager;
 import android.util.Pair;
-import android.view.ContextThemeWrapper;
+
+import androidx.test.core.app.ApplicationProvider;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
+import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 import org.robolectric.util.ReflectionHelpers;
 
@@ -57,18 +66,21 @@
 import java.util.List;
 
 @RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowAlertDialogCompat.class})
+@Config(shadows = {ShadowAlertDialogCompat.class,
+        com.android.settings.testutils.shadow.ShadowBluetoothUtils.class})
 public class BluetoothDevicePreferenceTest {
     private static final boolean SHOW_DEVICES_WITHOUT_NAMES = true;
-    private static final String MAC_ADDRESS = "04:52:C7:0B:D8:3C";
-    private static final String MAC_ADDRESS_2 = "05:52:C7:0B:D8:3C";
-    private static final String MAC_ADDRESS_3 = "06:52:C7:0B:D8:3C";
-    private static final String MAC_ADDRESS_4 = "07:52:C7:0B:D8:3C";
+    private static final String TEST_MAC_ADDRESS = "04:52:C7:0B:D8:3C";
+    private static final String TEST_MAC_ADDRESS_1 = "05:52:C7:0B:D8:3C";
+    private static final String TEST_MAC_ADDRESS_2 = "06:52:C7:0B:D8:3C";
+    private static final String TEST_MAC_ADDRESS_3 = "07:52:C7:0B:D8:3C";
     private static final Comparator<BluetoothDevicePreference> COMPARATOR =
             Comparator.naturalOrder();
     private static final String FAKE_DESCRIPTION = "fake_description";
+    private static final int TEST_DEVICE_GROUP_ID = 1;
 
-    private Context mContext;
+    @Rule
+    public final MockitoRule mockito = MockitoJUnit.rule();
     @Mock
     private CachedBluetoothDevice mCachedBluetoothDevice;
     @Mock
@@ -89,35 +101,37 @@
     private Drawable mDrawable;
     @Mock
     private BluetoothAdapter mBluetoothAdapter;
+    @Mock
+    private LocalBluetoothManager mLocalBluetoothManager;
+    @Mock
+    private CachedBluetoothDeviceManager mDeviceManager;
 
+    private Context mContext = ApplicationProvider.getApplicationContext();
     private FakeFeatureFactory mFakeFeatureFactory;
     private MetricsFeatureProvider mMetricsFeatureProvider;
+
     private BluetoothDevicePreference mPreference;
     private List<BluetoothDevicePreference> mPreferenceList = new ArrayList<>();
 
     @Before
     public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        Context context = spy(RuntimeEnvironment.application.getApplicationContext());
-        mContext = new ContextThemeWrapper(context, R.style.Theme_Settings);
+        mContext.setTheme(R.style.Theme_Settings);
         mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
         mMetricsFeatureProvider = mFakeFeatureFactory.getMetricsFeatureProvider();
-        when(mCachedBluetoothDevice.getAddress()).thenReturn(MAC_ADDRESS);
-        when(mCachedBluetoothDevice.getDrawableWithDescription())
-                .thenReturn(new Pair<>(mDrawable, FAKE_DESCRIPTION));
-        when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
-        when(mCachedDevice1.getAddress()).thenReturn(MAC_ADDRESS_2);
-        when(mCachedDevice1.getDrawableWithDescription())
-                .thenReturn(new Pair<>(mDrawable, FAKE_DESCRIPTION));
-        when(mCachedDevice1.getDevice()).thenReturn(mBluetoothDevice1);
-        when(mCachedDevice2.getAddress()).thenReturn(MAC_ADDRESS_3);
-        when(mCachedDevice2.getDrawableWithDescription())
-                .thenReturn(new Pair<>(mDrawable, FAKE_DESCRIPTION));
-        when(mCachedDevice2.getDevice()).thenReturn(mBluetoothDevice2);
-        when(mCachedDevice3.getAddress()).thenReturn(MAC_ADDRESS_4);
-        when(mCachedDevice3.getDrawableWithDescription())
-                .thenReturn(new Pair<>(mDrawable, FAKE_DESCRIPTION));
-        when(mCachedDevice3.getDevice()).thenReturn(mBluetoothDevice3);
+        ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
+        mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
+        when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
+        prepareCachedBluetoothDevice(mCachedBluetoothDevice, TEST_MAC_ADDRESS,
+                new Pair<>(mDrawable, FAKE_DESCRIPTION), TEST_DEVICE_GROUP_ID, mBluetoothDevice);
+        prepareCachedBluetoothDevice(mCachedDevice1, TEST_MAC_ADDRESS_1,
+                new Pair<>(mDrawable, FAKE_DESCRIPTION), TEST_DEVICE_GROUP_ID, mBluetoothDevice1);
+        prepareCachedBluetoothDevice(mCachedDevice2, TEST_MAC_ADDRESS_2,
+                new Pair<>(mDrawable, FAKE_DESCRIPTION), TEST_DEVICE_GROUP_ID, mBluetoothDevice2);
+        prepareCachedBluetoothDevice(mCachedDevice3, TEST_MAC_ADDRESS_3,
+                new Pair<>(mDrawable, FAKE_DESCRIPTION), TEST_DEVICE_GROUP_ID, mBluetoothDevice3);
+        when(mDeviceManager.getCachedDevicesCopy()).thenReturn(
+                ImmutableList.of(mCachedBluetoothDevice));
+
         mPreference = new BluetoothDevicePreference(mContext, mCachedBluetoothDevice,
                 SHOW_DEVICES_WITHOUT_NAMES, BluetoothDevicePreference.SortType.TYPE_DEFAULT);
         mPreference.mBluetoothAdapter = mBluetoothAdapter;
@@ -301,7 +315,8 @@
         // callback is not removed.
         mPreference.onAttached();
 
-        verify(mCachedBluetoothDevice, times(1)).registerCallback(any());
+        verify(mCachedBluetoothDevice, times(1)).registerCallback(eq(mContext.getMainExecutor()),
+                any());
         verify(mBluetoothAdapter, times(1)).addOnMetadataChangedListener(any(), any(), any());
     }
 
@@ -313,7 +328,99 @@
         mPreference.onAttached();
 
         verify(mCachedBluetoothDevice, times(1)).unregisterCallback(any());
-        verify(mCachedBluetoothDevice, times(2)).registerCallback(any());
+        verify(mCachedBluetoothDevice, times(2)).registerCallback(eq(mContext.getMainExecutor()),
+                any());
         verify(mBluetoothAdapter, times(2)).addOnMetadataChangedListener(any(), any(), any());
     }
+
+    @Test
+    public void onDeviceAttributesChanged_updatePreference() {
+        when(mCachedBluetoothDevice.getName()).thenReturn("Name");
+        mPreference.onAttached();
+        final String updatedName = "updatedName";
+        when(mCachedBluetoothDevice.getName()).thenReturn(updatedName);
+
+        getCachedBluetoothDeviceCallback().onDeviceAttributesChanged();
+
+        assertThat(mPreference.getTitle().toString()).isEqualTo(updatedName);
+    }
+
+    @Test
+    public void onAttached_memberDevicesAdded_registerAllCallback() {
+        when(mCachedBluetoothDevice.getMemberDevice()).thenReturn(
+                ImmutableSet.of(mCachedDevice1, mCachedDevice2, mCachedDevice3));
+        when(mDeviceManager.getCachedDevicesCopy()).thenReturn(
+                ImmutableList.of(mCachedBluetoothDevice, mCachedDevice1, mCachedDevice2,
+                        mCachedDevice3));
+        mPreference = new BluetoothDevicePreference(mContext, mCachedBluetoothDevice,
+                SHOW_DEVICES_WITHOUT_NAMES, BluetoothDevicePreference.SortType.TYPE_DEFAULT);
+
+        mPreference.onAttached();
+
+        verify(mCachedBluetoothDevice).registerCallback(eq(mContext.getMainExecutor()), any());
+        verify(mCachedDevice1).registerCallback(eq(mContext.getMainExecutor()), any());
+        verify(mCachedDevice2).registerCallback(eq(mContext.getMainExecutor()), any());
+        verify(mCachedDevice3).registerCallback(eq(mContext.getMainExecutor()), any());
+    }
+
+    @Test
+    public void onDetached_memberDevicesAdded_unregisterAllCallback() {
+        when(mCachedBluetoothDevice.getMemberDevice()).thenReturn(
+                ImmutableSet.of(mCachedDevice1, mCachedDevice2, mCachedDevice3));
+        when(mDeviceManager.getCachedDevicesCopy()).thenReturn(
+                ImmutableList.of(mCachedBluetoothDevice, mCachedDevice1, mCachedDevice2,
+                        mCachedDevice3));
+        mPreference = new BluetoothDevicePreference(mContext, mCachedBluetoothDevice,
+                SHOW_DEVICES_WITHOUT_NAMES, BluetoothDevicePreference.SortType.TYPE_DEFAULT);
+
+        mPreference.onAttached();
+        mPreference.onDetached();
+
+        verify(mCachedBluetoothDevice).unregisterCallback(any());
+        verify(mCachedDevice1).unregisterCallback(any());
+        verify(mCachedDevice2).unregisterCallback(any());
+        verify(mCachedDevice3).unregisterCallback(any());
+    }
+
+    @Test
+    public void onDeviceAttributesChanged_memberDevicesChanged_registerOnlyExistDeviceCallback() {
+        when(mCachedBluetoothDevice.getMemberDevice()).thenReturn(
+                ImmutableSet.of(mCachedDevice1, mCachedDevice2, mCachedDevice3));
+        when(mDeviceManager.getCachedDevicesCopy()).thenReturn(
+                ImmutableList.of(mCachedBluetoothDevice, mCachedDevice1, mCachedDevice2,
+                        mCachedDevice3));
+        mPreference = new BluetoothDevicePreference(mContext, mCachedBluetoothDevice,
+                SHOW_DEVICES_WITHOUT_NAMES, BluetoothDevicePreference.SortType.TYPE_DEFAULT);
+        mPreference.onAttached();
+        when(mCachedBluetoothDevice.getMemberDevice()).thenReturn(
+                ImmutableSet.of(mCachedDevice1, mCachedDevice2));
+        when(mDeviceManager.getCachedDevicesCopy()).thenReturn(
+                ImmutableList.of(mCachedBluetoothDevice, mCachedDevice1, mCachedDevice2));
+
+        getCachedBluetoothDeviceCallback().onDeviceAttributesChanged();
+
+        verify(mCachedBluetoothDevice, times(2)).registerCallback(eq(mContext.getMainExecutor()),
+                any());
+        verify(mCachedDevice1, times(2)).registerCallback(eq(mContext.getMainExecutor()), any());
+        verify(mCachedDevice2, times(2)).registerCallback(eq(mContext.getMainExecutor()), any());
+        verify(mCachedDevice3, times(1)).registerCallback(eq(mContext.getMainExecutor()), any());
+    }
+
+    private void prepareCachedBluetoothDevice(CachedBluetoothDevice cachedDevice, String address,
+            Pair<Drawable, String> drawableWithDescription, int groupId,
+            BluetoothDevice bluetoothDevice) {
+        when(cachedDevice.getAddress()).thenReturn(address);
+        when(cachedDevice.getDrawableWithDescription()).thenReturn(drawableWithDescription);
+        when(cachedDevice.getGroupId()).thenReturn(groupId);
+        when(cachedDevice.getDevice()).thenReturn(bluetoothDevice);
+    }
+
+    private CachedBluetoothDevice.Callback getCachedBluetoothDeviceCallback() {
+        ArgumentCaptor<CachedBluetoothDevice.Callback> callbackCaptor = ArgumentCaptor.forClass(
+                CachedBluetoothDevice.Callback.class);
+        verify(mCachedBluetoothDevice).registerCallback(eq(mContext.getMainExecutor()),
+                callbackCaptor.capture());
+
+        return callbackCaptor.getValue();
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragmentTest.java
index 20c225c..7227f37 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragmentTest.java
@@ -93,7 +93,6 @@
             new Pair[] {TEST_EVENT_DATA};
 
     private Fragment mParent;
-    private AudioSharingDialogFragment mFragment;
     private FakeFeatureFactory mFeatureFactory;
 
     @Before
@@ -107,7 +106,6 @@
         shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
                 BluetoothStatusCodes.FEATURE_SUPPORTED);
         mFeatureFactory = FakeFeatureFactory.setupForTest();
-        mFragment = new AudioSharingDialogFragment();
         mParent = new Fragment();
         FragmentController.setupFragment(
                 mParent, FragmentActivity.class, /* containerViewId= */ 0, /* bundle= */ null);
@@ -120,7 +118,8 @@
 
     @Test
     public void getMetricsCategory_correctValue() {
-        assertThat(mFragment.getMetricsCategory())
+        AudioSharingDialogFragment fragment = new AudioSharingDialogFragment();
+        assertThat(fragment.getMetricsCategory())
                 .isEqualTo(SettingsEnums.DIALOG_AUDIO_SHARING_ADD_DEVICE);
     }
 
@@ -145,7 +144,7 @@
     }
 
     @Test
-    public void onCreateDialog_flagOn_noConnectedDevice() {
+    public void onCreateDialog_flagOn_noExtraConnectedDevice() {
         mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
         AudioSharingDialogFragment.show(
                 mParent, new ArrayList<>(), EMPTY_EVENT_LISTENER, TEST_EVENT_DATA_LIST);
@@ -157,42 +156,67 @@
         assertThat(description).isNotNull();
         ImageView image = dialog.findViewById(R.id.description_image);
         assertThat(image).isNotNull();
-        Button shareBtn = dialog.findViewById(R.id.positive_btn);
-        assertThat(shareBtn).isNotNull();
-        Button cancelBtn = dialog.findViewById(R.id.negative_btn);
-        assertThat(cancelBtn).isNotNull();
+        Button positiveBtn = dialog.findViewById(R.id.positive_btn);
+        assertThat(positiveBtn).isNotNull();
+        Button negativeBtn = dialog.findViewById(R.id.negative_btn);
+        assertThat(negativeBtn).isNotNull();
         assertThat(dialog.isShowing()).isTrue();
         assertThat(description.getVisibility()).isEqualTo(View.VISIBLE);
         assertThat(description.getText().toString())
                 .isEqualTo(mParent.getString(R.string.audio_sharing_dialog_connect_device_content));
         assertThat(image.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(shareBtn.getVisibility()).isEqualTo(View.GONE);
-        assertThat(cancelBtn.getVisibility()).isEqualTo(View.GONE);
+        assertThat(positiveBtn.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(positiveBtn.getText().toString())
+                .isEqualTo(mParent.getString(R.string.audio_sharing_pair_button_label));
+        assertThat(negativeBtn.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(negativeBtn.getText().toString())
+                .isEqualTo(mParent.getString(R.string.audio_sharing_qrcode_button_label));
     }
 
     @Test
-    public void onCreateDialog_noConnectedDevice_dialogDismiss() {
+    public void onCreateDialog_noExtraConnectedDevice_pairNewDevice() {
         mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
         AudioSharingDialogFragment.show(
                 mParent, new ArrayList<>(), EMPTY_EVENT_LISTENER, TEST_EVENT_DATA_LIST);
         shadowMainLooper().idle();
         AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
         assertThat(dialog).isNotNull();
-        View btnView = dialog.findViewById(android.R.id.button2);
-        assertThat(btnView).isNotNull();
-        btnView.performClick();
+        Button pairBtn = dialog.findViewById(R.id.positive_btn);
+        assertThat(pairBtn).isNotNull();
+        pairBtn.performClick();
         shadowMainLooper().idle();
 
+        verify(mFeatureFactory.metricsFeatureProvider)
+                .action(
+                        any(Context.class),
+                        eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_POSITIVE_BTN_CLICKED),
+                        eq(TEST_EVENT_DATA));
         assertThat(dialog.isShowing()).isFalse();
+    }
+
+    @Test
+    public void onCreateDialog_noExtraConnectedDevice_showQRCode() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
+        AudioSharingDialogFragment.show(
+                mParent, new ArrayList<>(), EMPTY_EVENT_LISTENER, TEST_EVENT_DATA_LIST);
+        shadowMainLooper().idle();
+        AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+        assertThat(dialog).isNotNull();
+        Button qrCodeBtn = dialog.findViewById(R.id.negative_btn);
+        assertThat(qrCodeBtn).isNotNull();
+        qrCodeBtn.performClick();
+        shadowMainLooper().idle();
+
         verify(mFeatureFactory.metricsFeatureProvider)
                 .action(
                         any(Context.class),
                         eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_NEGATIVE_BTN_CLICKED),
                         eq(TEST_EVENT_DATA));
+        assertThat(dialog.isShowing()).isFalse();
     }
 
     @Test
-    public void onCreateDialog_flagOn_singleConnectedDevice() {
+    public void onCreateDialog_flagOn_singleExtraConnectedDevice() {
         mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
         ArrayList<AudioSharingDeviceItem> list = new ArrayList<>();
         list.add(TEST_DEVICE_ITEM1);
@@ -207,10 +231,10 @@
         assertThat(description).isNotNull();
         ImageView image = dialog.findViewById(R.id.description_image);
         assertThat(image).isNotNull();
-        Button shareBtn = dialog.findViewById(R.id.positive_btn);
-        assertThat(shareBtn).isNotNull();
-        Button cancelBtn = dialog.findViewById(R.id.negative_btn);
-        assertThat(cancelBtn).isNotNull();
+        Button positiveBtn = dialog.findViewById(R.id.positive_btn);
+        assertThat(positiveBtn).isNotNull();
+        Button negativeBtn = dialog.findViewById(R.id.negative_btn);
+        assertThat(negativeBtn).isNotNull();
         assertThat(dialog.isShowing()).isTrue();
         assertThat(title.getText().toString())
                 .isEqualTo(
@@ -220,12 +244,16 @@
         assertThat(description.getText().toString())
                 .isEqualTo(mParent.getString(R.string.audio_sharing_dialog_share_content));
         assertThat(image.getVisibility()).isEqualTo(View.GONE);
-        assertThat(shareBtn.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(cancelBtn.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(positiveBtn.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(positiveBtn.getText().toString())
+                .isEqualTo(mParent.getString(R.string.audio_sharing_share_button_label));
+        assertThat(negativeBtn.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(negativeBtn.getText().toString())
+                .isEqualTo(mParent.getString(R.string.audio_sharing_no_thanks_button_label));
     }
 
     @Test
-    public void onCreateDialog_singleConnectedDevice_dialogDismiss() {
+    public void onCreateDialog_singleExtraConnectedDevice_dialogDismiss() {
         mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
         ArrayList<AudioSharingDeviceItem> list = new ArrayList<>();
         list.add(TEST_DEVICE_ITEM1);
@@ -248,7 +276,7 @@
     }
 
     @Test
-    public void onCreateDialog_singleConnectedDevice_shareClicked() {
+    public void onCreateDialog_singleExtraConnectedDevice_shareClicked() {
         mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
         ArrayList<AudioSharingDeviceItem> list = new ArrayList<>();
         list.add(TEST_DEVICE_ITEM1);
@@ -285,7 +313,7 @@
     }
 
     @Test
-    public void onCreateDialog_flagOn_multipleConnectedDevice() {
+    public void onCreateDialog_flagOn_multipleExtraConnectedDevice() {
         mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
         ArrayList<AudioSharingDeviceItem> list = new ArrayList<>();
         list.add(TEST_DEVICE_ITEM1);
@@ -313,12 +341,14 @@
         assertThat(image.getVisibility()).isEqualTo(View.GONE);
         assertThat(shareBtn.getVisibility()).isEqualTo(View.GONE);
         assertThat(cancelBtn.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(cancelBtn.getText().toString())
+                .isEqualTo(mParent.getString(com.android.settings.R.string.cancel));
         assertThat(recyclerView.getVisibility()).isEqualTo(View.VISIBLE);
         assertThat(recyclerView.getAdapter().getItemCount()).isEqualTo(3);
     }
 
     @Test
-    public void onCreateDialog_multipleConnectedDevice_dialogDismiss() {
+    public void onCreateDialog_multipleExtraConnectedDevice_dialogDismiss() {
         mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
         ArrayList<AudioSharingDeviceItem> list = new ArrayList<>();
         list.add(TEST_DEVICE_ITEM1);
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingReceiverTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingReceiverTest.java
index deed229..db6eb8c 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingReceiverTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingReceiverTest.java
@@ -25,7 +25,7 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoInteractions;
 import static org.mockito.Mockito.when;
@@ -164,8 +164,7 @@
         AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent);
         audioSharingReceiver.onReceive(mContext, intent);
 
-        verify(mNm, times(1))
-                .notify(eq(R.drawable.ic_bt_le_audio_sharing), any(Notification.class));
+        verify(mNm).notify(eq(R.drawable.ic_bt_le_audio_sharing), any(Notification.class));
         verify(mFeatureFactory.metricsFeatureProvider)
                 .action(mContext, SettingsEnums.ACTION_SHOW_AUDIO_SHARING_NOTIFICATION);
     }
@@ -181,7 +180,7 @@
         AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent);
         audioSharingReceiver.onReceive(mContext, intent);
 
-        verify(mNm, times(1)).cancel(R.drawable.ic_bt_le_audio_sharing);
+        verify(mNm).cancel(R.drawable.ic_bt_le_audio_sharing);
         verify(mFeatureFactory.metricsFeatureProvider)
                 .action(mContext, SettingsEnums.ACTION_CANCEL_AUDIO_SHARING_NOTIFICATION);
     }
@@ -199,8 +198,10 @@
     }
 
     @Test
-    public void broadcastReceiver_receiveAudioSharingStopIntent_stopBroadcast() {
+    public void
+            broadcastReceiver_receiveAudioSharingStopIntent_notInBroadcast_cancelNotification() {
         mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
+        when(mBroadcast.isEnabled(null)).thenReturn(false);
         int broadcastId = 1;
         when(mBroadcast.getLatestBroadcastId()).thenReturn(broadcastId);
 
@@ -209,7 +210,25 @@
         AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent);
         audioSharingReceiver.onReceive(mContext, intent);
 
-        verify(mBroadcast, times(1)).stopBroadcast(broadcastId);
+        verify(mBroadcast, never()).stopBroadcast(broadcastId);
+        verify(mNm).cancel(R.drawable.ic_bt_le_audio_sharing);
+        verify(mFeatureFactory.metricsFeatureProvider)
+                .action(mContext, SettingsEnums.ACTION_CANCEL_AUDIO_SHARING_NOTIFICATION);
+    }
+
+    @Test
+    public void broadcastReceiver_receiveAudioSharingStopIntent_inBroadcast_stopBroadcast() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
+        when(mBroadcast.isEnabled(null)).thenReturn(true);
+        int broadcastId = 1;
+        when(mBroadcast.getLatestBroadcastId()).thenReturn(broadcastId);
+
+        Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_STOP);
+        intent.setPackage(mContext.getPackageName());
+        AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent);
+        audioSharingReceiver.onReceive(mContext, intent);
+
+        verify(mBroadcast).stopBroadcast(broadcastId);
         verify(mFeatureFactory.metricsFeatureProvider)
                 .action(mContext, SettingsEnums.ACTION_STOP_AUDIO_SHARING_FROM_NOTIFICATION);
     }
diff --git a/tests/robotests/src/com/android/settings/notification/app/AppChannelsBypassingDndPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/AppChannelsBypassingDndPreferenceControllerTest.java
index b8c9b5b..e0381f2 100644
--- a/tests/robotests/src/com/android/settings/notification/app/AppChannelsBypassingDndPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/app/AppChannelsBypassingDndPreferenceControllerTest.java
@@ -50,6 +50,7 @@
 import org.robolectric.shadows.ShadowPausedAsyncTask;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 
 @RunWith(RobolectricTestRunner.class)
@@ -185,12 +186,7 @@
                 NotificationManager.IMPORTANCE_DEFAULT));
 
         ParceledListSlice<NotificationChannelGroup> groups = new ParceledListSlice<>(
-                new ArrayList<NotificationChannelGroup>() {
-                    {
-                        add(group1);
-                        add(group2);
-                    }
-                }
+                Arrays.asList(group1, group2)
         );
 
         when(mBackend.getGroups(eq(mAppRow.pkg), eq(mAppRow.uid))).thenReturn(groups);
diff --git a/tests/robotests/src/com/android/settings/testutils/AccessibilityTestUtils.java b/tests/robotests/src/com/android/settings/testutils/AccessibilityTestUtils.java
index 5d895d9..4d69821 100644
--- a/tests/robotests/src/com/android/settings/testutils/AccessibilityTestUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/AccessibilityTestUtils.java
@@ -20,6 +20,8 @@
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
@@ -46,20 +48,15 @@
 
     public static void setSoftwareShortcutMode(
             Context context, boolean gestureNavEnabled, boolean floatingButtonEnabled) {
-        int mode = floatingButtonEnabled ? ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU : -1;
+        int buttonMode = floatingButtonEnabled ? ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU : -1;
+        int navMode = gestureNavEnabled ? NAV_BAR_MODE_GESTURAL : NAV_BAR_MODE_3BUTTON;
 
         Settings.Secure.putInt(context.getContentResolver(),
-                Settings.Secure.ACCESSIBILITY_BUTTON_MODE, mode);
-
-        if (gestureNavEnabled) {
-            SettingsShadowResources.overrideResource(
-                    com.android.internal.R.integer.config_navBarInteractionMode,
-                    NAV_BAR_MODE_GESTURAL);
-        } else {
-            SettingsShadowResources.overrideResource(
-                    com.android.internal.R.integer.config_navBarInteractionMode,
-                    NAV_BAR_MODE_3BUTTON);
-        }
+                Settings.Secure.ACCESSIBILITY_BUTTON_MODE, buttonMode);
+        SettingsShadowResources.overrideResource(
+                com.android.internal.R.integer.config_navBarInteractionMode, navMode);
+        assertThat(context.getResources().getInteger(
+                com.android.internal.R.integer.config_navBarInteractionMode)).isEqualTo(navMode);
     }
 
     /**
diff --git a/tests/spa_unit/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerHelperTest.kt b/tests/spa_unit/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerHelperTest.kt
new file mode 100644
index 0000000..8edc90f
--- /dev/null
+++ b/tests/spa_unit/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerHelperTest.kt
@@ -0,0 +1,96 @@
+/*
+ * 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.telephony.CarrierConfigManager
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.spy
+
+@RunWith(AndroidJUnit4::class)
+class EnabledNetworkModePreferenceControllerHelperTest {
+
+    private var context: Context = spy(ApplicationProvider.getApplicationContext()) {}
+
+    @Before
+    fun setUp() {
+        CarrierConfigRepository.resetForTest()
+        CarrierConfigRepository.setBooleanForTest(
+            SUB_ID, CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true)
+    }
+
+    @Test
+    fun getNetworkModePreferenceType_hideCarrierNetworkSettings_returnNone() {
+        CarrierConfigRepository.setBooleanForTest(
+            SUB_ID, CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL, true)
+
+        val networkModePreferenceType = getNetworkModePreferenceType(context, SUB_ID)
+
+        assertThat(networkModePreferenceType).isEqualTo(NetworkModePreferenceType.None)
+    }
+
+    @Test
+    fun getNetworkModePreferenceType_hidePreferredNetworkType_returnNone() {
+        CarrierConfigRepository.setBooleanForTest(
+            SUB_ID, CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL, true)
+
+        val networkModePreferenceType = getNetworkModePreferenceType(context, SUB_ID)
+
+        assertThat(networkModePreferenceType).isEqualTo(NetworkModePreferenceType.None)
+    }
+
+    @Test
+    fun getNetworkModePreferenceType_carrierConfigNotReady_returnNone() {
+        CarrierConfigRepository.setBooleanForTest(
+            SUB_ID, CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, false)
+
+        val networkModePreferenceType = getNetworkModePreferenceType(context, SUB_ID)
+
+        assertThat(networkModePreferenceType).isEqualTo(NetworkModePreferenceType.None)
+    }
+
+    @Test
+    fun getNetworkModePreferenceType_isWorldPhone_returnPreferredNetworkMode() {
+        CarrierConfigRepository.setBooleanForTest(
+            SUB_ID, CarrierConfigManager.KEY_WORLD_PHONE_BOOL, true)
+
+        val networkModePreferenceType = getNetworkModePreferenceType(context, SUB_ID)
+
+        assertThat(networkModePreferenceType)
+            .isEqualTo(NetworkModePreferenceType.PreferredNetworkMode)
+    }
+
+    @Test
+    fun getNetworkModePreferenceType_notWorldPhone_returnEnabledNetworkMode() {
+        CarrierConfigRepository.setBooleanForTest(
+            SUB_ID, CarrierConfigManager.KEY_WORLD_PHONE_BOOL, false)
+
+        val networkModePreferenceType = getNetworkModePreferenceType(context, SUB_ID)
+
+        assertThat(networkModePreferenceType)
+            .isEqualTo(NetworkModePreferenceType.EnabledNetworkMode)
+    }
+
+    private companion object {
+        const val SUB_ID = 10
+    }
+}
diff --git a/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndexTest.kt b/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndexTest.kt
index 5e7e83c..bf51208 100644
--- a/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndexTest.kt
+++ b/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndexTest.kt
@@ -25,6 +25,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import com.android.settings.R
 import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.Companion.isMobileNetworkSettingsSearchable
+import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchResult
 import com.android.settings.spa.SpaSearchLanding.BundleValue
 import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingFragment
 import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingKey
@@ -62,10 +63,12 @@
     private val mobileNetworkSettingsSearchIndex = MobileNetworkSettingsSearchIndex {
         listOf(
             object : MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchItem {
-                override val key = KEY
-                override val title = TITLE
-
-                override fun isAvailable(subId: Int) = subId == SUB_ID_1
+                override fun getSearchResult(subId: Int): MobileNetworkSettingsSearchResult? =
+                    if (subId == SUB_ID_1) {
+                        MobileNetworkSettingsSearchResult(key = KEY, title = TITLE)
+                    } else {
+                        null
+                    }
             })
     }
 
diff --git a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppNotificationPreferenceTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppNotificationPreferenceTest.kt
index 37f3a11..7a0ec8c 100644
--- a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppNotificationPreferenceTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppNotificationPreferenceTest.kt
@@ -20,8 +20,8 @@
 import android.content.pm.ApplicationInfo
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.test.assertIsDisplayed
 import androidx.compose.ui.test.assertIsNotEnabled
+import androidx.compose.ui.test.hasText
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithText
 import androidx.compose.ui.test.onRoot
@@ -34,36 +34,35 @@
 import com.android.settings.notification.app.AppNotificationSettings
 import com.android.settings.spa.notification.IAppNotificationRepository
 import com.android.settingslib.spa.testutils.delay
+import com.android.settingslib.spa.testutils.waitUntilExists
 import org.junit.After
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.MockitoSession
-import org.mockito.Spy
 import org.mockito.quality.Strictness
 
 @RunWith(AndroidJUnit4::class)
 class AppNotificationPreferenceTest {
-    @get:Rule
-    val composeTestRule = createComposeRule()
+    @get:Rule val composeTestRule = createComposeRule()
 
     private lateinit var mockSession: MockitoSession
 
-    @Spy
     private val context: Context = ApplicationProvider.getApplicationContext()
 
-    private val repository = object : IAppNotificationRepository {
-        override fun getNotificationSummary(app: ApplicationInfo) = SUMMARY
-    }
+    private val repository =
+        object : IAppNotificationRepository {
+            override fun getNotificationSummary(app: ApplicationInfo) = SUMMARY
+        }
 
     @Before
     fun setUp() {
-        mockSession = ExtendedMockito.mockitoSession()
-            .initMocks(this)
-            .mockStatic(AppInfoDashboardFragment::class.java)
-            .strictness(Strictness.LENIENT)
-            .startMocking()
+        mockSession =
+            ExtendedMockito.mockitoSession()
+                .mockStatic(AppInfoDashboardFragment::class.java)
+                .strictness(Strictness.LENIENT)
+                .startMocking()
     }
 
     @After
@@ -75,25 +74,26 @@
     fun title_displayed() {
         setContent(APP)
 
-        composeTestRule.onNodeWithText(context.getString(R.string.notifications_label))
-            .assertIsDisplayed()
+        composeTestRule.waitUntilExists(hasText(context.getString(R.string.notifications_label)))
     }
 
     @Test
     fun summary_displayed() {
         setContent(APP)
 
-        composeTestRule.onNodeWithText(SUMMARY).assertIsDisplayed()
+        composeTestRule.waitUntilExists(hasText(SUMMARY))
     }
 
     @Test
     fun whenNotInstalled_disable() {
-        setContent(ApplicationInfo().apply {
-            packageName = PACKAGE_NAME
-            uid = UID
-        })
+        setContent(
+            ApplicationInfo().apply {
+                packageName = PACKAGE_NAME
+                uid = UID
+            })
 
-        composeTestRule.onNodeWithText(context.getString(R.string.notifications_label))
+        composeTestRule
+            .onNodeWithText(context.getString(R.string.notifications_label))
             .assertIsNotEnabled()
     }
 
@@ -125,11 +125,12 @@
     private companion object {
         const val PACKAGE_NAME = "package.name"
         const val UID = 123
-        val APP = ApplicationInfo().apply {
-            packageName = PACKAGE_NAME
-            uid = UID
-            flags = ApplicationInfo.FLAG_INSTALLED
-        }
+        val APP =
+            ApplicationInfo().apply {
+                packageName = PACKAGE_NAME
+                uid = UID
+                flags = ApplicationInfo.FLAG_INSTALLED
+            }
         const val SUMMARY = "Summary"
     }
-}
\ No newline at end of file
+}
diff --git a/tests/unit/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerTest.java
index b3d095e..adc8dc0 100644
--- a/tests/unit/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerTest.java
@@ -18,9 +18,6 @@
 
 import static androidx.lifecycle.Lifecycle.Event.ON_START;
 
-import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
-import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
 import static com.android.settings.network.telephony.MobileNetworkUtils.getRafFromNetworkType;
 import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.CDMA;
 import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.EVDO;
@@ -33,8 +30,6 @@
 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.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
@@ -125,79 +120,6 @@
 
     @UiThreadTest
     @Test
-    public void getAvailabilityStatus_hideCarrierNetworkSettings_returnUnavailable() {
-        mPersistableBundle.putBoolean(
-                CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL,
-                true);
-
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
-    }
-
-    @UiThreadTest
-    @Test
-    public void getAvailabilityStatus_hidePreferredNetworkType_returnUnavailable() {
-        mPersistableBundle.putBoolean(CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL,
-                true);
-
-        when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
-        when(mServiceState.getDataRegistrationState()).thenReturn(
-                ServiceState.STATE_OUT_OF_SERVICE);
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
-
-        when(mServiceState.getState()).thenReturn(ServiceState.STATE_IN_SERVICE);
-        when(mServiceState.getDataRegistrationState()).thenReturn(ServiceState.STATE_IN_SERVICE);
-
-        when(mServiceState.getRoaming()).thenReturn(false);
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
-
-        when(mServiceState.getRoaming()).thenReturn(true);
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
-    }
-
-    @UiThreadTest
-    @Test
-    public void getAvailabilityStatus_carrierConfigNotReady_returnUnavailable() {
-        mPersistableBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, false);
-
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
-    }
-
-    @UiThreadTest
-    @Test
-    public void getAvailabilityStatus_notWorldPhone_returnAvailable() {
-        mPersistableBundle.putBoolean(CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL,
-                false);
-        mPersistableBundle.putBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL, false);
-
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
-    }
-
-    @UiThreadTest
-    @Test
-    public void getAvailabilityStatus_callStateIsIdle_returnAvailable() {
-        mockEnabledNetworkMode(TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA);
-        mController.getTelephonyCallback().onCallStateChanged(TelephonyManager.CALL_STATE_IDLE);
-
-        mController.updateState(mPreference);
-
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
-        assertTrue(mPreference.isEnabled());
-    }
-
-    @UiThreadTest
-    @Test
-    public void getAvailabilityStatus_duringCalling_returnAvailable() {
-        mockEnabledNetworkMode(TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA);
-        mController.getTelephonyCallback().onCallStateChanged(TelephonyManager.CALL_STATE_OFFHOOK);
-
-        mController.updateState(mPreference);
-
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
-        assertFalse(mPreference.isEnabled());
-    }
-
-    @UiThreadTest
-    @Test
     public void updateState_LteWorldPhone_GlobalHasLte() {
         mPersistableBundle.putBoolean(CarrierConfigManager.KEY_WORLD_MODE_ENABLED_BOOL, true);
 
diff --git a/tests/unit/src/com/android/settings/network/telephony/PreferredNetworkModePreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/PreferredNetworkModePreferenceControllerTest.java
index 9dbfdde..f22ad3b 100644
--- a/tests/unit/src/com/android/settings/network/telephony/PreferredNetworkModePreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/network/telephony/PreferredNetworkModePreferenceControllerTest.java
@@ -16,8 +16,6 @@
 
 package com.android.settings.network.telephony;
 
-import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
 import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.GSM;
 import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.RAF_TD_SCDMA;
 import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.WCDMA;
@@ -32,7 +30,6 @@
 
 import android.content.Context;
 import android.os.PersistableBundle;
-import android.telephony.CarrierConfigManager;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -92,43 +89,6 @@
     }
 
     @Test
-    public void getAvailabilityStatus_hideCarrierNetworkSettings_returnUnavailable() {
-        mPersistableBundle.putBoolean(CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL,
-                true);
-
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
-    }
-
-    @Test
-    public void getAvailabilityStatus_worldPhone_returnAvailable() {
-        mPersistableBundle.putBoolean(CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL,
-                false);
-        mPersistableBundle.putBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL, true);
-
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
-    }
-
-    @Test
-    public void getAvailabilityStatus_hidePreferredNetworkType_returnUnavailable() {
-        mPersistableBundle.putBoolean(CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL,
-                true);
-
-        when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
-        when(mServiceState.getDataRegistrationState()).thenReturn(
-                ServiceState.STATE_OUT_OF_SERVICE);
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
-
-        when(mServiceState.getState()).thenReturn(ServiceState.STATE_IN_SERVICE);
-        when(mServiceState.getDataRegistrationState()).thenReturn(ServiceState.STATE_IN_SERVICE);
-
-        when(mServiceState.getRoaming()).thenReturn(false);
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
-
-        when(mServiceState.getRoaming()).thenReturn(true);
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
-    }
-
-    @Test
     public void updateState_updateByNetworkMode() {
         // NETWORK_MODE_TDSCDMA_GSM_WCDMA = RAF_TD_SCDMA | GSM | WCDMA
         when(mTelephonyManager.getAllowedNetworkTypesForReason(