Merge "Hide new Hotspot preferences if feature is disabled" into main
diff --git a/res/drawable/battery_tips_all_rounded_bg.xml b/res/drawable/battery_tips_all_rounded_bg.xml
deleted file mode 100644
index ba164b9..0000000
--- a/res/drawable/battery_tips_all_rounded_bg.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2023 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <solid android:color="@color/settingslib_materialColorSurfaceBright" />
-    <corners android:radius="@dimen/battery_tips_card_corner_radius_normal" />
-</shape>
\ No newline at end of file
diff --git a/res/drawable/battery_tips_all_rounded_bg_ripple.xml b/res/drawable/battery_tips_all_rounded_bg_ripple.xml
deleted file mode 100644
index 3180570..0000000
--- a/res/drawable/battery_tips_all_rounded_bg_ripple.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2023 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
-    android:color="?android:attr/colorControlHighlight">
-    <item android:drawable="@drawable/battery_tips_all_rounded_bg"/>
-</ripple>
\ No newline at end of file
diff --git a/res/drawable/battery_tips_half_rounded_bottom_bg.xml b/res/drawable/battery_tips_half_rounded_bottom_bg.xml
deleted file mode 100644
index 7766de6..0000000
--- a/res/drawable/battery_tips_half_rounded_bottom_bg.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2023 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <solid android:color="@color/settingslib_dialog_background"/>
-    <corners
-        android:topLeftRadius="@dimen/battery_tips_card_corner_radius_small"
-        android:topRightRadius="@dimen/battery_tips_card_corner_radius_small"
-        android:bottomLeftRadius="@dimen/battery_tips_card_corner_radius_normal"
-        android:bottomRightRadius="@dimen/battery_tips_card_corner_radius_normal"
-        />
-</shape>
\ No newline at end of file
diff --git a/res/drawable/battery_tips_half_rounded_top_bg.xml b/res/drawable/battery_tips_half_rounded_top_bg.xml
deleted file mode 100644
index aba1a4f..0000000
--- a/res/drawable/battery_tips_half_rounded_top_bg.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2023 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <solid android:color="@color/settingslib_dialog_background"/>
-    <corners
-        android:topLeftRadius="@dimen/battery_tips_card_corner_radius_normal"
-        android:topRightRadius="@dimen/battery_tips_card_corner_radius_normal"
-        android:bottomLeftRadius="@dimen/battery_tips_card_corner_radius_small"
-        android:bottomRightRadius="@dimen/battery_tips_card_corner_radius_small"
-        />
-</shape>
\ No newline at end of file
diff --git a/res/layout/battery_tips_card.xml b/res/layout/battery_tips_card.xml
deleted file mode 100644
index 18c326f..0000000
--- a/res/layout/battery_tips_card.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/battery_tips_card"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:layout_marginStart="?android:attr/listPreferredItemPaddingStart"
-    android:layout_marginEnd="?android:attr/listPreferredItemPaddingEnd"
-    android:background="@drawable/battery_tips_all_rounded_bg_ripple"
-    android:orientation="vertical"
-    android:padding="20dp">
-
-    <ImageView
-        android:id="@+id/icon"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center_vertical|start"
-        android:contentDescription="@string/battery_usage_anomaly_content_description"
-        android:src="@drawable/ic_battery_tips_lightbulb" />
-
-    <TextView
-        android:id="@+id/title"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="8dp"
-        android:textAlignment="viewStart"
-        android:textAppearance="@style/TextAppearance.Material3.TitleMedium"
-        android:textColor="@color/settingslib_materialColorOnSurface" />
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="8dp"
-        android:gravity="end"
-        android:orientation="horizontal">
-
-        <com.google.android.material.button.MaterialButton
-            android:id="@+id/dismiss_button"
-            style="@style/Widget.Material3.Button.TextButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="end|center_vertical"
-            android:layout_marginEnd="8dp"
-            android:paddingHorizontal="16dp"
-            android:text="@string/battery_tips_card_dismiss_button"
-            android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle2"
-            android:textColor="@color/color_accent_selector" />
-
-        <com.google.android.material.button.MaterialButton
-            android:id="@+id/main_button"
-            style="@style/Widget.Material3.Button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="end|center_vertical"
-            android:paddingHorizontal="16dp"
-            android:text="@string/battery_tips_card_action_button"
-            android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle2"
-            android:textColor="@color/settingslib_materialColorOnPrimary"
-            app:backgroundTint="@color/color_accent_selector" />
-    </LinearLayout>
-</LinearLayout>
\ No newline at end of file
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/res/xml/power_usage_advanced.xml b/res/xml/power_usage_advanced.xml
index c129453..f0104e5 100644
--- a/res/xml/power_usage_advanced.xml
+++ b/res/xml/power_usage_advanced.xml
@@ -27,7 +27,7 @@
             "com.android.settings.fuelgauge.batteryusage.BatteryTipsController"
         settings:isPreferenceVisible="false">
 
-        <com.android.settings.fuelgauge.batteryusage.BatteryTipsCardPreference
+        <com.android.settings.widget.TipCardPreference
             android:key="battery_tips_card"
             settings:isPreferenceVisible="false" />
 
diff --git a/src/com/android/settings/accessibility/ScreenFlashNotificationColorDialogFragment.java b/src/com/android/settings/accessibility/ScreenFlashNotificationColorDialogFragment.java
index 5094154..2be843c 100644
--- a/src/com/android/settings/accessibility/ScreenFlashNotificationColorDialogFragment.java
+++ b/src/com/android/settings/accessibility/ScreenFlashNotificationColorDialogFragment.java
@@ -28,11 +28,13 @@
 import android.graphics.Color;
 import android.os.Bundle;
 import android.os.UserHandle;
+import android.provider.Settings;
 import android.view.View;
 
 import androidx.annotation.ColorInt;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
 import androidx.appcompat.app.AlertDialog;
 import androidx.fragment.app.DialogFragment;
 
@@ -40,8 +42,6 @@
 
 import java.util.Timer;
 import java.util.TimerTask;
-import java.util.function.Consumer;
-
 
 /**
  * DialogFragment for Screen flash notification color picker.
@@ -49,29 +49,33 @@
 public class ScreenFlashNotificationColorDialogFragment extends DialogFragment implements
         ColorSelectorLayout.OnCheckedChangeListener {
 
+    private static final int DEFAULT_COLOR = Color.TRANSPARENT;
     private static final int PREVIEW_LONG_TIME_MS = 5000;
     private static final int BETWEEN_STOP_AND_START_DELAY_MS = 250;
     private static final int MARGIN_FOR_STOP_DELAY_MS = 100;
 
+    @VisibleForTesting
+    static final String EXTRA_COLOR = "extra_color";
     @ColorInt
-    private int mCurrentColor = Color.TRANSPARENT;
-    private Consumer<Integer> mConsumer;
+    private int mCurrentColor = DEFAULT_COLOR;
 
     private Timer mTimer = null;
     private Boolean mIsPreview = false;
 
-    static ScreenFlashNotificationColorDialogFragment getInstance(int initialColor,
-            Consumer<Integer> colorConsumer) {
+    static ScreenFlashNotificationColorDialogFragment getInstance(int initialColor) {
         final ScreenFlashNotificationColorDialogFragment result =
                 new ScreenFlashNotificationColorDialogFragment();
-        result.mCurrentColor = initialColor;
-        result.mConsumer = colorConsumer != null ? colorConsumer : i -> {};
+        Bundle bundle = new Bundle();
+        bundle.putInt(EXTRA_COLOR, initialColor);
+        result.setArguments(bundle);
         return result;
     }
 
     @NonNull
     @Override
     public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+        mCurrentColor = getArguments().getInt(EXTRA_COLOR, DEFAULT_COLOR);
+
         final View dialogView = getLayoutInflater().inflate(R.layout.layout_color_selector_dialog,
                 null);
 
@@ -90,7 +94,8 @@
                 })
                 .setPositiveButton(R.string.color_selector_dialog_save, (dialog, which) -> {
                     mCurrentColor = colorSelectorLayout.getCheckedColor(DEFAULT_SCREEN_FLASH_COLOR);
-                    mConsumer.accept(mCurrentColor);
+                    Settings.System.putInt(getContext().getContentResolver(),
+                            Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR, mCurrentColor);
                 })
                 .create();
         createdDialog.setOnShowListener(
diff --git a/src/com/android/settings/accessibility/ScreenFlashNotificationPreferenceController.java b/src/com/android/settings/accessibility/ScreenFlashNotificationPreferenceController.java
index bd54aca..3ebcd1c 100644
--- a/src/com/android/settings/accessibility/ScreenFlashNotificationPreferenceController.java
+++ b/src/com/android/settings/accessibility/ScreenFlashNotificationPreferenceController.java
@@ -21,10 +21,17 @@
 import static com.android.settings.accessibility.FlashNotificationsUtil.DEFAULT_SCREEN_FLASH_COLOR;
 
 import android.content.Context;
+import android.database.ContentObserver;
 import android.graphics.Color;
+import android.net.Uri;
+import android.os.Handler;
 import android.provider.Settings;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.fragment.app.Fragment;
+import androidx.lifecycle.DefaultLifecycleObserver;
+import androidx.lifecycle.LifecycleOwner;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 
@@ -32,18 +39,21 @@
 import com.android.settings.core.TogglePreferenceController;
 import com.android.settings.overlay.FeatureFactory;
 
-import java.util.function.Consumer;
-
 /**
  * Controller for Screen flash notification.
  */
-public class ScreenFlashNotificationPreferenceController extends TogglePreferenceController {
+public class ScreenFlashNotificationPreferenceController extends
+        TogglePreferenceController implements DefaultLifecycleObserver {
+
+    private final FlashNotificationColorContentObserver mFlashNotificationColorContentObserver;
 
     private Fragment mParentFragment;
     private Preference mPreference;
 
     public ScreenFlashNotificationPreferenceController(Context context, String preferenceKey) {
         super(context, preferenceKey);
+        mFlashNotificationColorContentObserver = new FlashNotificationColorContentObserver(
+                new Handler(mContext.getMainLooper()));
     }
 
     public void setParentFragment(Fragment parentFragment) {
@@ -51,6 +61,16 @@
     }
 
     @Override
+    public void onStart(@NonNull LifecycleOwner owner) {
+        mFlashNotificationColorContentObserver.register(mContext);
+    }
+
+    @Override
+    public void onStop(@NonNull LifecycleOwner owner) {
+        mFlashNotificationColorContentObserver.unregister(mContext);
+    }
+
+    @Override
     public int getAvailabilityStatus() {
         return AVAILABLE;
     }
@@ -100,14 +120,8 @@
                     Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR,
                     DEFAULT_SCREEN_FLASH_COLOR);
 
-            final Consumer<Integer> consumer = color -> {
-                Settings.System.putInt(mContext.getContentResolver(),
-                        Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR, color);
-                refreshColorSummary();
-            };
-
             ScreenFlashNotificationColorDialogFragment
-                    .getInstance(initialColor, consumer)
+                    .getInstance(initialColor)
                     .show(mParentFragment.getParentFragmentManager(),
                             ScreenFlashNotificationColorDialogFragment.class.getSimpleName());
             return true;
@@ -128,4 +142,37 @@
     private void refreshColorSummary() {
         if (mPreference != null) mPreference.setSummary(getSummary());
     }
+
+    private final class FlashNotificationColorContentObserver extends ContentObserver {
+        private final Uri mColorUri = Settings.System.getUriFor(
+                Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR);
+
+        FlashNotificationColorContentObserver(Handler handler) {
+            super(handler);
+        }
+
+        /**
+         * Register this observer to given {@link Context}, to be called from lifecycle
+         * {@code onStart} method.
+         */
+        public void register(@NonNull Context context) {
+            context.getContentResolver().registerContentObserver(
+                    mColorUri, /* notifyForDescendants= */ false, this);
+        }
+
+        /**
+         * Unregister this observer from given {@link Context}, to be called from lifecycle
+         * {@code onStop} method.
+         */
+        public void unregister(@NonNull Context context) {
+            context.getContentResolver().unregisterContentObserver(this);
+        }
+
+        @Override
+        public void onChange(boolean selfChange, @Nullable Uri uri) {
+            if (mColorUri.equals(uri)) {
+                refreshColorSummary();
+            }
+        }
+    }
 }
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/batteryusage/AnomalyEventWrapper.java b/src/com/android/settings/fuelgauge/batteryusage/AnomalyEventWrapper.java
index be5de06..c62728b 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/AnomalyEventWrapper.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/AnomalyEventWrapper.java
@@ -28,10 +28,11 @@
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.widget.TipCardPreference;
 
 import java.util.function.Function;
 
-final class AnomalyEventWrapper {
+class AnomalyEventWrapper {
     private static final String TAG = "AnomalyEventWrapper";
 
     private final Context mContext;
@@ -235,16 +236,16 @@
         return mHighlightSlotPair;
     }
 
-    boolean updateTipsCardPreference(BatteryTipsCardPreference preference) {
+    boolean updateTipsCardPreference(TipCardPreference preference) {
         final String titleString = getTitleString();
         if (TextUtils.isEmpty(titleString)) {
             return false;
         }
         preference.setTitle(titleString);
-        preference.setIconResourceId(getIconResId());
-        preference.setButtonColorResourceId(getColorResId());
-        preference.setMainButtonLabel(getMainBtnString());
-        preference.setDismissButtonLabel(getDismissBtnString());
+        preference.setIconResId(getIconResId());
+        preference.setTintColorResId(getColorResId());
+        preference.setPrimaryButtonText(getDismissBtnString());
+        preference.setSecondaryButtonText(getMainBtnString());
         return true;
     }
 
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java
deleted file mode 100644
index bbd1099..0000000
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.fuelgauge.batteryusage;
-
-import android.content.Context;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.settings.R;
-
-import com.google.android.material.button.MaterialButton;
-
-/** A preference for displaying the battery tips card view. */
-public class BatteryTipsCardPreference extends Preference implements View.OnClickListener {
-
-    private static final String TAG = "BatteryTipsCardPreference";
-
-    interface OnConfirmListener {
-        void onConfirm();
-    }
-
-    interface OnRejectListener {
-        void onReject();
-    }
-
-    private OnConfirmListener mOnConfirmListener;
-    private OnRejectListener mOnRejectListener;
-    private int mIconResourceId = 0;
-    private int mButtonColorResourceId = 0;
-
-    @VisibleForTesting CharSequence mMainButtonLabel;
-    @VisibleForTesting CharSequence mDismissButtonLabel;
-
-    public BatteryTipsCardPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        setLayoutResource(R.layout.battery_tips_card);
-        setViewId(R.id.battery_tips_card);
-        setSelectable(false);
-    }
-
-    public void setOnConfirmListener(OnConfirmListener listener) {
-        mOnConfirmListener = listener;
-    }
-
-    public void setOnRejectListener(OnRejectListener listener) {
-        mOnRejectListener = listener;
-    }
-
-    /**
-     * Sets the icon in tips card.
-     */
-    public void setIconResourceId(int resourceId) {
-        if (mIconResourceId != resourceId) {
-            mIconResourceId = resourceId;
-            notifyChanged();
-        }
-    }
-
-    /**
-     * Sets the background color for main button and the text color for dismiss button.
-     */
-    public void setButtonColorResourceId(int resourceId) {
-        if (mButtonColorResourceId != resourceId) {
-            mButtonColorResourceId = resourceId;
-            notifyChanged();
-        }
-    }
-
-    /**
-     * Sets the label of main button in tips card.
-     */
-    public void setMainButtonLabel(CharSequence label) {
-        if (!TextUtils.equals(mMainButtonLabel, label)) {
-            mMainButtonLabel = label;
-            notifyChanged();
-        }
-    }
-
-    /**
-     * Sets the label of dismiss button in tips card.
-     */
-    public void setDismissButtonLabel(CharSequence label) {
-        if (!TextUtils.equals(mDismissButtonLabel, label)) {
-            mDismissButtonLabel = label;
-            notifyChanged();
-        }
-    }
-
-    @Override
-    public void onClick(View view) {
-        final int viewId = view.getId();
-        if (viewId == R.id.main_button || viewId == R.id.battery_tips_card) {
-            if (mOnConfirmListener != null) {
-                mOnConfirmListener.onConfirm();
-            }
-        } else if (viewId == R.id.dismiss_button) {
-            if (mOnRejectListener != null) {
-                mOnRejectListener.onReject();
-            }
-        }
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder view) {
-        super.onBindViewHolder(view);
-
-        ((TextView) view.findViewById(R.id.title)).setText(getTitle());
-
-        final LinearLayout tipsCard = (LinearLayout) view.findViewById(R.id.battery_tips_card);
-        tipsCard.setOnClickListener(this);
-        final MaterialButton mainButton = (MaterialButton) view.findViewById(R.id.main_button);
-        mainButton.setOnClickListener(this);
-        mainButton.setText(mMainButtonLabel);
-        final MaterialButton dismissButton =
-                (MaterialButton) view.findViewById(R.id.dismiss_button);
-        dismissButton.setOnClickListener(this);
-        dismissButton.setText(mDismissButtonLabel);
-        if (mButtonColorResourceId != 0) {
-            final int colorInt = getContext().getColor(mButtonColorResourceId);
-            mainButton.setBackgroundColor(colorInt);
-            dismissButton.setTextColor(colorInt);
-        }
-
-        if (mIconResourceId != 0) {
-            ((ImageView) view.findViewById(R.id.icon)).setImageResource(mIconResourceId);
-        }
-    }
-}
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java
index 821c868..405b786 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java
@@ -25,6 +25,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.widget.TipCardPreference;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 /** Controls the update for battery tips card */
@@ -50,10 +51,9 @@
         void onAnomalyReject();
     }
 
-    private OnAnomalyConfirmListener mOnAnomalyConfirmListener;
-    private OnAnomalyRejectListener mOnAnomalyRejectListener;
-
-    @VisibleForTesting BatteryTipsCardPreference mCardPreference;
+    @VisibleForTesting OnAnomalyConfirmListener mOnAnomalyConfirmListener;
+    @VisibleForTesting OnAnomalyRejectListener mOnAnomalyRejectListener;
+    @VisibleForTesting TipCardPreference mCardPreference;
     @VisibleForTesting AnomalyEventWrapper mAnomalyEventWrapper = null;
     @VisibleForTesting Boolean mIsAcceptable = false;
 
@@ -117,42 +117,20 @@
             return;
         }
 
-        // Set battery tips card listener
-        mCardPreference.setOnConfirmListener(
+        mCardPreference.setPrimaryButtonAction(
                 () -> {
-                    mCardPreference.setVisible(false);
-                    if (mOnAnomalyConfirmListener != null) {
-                        mOnAnomalyConfirmListener.onAnomalyConfirm();
-                    } else if (mAnomalyEventWrapper.updateSystemSettingsIfAvailable()
-                            || mAnomalyEventWrapper.launchSubSetting()) {
-                        mMetricsFeatureProvider.action(
-                                /* attribution= */ SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                                /* action= */ SettingsEnums.ACTION_BATTERY_TIPS_CARD_ACCEPT,
-                                /* pageId= */ SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                                /* key= */ ANOMALY_KEY,
-                                /* value= */ anomalyKeyNumber);
-                    }
+                    onBatteryTipsCardDismiss(anomalyKeyNumber);
+                    return null;
                 });
-        mCardPreference.setOnRejectListener(
+        mCardPreference.setSecondaryButtonAction(
                 () -> {
-                    mCardPreference.setVisible(false);
-                    if (mOnAnomalyRejectListener != null) {
-                        mOnAnomalyRejectListener.onAnomalyReject();
-                    }
-                    // For anomaly events with same record key, dismissed until next time full
-                    // charged.
-                    final String dismissRecordKey = mAnomalyEventWrapper.getDismissRecordKey();
-                    if (!TextUtils.isEmpty(dismissRecordKey)) {
-                        DatabaseUtils.setDismissedPowerAnomalyKeys(mContext, dismissRecordKey);
-                    }
-                    mMetricsFeatureProvider.action(
-                            /* attribution= */ SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                            /* action= */ SettingsEnums.ACTION_BATTERY_TIPS_CARD_DISMISS,
-                            /* pageId= */ SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                            /* key= */ ANOMALY_KEY,
-                            /* value= */ anomalyKeyNumber);
+                    onBatteryTipsCardAccept(anomalyKeyNumber);
+                    return null;
                 });
 
+        mCardPreference.setPrimaryButtonVisibility(true);
+        mCardPreference.setSecondaryButtonVisibility(true);
+        mCardPreference.buildContent();
         mCardPreference.setVisible(true);
         mMetricsFeatureProvider.action(
                 /* attribution= */ SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
@@ -161,4 +139,37 @@
                 /* key= */ ANOMALY_KEY,
                 /* value= */ anomalyKeyNumber);
     }
+
+    private void onBatteryTipsCardDismiss(final int anomalyKeyNumber) {
+        mCardPreference.setVisible(false);
+        if (mOnAnomalyRejectListener != null) {
+            mOnAnomalyRejectListener.onAnomalyReject();
+        }
+        // For anomaly events with same record key, dismissed until next time full charged.
+        final String dismissRecordKey = mAnomalyEventWrapper.getDismissRecordKey();
+        if (!TextUtils.isEmpty(dismissRecordKey)) {
+            DatabaseUtils.setDismissedPowerAnomalyKeys(mContext, dismissRecordKey);
+        }
+        mMetricsFeatureProvider.action(
+                /* attribution= */ SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
+                /* action= */ SettingsEnums.ACTION_BATTERY_TIPS_CARD_DISMISS,
+                /* pageId= */ SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
+                /* key= */ ANOMALY_KEY,
+                /* value= */ anomalyKeyNumber);
+    }
+
+    private void onBatteryTipsCardAccept(final int anomalyKeyNumber) {
+        mCardPreference.setVisible(false);
+        if (mOnAnomalyConfirmListener != null) {
+            mOnAnomalyConfirmListener.onAnomalyConfirm();
+        } else if (mAnomalyEventWrapper.updateSystemSettingsIfAvailable()
+                || mAnomalyEventWrapper.launchSubSetting()) {
+            mMetricsFeatureProvider.action(
+                    /* attribution= */ SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
+                    /* action= */ SettingsEnums.ACTION_BATTERY_TIPS_CARD_ACCEPT,
+                    /* pageId= */ SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
+                    /* key= */ ANOMALY_KEY,
+                    /* value= */ anomalyKeyNumber);
+        }
+    }
 }
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/SubscriptionsPreferenceController.java b/src/com/android/settings/network/SubscriptionsPreferenceController.java
index b7ed31e..cdbf456 100644
--- a/src/com/android/settings/network/SubscriptionsPreferenceController.java
+++ b/src/com/android/settings/network/SubscriptionsPreferenceController.java
@@ -241,6 +241,8 @@
         if (mSubsGearPref == null) {
             mPreferenceGroup.removeAll();
             mSubsGearPref = new MutableGearPreference(mContext, null);
+            mSubsGearPref
+                    .checkRestrictionAndSetDisabled(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
             mSubsGearPref.setOnPreferenceClickListener(preference -> {
                 connectCarrierNetwork();
                 return true;
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/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
index ee1485e..acf674f 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -202,6 +202,11 @@
     @Override
     public void onAttach(Context context) {
         super.onAttach(context);
+        if (isUiRestricted()) {
+            Log.d(LOG_TAG, "Mobile network page is disallowed.");
+            finish();
+            return;
+        }
 
         if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
             Log.d(LOG_TAG, "Invalid subId, get the default subscription to show.");
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/system/reset/ResetNetworkConfirm.kt b/src/com/android/settings/system/reset/ResetNetworkConfirm.kt
index 34b9909..e040356 100644
--- a/src/com/android/settings/system/reset/ResetNetworkConfirm.kt
+++ b/src/com/android/settings/system/reset/ResetNetworkConfirm.kt
@@ -18,6 +18,7 @@
 
 import android.app.ProgressDialog
 import android.app.settings.SettingsEnums
+import android.content.DialogInterface
 import android.os.Bundle
 import android.os.Looper
 import android.telephony.SubscriptionManager
@@ -56,7 +57,8 @@
  * This is the confirmation screen.
  */
 class ResetNetworkConfirm : InstrumentedFragment() {
-    @VisibleForTesting lateinit var resetNetworkRequest: ResetNetworkRequest
+    @VisibleForTesting
+    lateinit var resetNetworkRequest: ResetNetworkRequest
     private var progressDialog: ProgressDialog? = null
     private var alertDialog: AlertDialog? = null
     private var resetStarted = false
@@ -87,10 +89,7 @@
     /** Configure the UI for the final confirmation interaction */
     private fun View.establishFinalConfirmationState() {
         requireViewById<View>(R.id.execute_reset_network).setOnClickListener {
-            if (!Utils.isMonkeyRunning() && !resetStarted) {
-                resetStarted = true
-                viewLifecycleOwner.lifecycleScope.launch { onResetClicked() }
-            }
+            showResetInternetDialog();
         }
     }
 
@@ -118,10 +117,10 @@
     private fun invalidSubIdFlow(): Flow<Int> {
         val subIdsInRequest =
             listOf(
-                    resetNetworkRequest.resetTelephonyAndNetworkPolicyManager,
-                    resetNetworkRequest.resetApnSubId,
-                    resetNetworkRequest.resetImsSubId,
-                )
+                resetNetworkRequest.resetTelephonyAndNetworkPolicyManager,
+                resetNetworkRequest.resetApnSubId,
+                resetNetworkRequest.resetImsSubId,
+            )
                 .distinct()
                 .filter(SubscriptionManager::isUsableSubscriptionId)
 
@@ -162,6 +161,24 @@
         }
     }
 
+    private fun showResetInternetDialog() {
+        val builder = AlertDialog.Builder(requireContext())
+        val resetInternetClickListener =
+            DialogInterface.OnClickListener { dialog, which ->
+                if (!Utils.isMonkeyRunning() && !resetStarted) {
+                    resetStarted = true
+                    viewLifecycleOwner.lifecycleScope.launch { onResetClicked() }
+                }
+            }
+
+        builder.setTitle(R.string.reset_your_internet_title)
+            .setMessage(R.string.reset_internet_text)
+            .setPositiveButton(R.string.tts_reset, resetInternetClickListener)
+            .setNegativeButton(android.R.string.cancel, null)
+            .create()
+            .show()
+    }
+
     /**
      * Do all reset task.
      *
@@ -173,7 +190,8 @@
         withContext(Dispatchers.Default) {
             val builder =
                 resetNetworkRequest.toResetNetworkOperationBuilder(
-                    requireContext(), Looper.getMainLooper())
+                    requireContext(), Looper.getMainLooper()
+                )
             resetNetworkRequest.resetEsimPackageName?.let { resetEsimPackageName ->
                 builder.resetEsim(resetEsimPackageName)
                 builder.resetEsimResultCallback { resetEsimSuccess = it }
@@ -199,8 +217,8 @@
         } else {
             Toast.makeText(activity, R.string.reset_network_complete_toast, Toast.LENGTH_SHORT)
                 .show()
+            activity.finish()
         }
-        activity.finish()
     }
 
     override fun onDestroy() {
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/widget/MutableGearPreference.java b/src/com/android/settings/widget/MutableGearPreference.java
index b0804eb..73491f0 100644
--- a/src/com/android/settings/widget/MutableGearPreference.java
+++ b/src/com/android/settings/widget/MutableGearPreference.java
@@ -41,11 +41,13 @@
 
     @Override
     public void setGearEnabled(boolean enabled) {
+        boolean state = false;
         if (mGear != null) {
-            mGear.setEnabled(enabled);
-            mGear.setImageAlpha(enabled ? VALUE_ENABLED_ALPHA : mDisabledAlphaValue);
+            state = enabled && !(isDisabledByAdmin() || isDisabledByEcm());
+            mGear.setEnabled(state);
+            mGear.setImageAlpha(state ? VALUE_ENABLED_ALPHA : mDisabledAlphaValue);
         }
-        mGearState = enabled;
+        mGearState = state;
     }
 
     @Override
diff --git a/src/com/android/settings/widget/TipCardPreference.kt b/src/com/android/settings/widget/TipCardPreference.kt
index 0ae7d2a..0ca0272 100644
--- a/src/com/android/settings/widget/TipCardPreference.kt
+++ b/src/com/android/settings/widget/TipCardPreference.kt
@@ -19,6 +19,7 @@
 import android.content.Context
 import android.content.res.Resources
 import android.util.AttributeSet
+import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.compose.ui.res.vectorResource
 import com.android.settings.spa.preference.ComposePreference
@@ -37,6 +38,9 @@
     /** A icon resource id for displaying icon on tips card. */
     var iconResId: Int? = null
 
+    /** A color resource id for displaying icon and button text on tips card. */
+    var tintColorResId: Int? = null
+
     /** The primary button's text. */
     var primaryButtonText: String = ""
 
@@ -85,6 +89,8 @@
                     title = title?.toString() ?: "",
                     text = summary?.toString() ?: "",
                     buttons = listOfNotNull(configPrimaryButton(), configSecondaryButton()),
+                    tintColor = tintColorResId?.let { Color(context.getColor(it)) }
+                        ?: Color.Unspecified,
                     onDismiss = onDismiss,
                     imageVector =
                     iconResId
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/ScreenFlashNotificationColorDialogFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ScreenFlashNotificationColorDialogFragmentTest.java
index f3fa69d..ea48253 100644
--- a/tests/robotests/src/com/android/settings/accessibility/ScreenFlashNotificationColorDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/ScreenFlashNotificationColorDialogFragmentTest.java
@@ -37,10 +37,13 @@
 
 import android.content.Intent;
 import android.graphics.Color;
+import android.os.Bundle;
+import android.provider.Settings;
 
 import androidx.appcompat.app.AlertDialog;
 import androidx.fragment.app.testing.FragmentScenario;
 import androidx.lifecycle.Lifecycle;
+import androidx.test.core.app.ApplicationProvider;
 
 import com.android.settings.R;
 import com.android.settings.testutils.FakeTimer;
@@ -56,23 +59,26 @@
 
 import java.util.List;
 import java.util.Timer;
-import java.util.function.Consumer;
 
 @RunWith(RobolectricTestRunner.class)
 public class ScreenFlashNotificationColorDialogFragmentTest {
 
+    private static final int DEFAULT_COLOR = ROSE.mColorInt;
+
     private FragmentScenario<TestScreenFlashNotificationColorDialogFragment> mFragmentScenario;
     private ScreenFlashNotificationColorDialogFragment mDialogFragment;
     private AlertDialog mAlertDialog;
     private ColorSelectorLayout mColorSelectorLayout;
-    private int mCurrentColor;
 
     @Before
     public void setUp() {
-        mCurrentColor = ROSE.mColorInt;
+        Settings.System.putInt(ApplicationProvider.getApplicationContext().getContentResolver(),
+                Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR, DEFAULT_COLOR);
+        Bundle fragmentArgs = new Bundle();
+        fragmentArgs.putInt(ScreenFlashNotificationColorDialogFragment.EXTRA_COLOR, DEFAULT_COLOR);
         mFragmentScenario = FragmentScenario.launch(
                 TestScreenFlashNotificationColorDialogFragment.class,
-                /* fragmentArgs= */ null,
+                fragmentArgs,
                 R.style.Theme_AlertDialog_SettingsLib,
                 Lifecycle.State.INITIALIZED);
         setupFragment();
@@ -99,7 +105,7 @@
         performClickOnDialog(BUTTON_NEUTRAL);
         getTimerFromFragment().runOneTask();
 
-        assertStartPreview(ROSE.mColorInt);
+        assertStartPreview(DEFAULT_COLOR);
     }
 
     @Test
@@ -168,20 +174,26 @@
     }
 
     @Test
-    public void clickColorAndClickNegative_assertColor() {
+    public void clickColorAndClickNegative_assertDefaultColor() {
         checkColorButton(AZURE);
         performClickOnDialog(BUTTON_NEGATIVE);
 
         assertThat(getTimerFromFragment()).isNull();
-        assertThat(mCurrentColor).isEqualTo(ROSE.mColorInt);
+        assertThat(Settings.System.getInt(
+                ApplicationProvider.getApplicationContext().getContentResolver(),
+                Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR, AZURE.mColorInt)).isEqualTo(
+                DEFAULT_COLOR);
     }
 
     @Test
-    public void clickColorAndClickPositive_assertColor() {
+    public void clickColorAndClickPositive_assertSameColor() {
         checkColorButton(BLUE);
         performClickOnDialog(BUTTON_POSITIVE);
 
-        assertThat(mCurrentColor).isEqualTo(BLUE.mColorInt);
+        assertThat(Settings.System.getInt(
+                ApplicationProvider.getApplicationContext().getContentResolver(),
+                Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR, DEFAULT_COLOR)).isEqualTo(
+                BLUE.mColorInt);
     }
 
     private void checkColorButton(ScreenFlashNotificationColor color) {
@@ -201,11 +213,6 @@
     }
 
     private void setupFragment() {
-        mFragmentScenario.onFragment(fragment -> {
-            ReflectionHelpers.setField(fragment, "mCurrentColor", mCurrentColor);
-            ReflectionHelpers.setField(fragment, "mConsumer",
-                    (Consumer<Integer>) selectedColor -> mCurrentColor = selectedColor);
-        });
         mFragmentScenario.moveToState(Lifecycle.State.RESUMED);
 
         mFragmentScenario.onFragment(fragment -> {
diff --git a/tests/robotests/src/com/android/settings/accessibility/ScreenFlashNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/ScreenFlashNotificationPreferenceControllerTest.java
index 95a9438..d7c1a0f 100644
--- a/tests/robotests/src/com/android/settings/accessibility/ScreenFlashNotificationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/ScreenFlashNotificationPreferenceControllerTest.java
@@ -57,8 +57,6 @@
 import org.robolectric.annotation.Implements;
 import org.robolectric.annotation.Resetter;
 
-import java.util.function.Consumer;
-
 @RunWith(RobolectricTestRunner.class)
 @Config(shadows = {
         ScreenFlashNotificationPreferenceControllerTest
@@ -83,7 +81,6 @@
     private FragmentManager mFragmentManager;
     @Mock
     private ScreenFlashNotificationColorDialogFragment mDialogFragment;
-
     private ScreenFlashNotificationPreferenceController mController;
     private ContentResolver mContentResolver;
 
@@ -92,6 +89,7 @@
         MockitoAnnotations.initMocks(this);
         FragmentActivity fragmentActivity = Robolectric.setupActivity(FragmentActivity.class);
         Context context = fragmentActivity.getApplicationContext();
+
         ShadowScreenFlashNotificationColorDialogFragment.setInstance(mDialogFragment);
         ShadowFlashNotificationsUtils.setColorDescriptionText(COLOR_DESCRIPTION_TEXT);
 
@@ -99,8 +97,9 @@
         mController = new ScreenFlashNotificationPreferenceController(context, PREFERENCE_KEY);
         when(mPreferenceScreen.findPreference(PREFERENCE_KEY)).thenReturn(mPreference);
         when(mPreference.getKey()).thenReturn(PREFERENCE_KEY);
-        mController.setParentFragment(mParentFragment);
         when(mParentFragment.getParentFragmentManager()).thenReturn(mFragmentManager);
+
+        mController.setParentFragment(mParentFragment);
     }
 
     @After
@@ -181,6 +180,7 @@
     @Test
     public void handlePreferenceTreeClick() {
         mController.handlePreferenceTreeClick(mPreference);
+
         verify(mDialogFragment).show(any(FragmentManager.class), anyString());
     }
 
@@ -194,7 +194,7 @@
 
         @Implementation
         protected static ScreenFlashNotificationColorDialogFragment getInstance(
-                int initialColor, Consumer<Integer> colorConsumer) {
+                int initialColor) {
             return sInstance;
         }
 
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/fuelgauge/batteryusage/BatteryTipsCardPreferenceTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreferenceTest.java
deleted file mode 100644
index 5f86301..0000000
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreferenceTest.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.fuelgauge.batteryusage;
-
-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.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.settings.SettingsEnums;
-import android.content.Context;
-import android.content.Intent;
-import android.provider.Settings;
-import android.util.Pair;
-import android.view.View;
-
-import com.android.settings.DisplaySettings;
-import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settings.testutils.BatteryTestUtils;
-import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-import java.util.Map;
-import java.util.Optional;
-import java.util.TimeZone;
-
-@RunWith(RobolectricTestRunner.class)
-public final class BatteryTipsCardPreferenceTest {
-
-    private Context mContext;
-    private FakeFeatureFactory mFeatureFactory;
-    private BatteryTipsCardPreference mBatteryTipsCardPreference;
-    private PowerUsageAdvanced mPowerUsageAdvanced;
-    private BatteryTipsController mBatteryTipsController;
-    private BatteryChartPreferenceController mBatteryChartPreferenceController;
-
-    @Mock private View mFakeView;
-    @Mock private BatteryUsageBreakdownController mBatteryUsageBreakdownController;
-    @Mock private BatteryDiffEntry mFakeEntry;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        TimeZone.setDefault(TimeZone.getTimeZone("GMT+8"));
-        mContext = spy(RuntimeEnvironment.application);
-        mFeatureFactory = FakeFeatureFactory.setupForTest();
-        mBatteryTipsCardPreference = new BatteryTipsCardPreference(mContext, /* attrs= */ null);
-        mBatteryTipsController = new BatteryTipsController(mContext);
-        mBatteryChartPreferenceController =
-                spy(new BatteryChartPreferenceController(mContext, null, null));
-        mBatteryChartPreferenceController.mPrefContext = mContext;
-        mBatteryTipsController.mCardPreference = mBatteryTipsCardPreference;
-
-        mPowerUsageAdvanced = spy(new PowerUsageAdvanced());
-        doReturn(mContext).when(mPowerUsageAdvanced).getContext();
-        mPowerUsageAdvanced.mBatteryTipsController = mBatteryTipsController;
-        mPowerUsageAdvanced.mBatteryChartPreferenceController = mBatteryChartPreferenceController;
-        mPowerUsageAdvanced.mBatteryUsageBreakdownController = mBatteryUsageBreakdownController;
-        mPowerUsageAdvanced.mBatteryLevelData =
-                Optional.of(
-                        new BatteryLevelData(
-                                Map.of(
-                                        1694354400000L, 1, // 2023-09-10 22:00:00
-                                        1694361600000L, 2, // 2023-09-11 00:00:00
-                                        1694368800000L, 3))); // 2023-09-11 02:00:00
-        doReturn("TestEntriesKey").when(mFakeEntry).getKey();
-    }
-
-    @Test
-    public void constructor_returnExpectedResult() {
-        assertThat(mBatteryTipsCardPreference.getLayoutResource())
-                .isEqualTo(R.layout.battery_tips_card);
-    }
-
-    @Test
-    public void onClick_mainBtnOfSettingsAnomalyLaunchPage_getAdaptiveBrightnessLauncher() {
-        final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
-        PowerAnomalyEvent adaptiveBrightnessAnomaly =
-                BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent(/* changeSettings= */ false);
-        when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
-        when(mFakeView.getId()).thenReturn(R.id.main_button);
-        doNothing().when(mContext).startActivity(captor.capture());
-
-        mPowerUsageAdvanced.onDisplayAnomalyEventUpdated(
-                adaptiveBrightnessAnomaly, adaptiveBrightnessAnomaly);
-        mBatteryTipsCardPreference.onClick(mFakeView);
-
-        assertThat(mBatteryTipsCardPreference.isVisible()).isFalse();
-        verify(mContext).startActivity(any(Intent.class));
-        final Intent intent = captor.getValue();
-        assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
-                .isEqualTo(DisplaySettings.class.getName());
-        assertThat(intent.getIntExtra(MetricsFeatureProvider.EXTRA_SOURCE_METRICS_CATEGORY, -1))
-                .isEqualTo(SettingsEnums.DISPLAY);
-        verify(mFeatureFactory.metricsFeatureProvider)
-                .action(
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW,
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        BatteryTipsController.ANOMALY_KEY,
-                        PowerAnomalyKey.KEY_BRIGHTNESS.getNumber());
-        verify(mFeatureFactory.metricsFeatureProvider)
-                .action(
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        SettingsEnums.ACTION_BATTERY_TIPS_CARD_ACCEPT,
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        BatteryTipsController.ANOMALY_KEY,
-                        PowerAnomalyKey.KEY_BRIGHTNESS.getNumber());
-    }
-
-    @Test
-    public void onClick_mainBtnOfSettingsAnomalyChangeSettings_settingsChanged()
-            throws Settings.SettingNotFoundException {
-        Settings.System.putInt(
-                mContext.getContentResolver(),
-                Settings.System.SCREEN_BRIGHTNESS_MODE,
-                Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
-        final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
-        PowerAnomalyEvent adaptiveBrightnessAnomaly =
-                BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent(/* changeSettings= */ true);
-        when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
-        when(mFakeView.getId()).thenReturn(R.id.main_button);
-        doNothing().when(mContext).startActivity(captor.capture());
-
-        mPowerUsageAdvanced.onDisplayAnomalyEventUpdated(
-                adaptiveBrightnessAnomaly, adaptiveBrightnessAnomaly);
-        mBatteryTipsCardPreference.onClick(mFakeView);
-
-        assertThat(mBatteryTipsCardPreference.isVisible()).isFalse();
-        assertThat(
-                        Settings.System.getInt(
-                                mContext.getContentResolver(),
-                                Settings.System.SCREEN_BRIGHTNESS_MODE))
-                .isEqualTo(Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
-        verify(mContext, never()).startActivity(any(Intent.class));
-        verify(mFeatureFactory.metricsFeatureProvider)
-                .action(
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW,
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        BatteryTipsController.ANOMALY_KEY,
-                        PowerAnomalyKey.KEY_BRIGHTNESS.getNumber());
-        verify(mFeatureFactory.metricsFeatureProvider)
-                .action(
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        SettingsEnums.ACTION_BATTERY_TIPS_CARD_ACCEPT,
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        BatteryTipsController.ANOMALY_KEY,
-                        PowerAnomalyKey.KEY_BRIGHTNESS.getNumber());
-    }
-
-    @Test
-    public void onClick_dismissBtnOfSettingsAnomaly_cardDismissAndLogged() {
-        final PowerAnomalyEvent screenTimeoutAnomaly =
-                BatteryTestUtils.createScreenTimeoutAnomalyEvent();
-        DatabaseUtils.removeDismissedPowerAnomalyKeys(mContext);
-        when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
-        when(mFakeView.getId()).thenReturn(R.id.dismiss_button);
-
-        mPowerUsageAdvanced.onDisplayAnomalyEventUpdated(
-                screenTimeoutAnomaly, screenTimeoutAnomaly);
-        mBatteryTipsCardPreference.onClick(mFakeView);
-
-        assertThat(mBatteryTipsCardPreference.isVisible()).isFalse();
-        assertThat(DatabaseUtils.getDismissedPowerAnomalyKeys(mContext)).hasSize(1);
-        assertThat(DatabaseUtils.getDismissedPowerAnomalyKeys(mContext))
-                .contains(PowerAnomalyKey.KEY_SCREEN_TIMEOUT.name());
-        verify(mFeatureFactory.metricsFeatureProvider)
-                .action(
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW,
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        BatteryTipsController.ANOMALY_KEY,
-                        PowerAnomalyKey.KEY_SCREEN_TIMEOUT.getNumber());
-        verify(mFeatureFactory.metricsFeatureProvider)
-                .action(
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        SettingsEnums.ACTION_BATTERY_TIPS_CARD_DISMISS,
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        BatteryTipsController.ANOMALY_KEY,
-                        PowerAnomalyKey.KEY_SCREEN_TIMEOUT.getNumber());
-    }
-
-    @Test
-    public void onClick_mainBtnOfAppsAnomaly_selectHighlightSlot() {
-        final PowerAnomalyEvent appsAnomaly = BatteryTestUtils.createAppAnomalyEvent();
-        when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
-        when(mFakeView.getId()).thenReturn(R.id.main_button);
-        doNothing().when(mBatteryChartPreferenceController).selectHighlightSlotIndex();
-        when(mPowerUsageAdvanced.findRelatedBatteryDiffEntry(any())).thenReturn(mFakeEntry);
-
-        mPowerUsageAdvanced.onDisplayAnomalyEventUpdated(appsAnomaly, appsAnomaly);
-        assertHighlightSlotIndexPair(1, 0);
-        mBatteryTipsCardPreference.onClick(mFakeView);
-
-        assertThat(mBatteryTipsCardPreference.isVisible()).isFalse();
-        verify(mContext, never()).startActivity(any(Intent.class));
-        verify(mBatteryChartPreferenceController).onHighlightSlotIndexUpdate(eq(1), eq(0));
-        verify(mBatteryChartPreferenceController).selectHighlightSlotIndex();
-        verify(mFeatureFactory.metricsFeatureProvider)
-                .action(
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW,
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        BatteryTipsController.ANOMALY_KEY,
-                        PowerAnomalyKey.KEY_APP_TOTAL_HIGHER_THAN_USUAL.getNumber());
-        verify(mFeatureFactory.metricsFeatureProvider)
-                .action(
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        SettingsEnums.ACTION_BATTERY_TIPS_CARD_ACCEPT,
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        BatteryTipsController.ANOMALY_KEY,
-                        PowerAnomalyKey.KEY_APP_TOTAL_HIGHER_THAN_USUAL.getNumber());
-    }
-
-    @Test
-    public void onClick_dismissBtnOfAppsAnomaly_keepHighlightSlotIndex() {
-        final PowerAnomalyEvent appsAnomaly = BatteryTestUtils.createAppAnomalyEvent();
-        when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
-        when(mFakeView.getId()).thenReturn(R.id.dismiss_button);
-        when(mPowerUsageAdvanced.findRelatedBatteryDiffEntry(any())).thenReturn(mFakeEntry);
-
-        mPowerUsageAdvanced.onDisplayAnomalyEventUpdated(appsAnomaly, appsAnomaly);
-        assertHighlightSlotIndexPair(1, 0);
-        mBatteryTipsCardPreference.onClick(mFakeView);
-
-        assertThat(mBatteryTipsCardPreference.isVisible()).isFalse();
-        verify(mContext, never()).startActivity(any(Intent.class));
-        verify(mBatteryChartPreferenceController).onHighlightSlotIndexUpdate(eq(1), eq(0));
-        verify(mBatteryChartPreferenceController, never()).selectHighlightSlotIndex();
-        verify(mFeatureFactory.metricsFeatureProvider)
-                .action(
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW,
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        BatteryTipsController.ANOMALY_KEY,
-                        PowerAnomalyKey.KEY_APP_TOTAL_HIGHER_THAN_USUAL.getNumber());
-        verify(mFeatureFactory.metricsFeatureProvider)
-                .action(
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        SettingsEnums.ACTION_BATTERY_TIPS_CARD_DISMISS,
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        BatteryTipsController.ANOMALY_KEY,
-                        PowerAnomalyKey.KEY_APP_TOTAL_HIGHER_THAN_USUAL.getNumber());
-    }
-
-    private void assertHighlightSlotIndexPair(
-            int dailyHighlightSlotIndex, int hourlyHighlightSlotIndex) {
-        assertThat(mPowerUsageAdvanced.mBatteryLevelData.isPresent()).isTrue();
-        assertThat(mPowerUsageAdvanced.mHighlightEventWrapper.isPresent()).isTrue();
-        Pair<Integer, Integer> slotIndexPair =
-                mPowerUsageAdvanced
-                        .mHighlightEventWrapper
-                        .get()
-                        .getHighlightSlotPair(mPowerUsageAdvanced.mBatteryLevelData.get());
-        assertThat(slotIndexPair)
-                .isEqualTo(Pair.create(dailyHighlightSlotIndex, hourlyHighlightSlotIndex));
-        assertThat(mPowerUsageAdvanced.mBatteryChartPreferenceController.mDailyHighlightSlotIndex)
-                .isEqualTo(dailyHighlightSlotIndex);
-        assertThat(mPowerUsageAdvanced.mBatteryChartPreferenceController.mHourlyHighlightSlotIndex)
-                .isEqualTo(hourlyHighlightSlotIndex);
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java
index 954437f..6c29036b 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java
@@ -16,8 +16,13 @@
 
 package com.android.settings.fuelgauge.batteryusage;
 
+
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Mockito.doReturn;
+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;
 
@@ -29,11 +34,11 @@
 import com.android.settings.R;
 import com.android.settings.testutils.BatteryTestUtils;
 import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.widget.TipCardPreference;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
@@ -47,134 +52,156 @@
     private Context mContext;
     private FakeFeatureFactory mFeatureFactory;
     private BatteryTipsController mBatteryTipsController;
-
-    @Mock private BatteryTipsCardPreference mBatteryTipsCardPreference;
+    private TipCardPreference mCardPreference;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         Locale.setDefault(new Locale("en_US"));
-        org.robolectric.shadows.ShadowSettings.set24HourTimeFormat(false);
         TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+
         mContext = spy(RuntimeEnvironment.application);
         final Resources resources = spy(mContext.getResources());
         resources.getConfiguration().setLocales(new LocaleList(new Locale("en_US")));
         doReturn(resources).when(mContext).getResources();
         mFeatureFactory = FakeFeatureFactory.setupForTest();
-        mBatteryTipsController = new BatteryTipsController(mContext);
-        mBatteryTipsController.mCardPreference = mBatteryTipsCardPreference;
+        mBatteryTipsController = spy(new BatteryTipsController(mContext));
+        mCardPreference = new TipCardPreference(mContext);
+        mBatteryTipsController.mCardPreference = mCardPreference;
     }
 
     @Test
     public void handleBatteryTipsCardUpdated_null_hidePreference() {
         mBatteryTipsController.handleBatteryTipsCardUpdated(/* powerAnomalyEvents= */ null, false);
 
-        verify(mBatteryTipsCardPreference).setVisible(false);
+        assertThat(mCardPreference.isVisible()).isFalse();
     }
 
     @Test
     public void handleBatteryTipsCardUpdated_adaptiveBrightnessAnomaly_showAnomaly() {
-        PowerAnomalyEvent event = BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent();
+        AnomalyEventWrapper anomalyEventWrapper =
+                spy(
+                        new AnomalyEventWrapper(
+                                mContext,
+                                BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent(true)));
         when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
 
-        mBatteryTipsController.handleBatteryTipsCardUpdated(
-                new AnomalyEventWrapper(mContext, event), false);
+        mBatteryTipsController.handleBatteryTipsCardUpdated(anomalyEventWrapper, false);
 
-        // Check pre-defined string
-        verify(mBatteryTipsCardPreference)
-                .setTitle("Turn on adaptive brightness to extend battery life");
-        verify(mBatteryTipsCardPreference).setIconResourceId(R.drawable.ic_battery_tips_lightbulb);
-        verify(mBatteryTipsCardPreference).setButtonColorResourceId(R.color.color_accent_selector);
-        verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings");
-        verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
-        // Check proto info
-        verify(mBatteryTipsCardPreference).setVisible(true);
-        verify(mFeatureFactory.metricsFeatureProvider)
-                .action(
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW,
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        BatteryTipsController.ANOMALY_KEY,
-                        PowerAnomalyKey.KEY_BRIGHTNESS.getNumber());
+        assertThat(mCardPreference.getTitle())
+                .isEqualTo("Turn on adaptive brightness to extend battery life");
+        assertThat(mCardPreference.getPrimaryButtonText()).isEqualTo("Got it");
+        assertThat(mCardPreference.getSecondaryButtonText()).isEqualTo("View Settings");
+        assertThat(mCardPreference.getIconResId()).isEqualTo(R.drawable.ic_battery_tips_lightbulb);
+        assertThat(mCardPreference.getTintColorResId()).isEqualTo(R.color.color_accent_selector);
+        assertThat(mCardPreference.getPrimaryButtonVisibility()).isTrue();
+        assertThat(mCardPreference.getSecondaryButtonVisibility()).isTrue();
+        assertCardButtonActionAndMetrics(anomalyEventWrapper);
     }
 
     @Test
     public void handleBatteryTipsCardUpdated_screenTimeoutAnomaly_showAnomaly() {
-        PowerAnomalyEvent event = BatteryTestUtils.createScreenTimeoutAnomalyEvent();
+        AnomalyEventWrapper anomalyEventWrapper =
+                spy(
+                        new AnomalyEventWrapper(
+                                mContext, BatteryTestUtils.createScreenTimeoutAnomalyEvent(true)));
         when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
 
-        mBatteryTipsController.handleBatteryTipsCardUpdated(
-                new AnomalyEventWrapper(mContext, event), false);
+        mBatteryTipsController.handleBatteryTipsCardUpdated(anomalyEventWrapper, false);
 
-        verify(mBatteryTipsCardPreference).setTitle("Reduce screen timeout to extend battery life");
-        verify(mBatteryTipsCardPreference).setIconResourceId(R.drawable.ic_battery_tips_lightbulb);
-        verify(mBatteryTipsCardPreference).setButtonColorResourceId(R.color.color_accent_selector);
-        verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings");
-        verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
-        verify(mBatteryTipsCardPreference).setVisible(true);
-        verify(mFeatureFactory.metricsFeatureProvider)
-                .action(
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW,
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        BatteryTipsController.ANOMALY_KEY,
-                        PowerAnomalyKey.KEY_SCREEN_TIMEOUT.getNumber());
+        assertThat(mCardPreference.getTitle())
+                .isEqualTo("Reduce screen timeout to extend battery life");
+        assertThat(mCardPreference.getPrimaryButtonText()).isEqualTo("Got it");
+        assertThat(mCardPreference.getSecondaryButtonText()).isEqualTo("View Settings");
+        assertThat(mCardPreference.getIconResId()).isEqualTo(R.drawable.ic_battery_tips_lightbulb);
+        assertThat(mCardPreference.getTintColorResId()).isEqualTo(R.color.color_accent_selector);
+        assertThat(mCardPreference.getPrimaryButtonVisibility()).isTrue();
+        assertThat(mCardPreference.getSecondaryButtonVisibility()).isTrue();
+        assertCardButtonActionAndMetrics(anomalyEventWrapper);
     }
 
     @Test
     public void handleBatteryTipsCardUpdated_screenTimeoutAnomalyHasTitle_showAnomaly() {
-        PowerAnomalyEvent event = BatteryTestUtils.createScreenTimeoutAnomalyEvent();
+        PowerAnomalyEvent anomalyEvent = BatteryTestUtils.createScreenTimeoutAnomalyEvent(true);
         String testTitle = "TestTitle";
-        event =
-                event.toBuilder()
+        anomalyEvent =
+                anomalyEvent.toBuilder()
                         .setWarningBannerInfo(
-                                event.getWarningBannerInfo().toBuilder()
+                                anomalyEvent.getWarningBannerInfo().toBuilder()
                                         .setTitleString(testTitle)
                                         .build())
                         .build();
+        AnomalyEventWrapper anomalyEventWrapper =
+                spy(new AnomalyEventWrapper(mContext, anomalyEvent));
         when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
 
-        mBatteryTipsController.handleBatteryTipsCardUpdated(
-                new AnomalyEventWrapper(mContext, event), false);
+        mBatteryTipsController.handleBatteryTipsCardUpdated(anomalyEventWrapper, false);
 
-        verify(mBatteryTipsCardPreference).setTitle(testTitle);
-        verify(mBatteryTipsCardPreference).setIconResourceId(R.drawable.ic_battery_tips_lightbulb);
-        verify(mBatteryTipsCardPreference).setButtonColorResourceId(R.color.color_accent_selector);
-        verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings");
-        verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
-        verify(mBatteryTipsCardPreference).setVisible(true);
-        verify(mFeatureFactory.metricsFeatureProvider)
-                .action(
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW,
-                        SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        BatteryTipsController.ANOMALY_KEY,
-                        PowerAnomalyKey.KEY_SCREEN_TIMEOUT.getNumber());
+        assertThat(mCardPreference.getTitle()).isEqualTo(testTitle);
+        assertThat(mCardPreference.getPrimaryButtonText()).isEqualTo("Got it");
+        assertThat(mCardPreference.getSecondaryButtonText()).isEqualTo("View Settings");
+        assertThat(mCardPreference.getIconResId()).isEqualTo(R.drawable.ic_battery_tips_lightbulb);
+        assertThat(mCardPreference.getTintColorResId()).isEqualTo(R.color.color_accent_selector);
+        assertThat(mCardPreference.getPrimaryButtonVisibility()).isTrue();
+        assertThat(mCardPreference.getSecondaryButtonVisibility()).isTrue();
+        assertCardButtonActionAndMetrics(anomalyEventWrapper);
     }
 
     @Test
     public void handleBatteryTipsCardUpdated_appAnomaly_showAnomaly() {
-        PowerAnomalyEvent event = BatteryTestUtils.createAppAnomalyEvent();
+        AnomalyEventWrapper anomalyEventWrapper =
+                spy(new AnomalyEventWrapper(mContext, BatteryTestUtils.createAppAnomalyEvent()));
         when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
 
-        AnomalyEventWrapper eventWrapper = new AnomalyEventWrapper(mContext, event);
-        eventWrapper.setRelatedBatteryDiffEntry(new BatteryDiffEntry(mContext, "", "Chrome", 0));
-        mBatteryTipsController.handleBatteryTipsCardUpdated(eventWrapper, false);
+        anomalyEventWrapper.setRelatedBatteryDiffEntry(
+                new BatteryDiffEntry(mContext, "", "Chrome", 0));
+        mBatteryTipsController.setOnAnomalyConfirmListener(
+                () -> mBatteryTipsController.acceptTipsCard());
+        mBatteryTipsController.handleBatteryTipsCardUpdated(anomalyEventWrapper, true);
 
-        verify(mBatteryTipsCardPreference).setTitle("Chrome used more battery than usual");
-        verify(mBatteryTipsCardPreference)
-                .setIconResourceId(R.drawable.ic_battery_tips_warning_icon);
-        verify(mBatteryTipsCardPreference)
-                .setButtonColorResourceId(R.color.color_battery_anomaly_app_warning_selector);
-        verify(mBatteryTipsCardPreference).setMainButtonLabel("Check");
-        verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
-        verify(mBatteryTipsCardPreference).setVisible(true);
+        assertThat(mCardPreference.getTitle()).isEqualTo("Chrome used more battery than usual");
+        assertThat(mCardPreference.getPrimaryButtonText()).isEqualTo("Got it");
+        assertThat(mCardPreference.getSecondaryButtonText()).isEqualTo("Check");
+        assertThat(mCardPreference.getIconResId())
+                .isEqualTo(R.drawable.ic_battery_tips_warning_icon);
+        assertThat(mCardPreference.getTintColorResId())
+                .isEqualTo(R.color.color_battery_anomaly_app_warning_selector);
+        assertThat(mCardPreference.getPrimaryButtonVisibility()).isTrue();
+        assertThat(mCardPreference.getSecondaryButtonVisibility()).isTrue();
+        assertThat(mCardPreference.isVisible()).isTrue();
+        assertCardButtonActionAndMetrics(anomalyEventWrapper);
+    }
+
+    private void assertCardButtonActionAndMetrics(final AnomalyEventWrapper anomalyEventWrapper) {
+        when(anomalyEventWrapper.updateSystemSettingsIfAvailable()).thenReturn(true);
+
+        final int powerAnomalyKeyNumber = anomalyEventWrapper.getAnomalyKeyNumber();
+        assertCardMetrics(SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, powerAnomalyKeyNumber);
+        assertThat(mCardPreference.isVisible()).isTrue();
+
+        // Check accept button action
+        mCardPreference.setVisible(true);
+        mCardPreference.getSecondaryButtonAction().invoke();
+        assertCardMetrics(SettingsEnums.ACTION_BATTERY_TIPS_CARD_ACCEPT, powerAnomalyKeyNumber);
+        assertThat(mCardPreference.isVisible()).isFalse();
+        final boolean isAppAnomalyCard = powerAnomalyKeyNumber > 1;
+        verify(anomalyEventWrapper, isAppAnomalyCard ? never() : times(1))
+                .updateSystemSettingsIfAvailable();
+
+        // Check reject button action
+        mCardPreference.setVisible(true);
+        mCardPreference.getPrimaryButtonAction().invoke();
+        assertCardMetrics(SettingsEnums.ACTION_BATTERY_TIPS_CARD_DISMISS, powerAnomalyKeyNumber);
+        assertThat(mCardPreference.isVisible()).isFalse();
+    }
+
+    private void assertCardMetrics(final int action, final int powerAnomalyKeyNumber) {
         verify(mFeatureFactory.metricsFeatureProvider)
                 .action(
                         SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
-                        SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW,
+                        action,
                         SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,
                         BatteryTipsController.ANOMALY_KEY,
-                        PowerAnomalyKey.KEY_APP_TOTAL_HIGHER_THAN_USUAL.getNumber());
+                        powerAnomalyKeyNumber);
     }
 }
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/robotests/src/com/android/settings/testutils/BatteryTestUtils.java b/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java
index a151632..951f2f0 100644
--- a/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java
@@ -264,18 +264,28 @@
 
     /** Create a power anomaly event proto of screen timeout. */
     public static PowerAnomalyEvent createScreenTimeoutAnomalyEvent() {
+        return createScreenTimeoutAnomalyEvent(false);
+    }
+
+    /** Create a power anomaly event proto of screen timeout. */
+    public static PowerAnomalyEvent createScreenTimeoutAnomalyEvent(boolean changeSettings) {
+        WarningBannerInfo.Builder warningBannerInfoBuilder =
+                WarningBannerInfo.newBuilder()
+                        .setMainButtonDestination(ScreenTimeoutSettings.class.getName())
+                        .setMainButtonSourceMetricsCategory(SettingsEnums.SCREEN_TIMEOUT)
+                        .setMainButtonSourceHighlightKey("60000");
+        if (changeSettings) {
+            warningBannerInfoBuilder
+                    .setMainButtonConfigSettingsName(Settings.System.SCREEN_OFF_TIMEOUT)
+                    .setMainButtonConfigSettingsValue(60000);
+        }
         return PowerAnomalyEvent.newBuilder()
                 .setEventId("ScreenTimeoutAnomaly")
                 .setType(PowerAnomalyType.TYPE_SETTINGS_BANNER)
                 .setKey(PowerAnomalyKey.KEY_SCREEN_TIMEOUT)
                 .setDismissRecordKey(PowerAnomalyKey.KEY_SCREEN_TIMEOUT.name())
                 .setScore(1.1f)
-                .setWarningBannerInfo(
-                        WarningBannerInfo.newBuilder()
-                                .setMainButtonDestination(ScreenTimeoutSettings.class.getName())
-                                .setMainButtonSourceMetricsCategory(SettingsEnums.SCREEN_TIMEOUT)
-                                .setMainButtonSourceHighlightKey("60000")
-                                .build())
+                .setWarningBannerInfo(warningBannerInfoBuilder.build())
                 .build();
     }
 
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(
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
index 4d723dc1..34c8602 100644
--- a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
+++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
@@ -20,15 +20,33 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
 
 import android.content.Context;
+import android.content.Intent;
 import android.os.UserManager;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
 
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
 import androidx.test.annotation.UiThreadTest;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
+import com.android.settings.flags.Flags;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.wifi.factory.WifiFeatureProvider;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -44,18 +62,36 @@
 
     @Rule
     public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
     @Spy
     private final Context mContext = ApplicationProvider.getApplicationContext();
     @Mock
     private UserManager mUserManager;
+    @Mock
+    private FragmentManager mFragmentManager;
 
+    // Mock, created by FakeFeatureFactory
+    private WifiFeatureProvider mWifiFeatureProviderMock;
+
+    @Spy
     private WifiDppConfiguratorActivity mActivity;
 
     @Before
     public void setUp() {
         when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
 
-        mActivity = new WifiDppConfiguratorActivity();
+        mActivity.mFragmentManager = mFragmentManager;
+        doReturn(mContext).when(mActivity).getApplicationContext();
+
+        FragmentTransaction mockTransaction = mock(FragmentTransaction.class);
+        when(mFragmentManager.beginTransaction()).thenReturn(mockTransaction);
+        when(mockTransaction.replace(anyInt(), any(Fragment.class), anyString()))
+                .thenReturn(mockTransaction);
+
+        FakeFeatureFactory featureFactory = FakeFeatureFactory.setupForTest();
+        mWifiFeatureProviderMock = featureFactory.mWifiFeatureProvider;
     }
 
     @Test
@@ -71,4 +107,37 @@
 
         assertThat(mActivity.isAddWifiConfigAllowed(mContext)).isFalse();
     }
+
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_WIFI_SHARING_RUNTIME_FRAGMENT)
+    public void showQrCodeGeneratorFragment_shouldUseFeatureFactory() {
+        when(mUserManager.isGuestUser()).thenReturn(false);
+        when(mWifiFeatureProviderMock.getWifiDppQrCodeGeneratorFragment())
+                .thenReturn(new WifiDppQrCodeGeneratorFragment());
+
+        mActivity.handleIntent(createQrCodeGeneratorIntent());
+
+        verify(mWifiFeatureProviderMock).getWifiDppQrCodeGeneratorFragment();
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_ENABLE_WIFI_SHARING_RUNTIME_FRAGMENT)
+    public void showQrCodeGeneratorFragment_shouldNotUseFeatureFactory() {
+        when(mUserManager.isGuestUser()).thenReturn(false);
+
+        mActivity.handleIntent(createQrCodeGeneratorIntent());
+
+        verify(mWifiFeatureProviderMock, never())
+                .getWifiDppQrCodeGeneratorFragment();
+    }
+
+    private static Intent createQrCodeGeneratorIntent() {
+        Intent intent = new Intent(
+                WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_GENERATOR);
+        intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "GoogleGuest");
+        intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WPA");
+        intent.putExtra(WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY, "\\012345678,");
+        return intent;
+    }
 }