Merge "Moves battery saver warning message below Screen Attention setting." into tm-dev
diff --git a/res/layout/accessibility_edit_magnification_shortcut.xml b/res/layout/accessibility_edit_magnification_shortcut.xml
deleted file mode 100644
index 2702e70..0000000
--- a/res/layout/accessibility_edit_magnification_shortcut.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
-  Copyright (C) 2020 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
-  -->
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/container_layout"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:scrollbarStyle="outsideOverlay">
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        android:padding="24dp">
-
-        <ImageView
-            android:id="@+id/image"
-            android:layout_width="@dimen/accessibility_imageview_size"
-            android:layout_height="@dimen/accessibility_imageview_size"
-            android:layout_gravity="center_horizontal"
-            android:layout_marginBottom="@dimen/accessibility_textview_layout_margin_bottom"
-            android:scaleType="fitCenter"/>
-
-        <TextView
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/accessibility_magnification_switch_shortcut_message"
-            android:textAppearance="?android:attr/textAppearanceListItemSecondary"
-            android:textColor="?android:attr/textColorSecondary"
-            android:layout_marginBottom="@dimen/accessibility_textview_layout_margin_bottom"/>
-
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical">
-
-            <Button
-                android:id="@+id/custom_positive_button"
-                style="@style/AccessibilityDialogButton"
-                android:gravity="center|end"
-                android:text="@string/accessibility_magnification_switch_shortcut_positive_button"/>
-
-            <Button
-                android:id="@+id/custom_negative_button"
-                style="@style/AccessibilityDialogButton"
-                android:gravity="center|end"
-                android:text="@string/accessibility_magnification_switch_shortcut_negative_button"/>
-
-        </LinearLayout>
-    </LinearLayout>
-</ScrollView>
\ No newline at end of file
diff --git a/res/layout/magnification_triple_tap_warning_dialog.xml b/res/layout/magnification_triple_tap_warning_dialog.xml
new file mode 100644
index 0000000..059ab62
--- /dev/null
+++ b/res/layout/magnification_triple_tap_warning_dialog.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2022 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License
+  -->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:scrollbarStyle="outsideOverlay">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:paddingTop="?android:attr/dialogPreferredPadding"
+        android:paddingStart="?android:attr/dialogPreferredPadding"
+        android:paddingEnd="?android:attr/dialogPreferredPadding">
+
+        <TextView
+            android:id="@+id/message"
+            android:text="@string/accessibility_magnification_triple_tap_warning_message"
+            style="@style/AccessibilityDialogDescription" />
+
+    </LinearLayout>
+</ScrollView>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 3e0abbb..20733a3 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7657,8 +7657,7 @@
     <string name="user_you">You (<xliff:g id="name" example="Name">%s</xliff:g>)</string>
 
     <!-- Summary for add user action, when it's disabled [CHAR LIMIT=100] -->
-    <string name="user_add_max_count">You can add up to <xliff:g id="user_count">%1$d</xliff:g> users</string>
-
+    <string name="user_add_max_count">You can\u2019t add any more users. Remove a user to add a new one.</string>
 
     <!-- Message to secondary users that only owner can manage users [CHAR LIMIT=none] -->
     <string name="user_cannot_manage_message" product="tablet">Only the tablet\u2019s owner can manage users.</string>
@@ -13712,7 +13711,7 @@
     <!-- Title for default print service main switch. [CHAR LIMIT=50] -->
     <string name="default_print_service_main_switch_title">Use print service</string>
     <!-- Title for multiple users main switch. [CHAR LIMIT=50] -->
-    <string name="multiple_users_main_switch_title">Enable multiple users</string>
+    <string name="multiple_users_main_switch_title">Allow multiple users</string>
     <!-- Title for wireless debugging main switch. [CHAR LIMIT=50] -->
     <string name="wireless_debugging_main_switch_title">Use wireless debugging</string>
     <!-- Title for graphics driver main switch. [CHAR LIMIT=50] -->
diff --git a/src/com/android/settings/accessibility/AccessibilityDialogUtils.java b/src/com/android/settings/accessibility/AccessibilityDialogUtils.java
index f06138f..3d0c1db 100644
--- a/src/com/android/settings/accessibility/AccessibilityDialogUtils.java
+++ b/src/com/android/settings/accessibility/AccessibilityDialogUtils.java
@@ -36,7 +36,6 @@
 import android.view.View;
 import android.widget.AbsListView;
 import android.widget.AdapterView;
-import android.widget.Button;
 import android.widget.CheckBox;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
@@ -131,7 +130,6 @@
          DialogType.EDIT_SHORTCUT_GENERIC_SUW,
          DialogType.EDIT_SHORTCUT_MAGNIFICATION,
          DialogType.EDIT_SHORTCUT_MAGNIFICATION_SUW,
-         DialogType.EDIT_MAGNIFICATION_SWITCH_SHORTCUT,
     })
 
     public @interface DialogType {
@@ -139,7 +137,6 @@
         int EDIT_SHORTCUT_GENERIC_SUW = 1;
         int EDIT_SHORTCUT_MAGNIFICATION = 2;
         int EDIT_SHORTCUT_MAGNIFICATION_SUW = 3;
-        int EDIT_MAGNIFICATION_SWITCH_SHORTCUT = 4;
     }
 
     /**
@@ -160,27 +157,6 @@
     }
 
     /**
-     * Method to show the magnification edit shortcut dialog in Magnification.
-     *
-     * @param context A valid context
-     * @param positiveBtnListener The positive button listener
-     * @return A magnification edit shortcut dialog in Magnification
-     */
-    public static Dialog createMagnificationSwitchShortcutDialog(Context context,
-            CustomButtonsClickListener positiveBtnListener) {
-        final View contentView = createSwitchShortcutDialogContentView(context);
-        final AlertDialog alertDialog = new AlertDialog.Builder(context)
-                .setView(contentView)
-                .setTitle(context.getString(
-                        R.string.accessibility_magnification_switch_shortcut_title))
-                .create();
-        setCustomButtonsClickListener(alertDialog, contentView,
-                positiveBtnListener, /* negativeBtnListener= */ null);
-        setScrollIndicators(contentView);
-        return alertDialog;
-    }
-
-    /**
      * Updates the software shortcut in edit shortcut dialog.
      *
      * @param context A valid context
@@ -233,56 +209,6 @@
                 View.SCROLL_INDICATOR_TOP | View.SCROLL_INDICATOR_BOTTOM);
     }
 
-
-    interface CustomButtonsClickListener {
-        void onClick(@CustomButton int which);
-    }
-
-    /**
-     * Annotation for customized dialog button type.
-     */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({
-            CustomButton.POSITIVE,
-            CustomButton.NEGATIVE,
-    })
-
-    public @interface CustomButton {
-        int POSITIVE = 1;
-        int NEGATIVE = 2;
-    }
-
-    private static void setCustomButtonsClickListener(Dialog dialog, View contentView,
-            CustomButtonsClickListener positiveBtnListener,
-            CustomButtonsClickListener negativeBtnListener) {
-        final Button positiveButton = contentView.findViewById(
-                R.id.custom_positive_button);
-        final Button negativeButton = contentView.findViewById(
-                R.id.custom_negative_button);
-
-        if (positiveButton != null) {
-            positiveButton.setOnClickListener(v -> {
-                if (positiveBtnListener != null) {
-                    positiveBtnListener.onClick(CustomButton.POSITIVE);
-                }
-                dialog.dismiss();
-            });
-        }
-
-        if (negativeButton != null) {
-            negativeButton.setOnClickListener(v -> {
-                if (negativeBtnListener != null) {
-                    negativeBtnListener.onClick(CustomButton.NEGATIVE);
-                }
-                dialog.dismiss();
-            });
-        }
-    }
-
-    private static View createSwitchShortcutDialogContentView(Context context) {
-        return createEditDialogContentView(context, DialogType.EDIT_MAGNIFICATION_SWITCH_SHORTCUT);
-    }
-
     /**
      * Get a content View for the edit shortcut dialog.
      *
@@ -325,12 +251,6 @@
                 initMagnifyShortcut(context, contentView);
                 initAdvancedWidget(contentView);
                 break;
-            case DialogType.EDIT_MAGNIFICATION_SWITCH_SHORTCUT:
-                contentView = inflater.inflate(
-                        R.layout.accessibility_edit_magnification_shortcut, null);
-                final ImageView image = contentView.findViewById(R.id.image);
-                image.setImageResource(retrieveSoftwareShortcutImageResId(context));
-                break;
             default:
                 throw new IllegalArgumentException();
         }
@@ -548,18 +468,24 @@
      * @param context A valid context
      * @param dialogTitle The title of the dialog
      * @param customView The customized view
-     * @param listener This listener will be invoked when the positive button in the dialog is
-     *                 clicked
+     * @param positiveButtonText The text of the positive button
+     * @param positiveListener This listener will be invoked when the positive button in the dialog
+     *                         is clicked
+     * @param negativeButtonText The text of the negative button
+     * @param negativeListener This listener will be invoked when the negative button in the dialog
+     *                         is clicked
      * @return the {@link Dialog} with the given view
      */
     public static Dialog createCustomDialog(Context context, CharSequence dialogTitle,
-            View customView, DialogInterface.OnClickListener listener) {
+            View customView, CharSequence positiveButtonText,
+            DialogInterface.OnClickListener positiveListener, CharSequence negativeButtonText,
+            DialogInterface.OnClickListener negativeListener) {
         final AlertDialog alertDialog = new AlertDialog.Builder(context)
                 .setView(customView)
                 .setTitle(dialogTitle)
                 .setCancelable(true)
-                .setPositiveButton(R.string.save, listener)
-                .setNegativeButton(R.string.cancel, null)
+                .setPositiveButton(positiveButtonText, positiveListener)
+                .setNegativeButton(negativeButtonText, negativeListener)
                 .create();
         if (customView instanceof ScrollView || customView instanceof AbsListView) {
             setScrollIndicators(customView);
diff --git a/src/com/android/settings/accessibility/MagnificationModePreferenceController.java b/src/com/android/settings/accessibility/MagnificationModePreferenceController.java
index 7110656..91eb2e9 100644
--- a/src/com/android/settings/accessibility/MagnificationModePreferenceController.java
+++ b/src/com/android/settings/accessibility/MagnificationModePreferenceController.java
@@ -16,8 +16,6 @@
 
 package com.android.settings.accessibility;
 
-import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
-import static com.android.settings.accessibility.AccessibilityDialogUtils.CustomButton;
 import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
 import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
 
@@ -27,12 +25,13 @@
 import android.content.DialogInterface;
 import android.os.Bundle;
 import android.provider.Settings;
-import android.text.TextUtils;
+import android.text.method.LinkMovementMethod;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.AdapterView;
 import android.widget.ListView;
+import android.widget.TextView;
 
 import androidx.annotation.DrawableRes;
 import androidx.annotation.NonNull;
@@ -45,6 +44,7 @@
 import com.android.settings.R;
 import com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;
 import com.android.settings.core.BasePreferenceController;
+import com.android.settings.utils.AnnotationSpan;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnCreate;
 import com.android.settingslib.core.lifecycle.events.OnResume;
@@ -52,7 +52,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.StringJoiner;
 
 /** Controller that shows the magnification area mode summary and the preference click behavior. */
 public class MagnificationModePreferenceController extends BasePreferenceController implements
@@ -63,17 +62,18 @@
     @VisibleForTesting
     static final int DIALOG_MAGNIFICATION_MODE = DIALOG_ID_BASE + 1;
     @VisibleForTesting
-    static final int DIALOG_MAGNIFICATION_SWITCH_SHORTCUT = DIALOG_ID_BASE + 2;
+    static final int DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING = DIALOG_ID_BASE + 2;
     @VisibleForTesting
     static final String EXTRA_MODE = "mode";
 
     private static final String TAG = "MagnificationModePreferenceController";
-    private static final char COMPONENT_NAME_SEPARATOR = ':';
 
     private DialogHelper mDialogHelper;
     // The magnification mode in the dialog.
-    private int mMode = MagnificationMode.NONE;
+    @MagnificationMode
+    private int mModeCache = MagnificationMode.NONE;
     private Preference mModePreference;
+    private ShortcutPreference mLinkPreference;
 
     @VisibleForTesting
     ListView mMagnificationModesListView;
@@ -113,7 +113,7 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         if (savedInstanceState != null) {
-            mMode = savedInstanceState.getInt(EXTRA_MODE, MagnificationMode.NONE);
+            mModeCache = savedInstanceState.getInt(EXTRA_MODE, MagnificationMode.NONE);
         }
     }
 
@@ -121,8 +121,10 @@
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
         mModePreference = screen.findPreference(getPreferenceKey());
+        mLinkPreference = screen.findPreference(
+                ToggleFeaturePreferenceFragment.KEY_SHORTCUT_PREFERENCE);
         mModePreference.setOnPreferenceClickListener(preference -> {
-            mMode = MagnificationCapabilities.getCapabilities(mContext);
+            mModeCache = MagnificationCapabilities.getCapabilities(mContext);
             mDialogHelper.showDialog(DIALOG_MAGNIFICATION_MODE);
             return true;
         });
@@ -130,7 +132,7 @@
 
     @Override
     public void onSaveInstanceState(Bundle outState) {
-        outState.putInt(EXTRA_MODE, mMode);
+        outState.putInt(EXTRA_MODE, mModeCache);
     }
 
     /**
@@ -147,8 +149,8 @@
             case DIALOG_MAGNIFICATION_MODE:
                 return createMagnificationModeDialog();
 
-            case DIALOG_MAGNIFICATION_SWITCH_SHORTCUT:
-                return createMagnificationShortCutConfirmDialog();
+            case DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING:
+                return createMagnificationTripleTapWarningDialog();
         }
         return null;
     }
@@ -158,8 +160,8 @@
         switch (dialogId) {
             case DIALOG_MAGNIFICATION_MODE:
                 return SettingsEnums.DIALOG_MAGNIFICATION_CAPABILITY;
-            case DIALOG_MAGNIFICATION_SWITCH_SHORTCUT:
-                return SettingsEnums.DIALOG_MAGNIFICATION_SWITCH_SHORTCUT;
+            case DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING:
+                return SettingsEnums.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING;
             default:
                 return 0;
         }
@@ -178,29 +180,40 @@
         mMagnificationModesListView.setItemChecked(computeSelectionIndex(), true);
         final CharSequence title = mContext.getString(
                 R.string.accessibility_magnification_mode_dialog_title);
+        final CharSequence positiveBtnText = mContext.getString(R.string.save);
+        final CharSequence negativeBtnText = mContext.getString(R.string.cancel);
 
         return AccessibilityDialogUtils.createCustomDialog(mContext, title,
-                mMagnificationModesListView, this::onMagnificationModeDialogPositiveButtonClicked);
+                mMagnificationModesListView,
+                positiveBtnText, this::onMagnificationModeDialogPositiveButtonClicked,
+                negativeBtnText, /* negativeListener= */ null);
     }
 
-    private void onMagnificationModeDialogPositiveButtonClicked(DialogInterface dialogInterface,
+    @VisibleForTesting
+    void onMagnificationModeDialogPositiveButtonClicked(DialogInterface dialogInterface,
             int which) {
         final int selectedIndex = mMagnificationModesListView.getCheckedItemPosition();
-        if (selectedIndex != AdapterView.INVALID_POSITION) {
-            final MagnificationModeInfo modeInfo =
-                    (MagnificationModeInfo) mMagnificationModesListView.getItemAtPosition(
-                            selectedIndex);
-            setMode(modeInfo.mMagnificationMode);
-        } else {
+        if (selectedIndex == AdapterView.INVALID_POSITION) {
             Log.w(TAG, "invalid index");
+            return;
+        }
+
+        mModeCache = ((MagnificationModeInfo) mMagnificationModesListView.getItemAtPosition(
+                        selectedIndex)).mMagnificationMode;
+
+        // Do not save mode until user clicks positive button in triple tap warning dialog.
+        if (isTripleTapEnabled(mContext) && mModeCache != MagnificationMode.FULLSCREEN) {
+            mDialogHelper.showDialog(DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING);
+        } else { // Save mode (capabilities) value, don't need to show dialog to confirm.
+            updateCapabilitiesAndSummary(mModeCache);
         }
     }
 
-    private void setMode(int mode) {
-        mMode = mode;
-        MagnificationCapabilities.setCapabilities(mContext, mMode);
+    private void updateCapabilitiesAndSummary(@MagnificationMode int mode) {
+        mModeCache = mode;
+        MagnificationCapabilities.setCapabilities(mContext, mModeCache);
         mModePreference.setSummary(
-                MagnificationCapabilities.getSummary(mContext, mMode));
+                MagnificationCapabilities.getSummary(mContext, mModeCache));
     }
 
     private void onMagnificationModeSelected(AdapterView<?> parent, View view, int position,
@@ -208,19 +221,16 @@
         final MagnificationModeInfo modeInfo =
                 (MagnificationModeInfo) mMagnificationModesListView.getItemAtPosition(
                         position);
-        if (modeInfo.mMagnificationMode == mMode) {
+        if (modeInfo.mMagnificationMode == mModeCache) {
             return;
         }
-        mMode = modeInfo.mMagnificationMode;
-        if (isTripleTapEnabled(mContext) && mMode != MagnificationMode.FULLSCREEN) {
-            mDialogHelper.showDialog(DIALOG_MAGNIFICATION_SWITCH_SHORTCUT);
-        }
+        mModeCache = modeInfo.mMagnificationMode;
     }
 
     private int computeSelectionIndex() {
         final int modesSize = mModeInfos.size();
         for (int i = 0; i < modesSize; i++) {
-            if (mModeInfos.get(i).mMagnificationMode == mMode) {
+            if (mModeInfos.get(i).mMagnificationMode == mModeCache) {
                 return i + mMagnificationModesListView.getHeaderViewsCount();
             }
         }
@@ -234,41 +244,56 @@
                 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, OFF) == ON;
     }
 
-    private Dialog createMagnificationShortCutConfirmDialog() {
-        return AccessibilityDialogUtils.createMagnificationSwitchShortcutDialog(mContext,
-                this::onSwitchShortcutDialogButtonClicked);
+    private Dialog createMagnificationTripleTapWarningDialog() {
+        final View contentView = LayoutInflater.from(mContext).inflate(
+                R.layout.magnification_triple_tap_warning_dialog, /* root= */ null);
+        final CharSequence title = mContext.getString(
+                R.string.accessibility_magnification_triple_tap_warning_title);
+        final CharSequence positiveBtnText = mContext.getString(
+                R.string.accessibility_magnification_triple_tap_warning_positive_button);
+        final CharSequence negativeBtnText = mContext.getString(
+                R.string.accessibility_magnification_triple_tap_warning_negative_button);
+
+        final Dialog dialog = AccessibilityDialogUtils.createCustomDialog(mContext, title,
+                contentView,
+                positiveBtnText, this::onMagnificationTripleTapWarningDialogPositiveButtonClicked,
+                negativeBtnText, this::onMagnificationTripleTapWarningDialogNegativeButtonClicked);
+
+        updateLinkInTripleTapWarningDialog(dialog, contentView);
+
+        return dialog;
+    }
+
+    private void updateLinkInTripleTapWarningDialog(Dialog dialog, View contentView) {
+        final TextView messageView = contentView.findViewById(R.id.message);
+        // TODO(b/225682559): Need to remove performClick() after refactoring accessibility dialog.
+        final View.OnClickListener linkListener = view -> {
+            mLinkPreference.performClick();
+            dialog.dismiss();
+        };
+        final AnnotationSpan.LinkInfo linkInfo = new AnnotationSpan.LinkInfo(
+                AnnotationSpan.LinkInfo.DEFAULT_ANNOTATION, linkListener);
+        final CharSequence textWithLink = AnnotationSpan.linkify(mContext.getText(
+                R.string.accessibility_magnification_triple_tap_warning_message), linkInfo);
+
+        if (messageView != null) {
+            messageView.setText(textWithLink);
+            messageView.setMovementMethod(LinkMovementMethod.getInstance());
+        }
+        dialog.setContentView(contentView);
     }
 
     @VisibleForTesting
-    void onSwitchShortcutDialogButtonClicked(@CustomButton int which) {
-        optOutMagnificationFromTripleTap();
-        //TODO(b/147990389): Merge this function into AccessibilityUtils after the format of
-        // magnification target is changed to ComponentName.
-        optInMagnificationToAccessibilityButton();
+    void onMagnificationTripleTapWarningDialogNegativeButtonClicked(
+            DialogInterface dialogInterface, int which) {
+        mModeCache = MagnificationCapabilities.getCapabilities(mContext);
+        mDialogHelper.showDialog(DIALOG_MAGNIFICATION_MODE);
     }
 
-    private void optOutMagnificationFromTripleTap() {
-        Settings.Secure.putInt(mContext.getContentResolver(),
-                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, OFF);
-    }
-
-    private void optInMagnificationToAccessibilityButton() {
-        final String targetKey = Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
-        final String targetString = Settings.Secure.getString(mContext.getContentResolver(),
-                targetKey);
-        if (targetString != null && targetString.contains(MAGNIFICATION_CONTROLLER_NAME)) {
-            return;
-        }
-
-        final StringJoiner joiner = new StringJoiner(String.valueOf(COMPONENT_NAME_SEPARATOR));
-
-        if (!TextUtils.isEmpty(targetString)) {
-            joiner.add(targetString);
-        }
-        joiner.add(MAGNIFICATION_CONTROLLER_NAME);
-
-        Settings.Secure.putString(mContext.getContentResolver(), targetKey,
-                joiner.toString());
+    @VisibleForTesting
+    void onMagnificationTripleTapWarningDialogPositiveButtonClicked(
+            DialogInterface dialogInterface, int which) {
+        updateCapabilitiesAndSummary(mModeCache);
     }
 
     // TODO(b/186731461): Remove it when this controller is used in DashBoardFragment only.
@@ -277,7 +302,6 @@
         updateState(mModePreference);
     }
 
-
     /**
      * An interface to help the delegate to show the dialog. It will be injected to the delegate.
      */
diff --git a/src/com/android/settings/accessibility/ShortcutPreference.java b/src/com/android/settings/accessibility/ShortcutPreference.java
index cff9117..ec911a9 100644
--- a/src/com/android/settings/accessibility/ShortcutPreference.java
+++ b/src/com/android/settings/accessibility/ShortcutPreference.java
@@ -64,6 +64,11 @@
         setLayoutResource(R.layout.accessibility_shortcut_secondary_action);
         setWidgetLayoutResource(R.layout.preference_widget_primary_switch);
         setIconSpaceReserved(false);
+        // Treat onSettingsClicked as this preference's click.
+        setOnPreferenceClickListener(preference -> {
+            callOnSettingsClicked();
+            return true;
+        });
     }
 
     @Override
diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
index fd19376..e123a53 100644
--- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
@@ -102,7 +102,7 @@
     protected static final String KEY_USE_SERVICE_PREFERENCE = "use_service";
     public static final String KEY_GENERAL_CATEGORY = "general_categories";
     protected static final String KEY_HTML_DESCRIPTION_PREFERENCE = "html_description";
-    private static final String KEY_SHORTCUT_PREFERENCE = "shortcut_preference";
+    public static final String KEY_SHORTCUT_PREFERENCE = "shortcut_preference";
     protected static final String KEY_SAVED_USER_SHORTCUT_TYPE = "shortcut_type";
     protected static final String KEY_SAVED_QS_TOOLTIP_RESHOW = "qs_tooltip_reshow";
     protected static final String KEY_SAVED_QS_TOOLTIP_TYPE = "qs_tooltip_type";
diff --git a/src/com/android/settings/nearby/FastPairSettingsFragment.java b/src/com/android/settings/nearby/FastPairSettingsFragment.java
index 702e90a..434087d 100644
--- a/src/com/android/settings/nearby/FastPairSettingsFragment.java
+++ b/src/com/android/settings/nearby/FastPairSettingsFragment.java
@@ -58,8 +58,7 @@
         mainSwitchPreference.addOnSwitchChangeListener(
                 (switchView, isChecked) ->
                         NearbyManager.setFastPairScanEnabled(getContext(), isChecked));
-        mainSwitchPreference.setChecked(
-                NearbyManager.getFastPairScanEnabled(getContext(), false));
+        mainSwitchPreference.setChecked(NearbyManager.getFastPairScanEnabled(getContext()));
 
         Preference savedDevicePref = Objects.requireNonNull(
                 findPreference(SAVED_DEVICES_PREF_KEY));
diff --git a/src/com/android/settings/shortcut/CreateShortcutPreferenceController.java b/src/com/android/settings/shortcut/CreateShortcutPreferenceController.java
index c0f7e1f..c871e9f 100644
--- a/src/com/android/settings/shortcut/CreateShortcutPreferenceController.java
+++ b/src/com/android/settings/shortcut/CreateShortcutPreferenceController.java
@@ -44,8 +44,10 @@
 import androidx.preference.PreferenceGroup;
 
 import com.android.settings.R;
+import com.android.settings.Settings;
 import com.android.settings.Settings.TetherSettingsActivity;
 import com.android.settings.core.BasePreferenceController;
+import com.android.settings.gestures.OneHandedSettingsUtils;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
@@ -178,6 +180,12 @@
             return null;
         }
         for (ResolveInfo info : activities) {
+            if (info.activityInfo.name.contains(
+                    Settings.OneHandedSettingsActivity.class.getSimpleName())) {
+                if (!OneHandedSettingsUtils.isSupportOneHandedMode()) {
+                    continue;
+                }
+            }
             if (info.activityInfo.name.endsWith(TetherSettingsActivity.class.getSimpleName())) {
                 if (!mConnectivityManager.isTetheringSupported()) {
                     continue;
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 0f2eb66..47d7b46 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -1199,8 +1199,7 @@
             addUser.setEnabled(canAddMoreUsers && !mAddingUser && canSwitchUserNow());
 
             if (!canAddMoreUsers) {
-                addUser.setSummary(
-                        getString(R.string.user_add_max_count, getRealUsersCount()));
+                addUser.setSummary(getString(R.string.user_add_max_count));
             } else {
                 addUser.setSummary(null);
             }
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityDialogUtilsTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityDialogUtilsTest.java
index 83bba14..ddc3fe4 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityDialogUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityDialogUtilsTest.java
@@ -18,6 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import android.app.Dialog;
 import android.content.Context;
 
 import androidx.appcompat.app.AlertDialog;
@@ -58,4 +59,14 @@
         assertThat(AccessibilityDialogUtils.updateSoftwareShortcutInDialog(mContext,
                 dialog)).isFalse();
     }
+
+    @Test
+    public void showDialog_createCustomDialog_isShowing() {
+        final Dialog dialog = AccessibilityDialogUtils.createCustomDialog(mContext,
+                "Title", /* customView= */ null, "positiveButton", /* positiveListener= */ null,
+                "negativeButton", /* negativeListener= */ null);
+        dialog.show();
+
+        assertThat(dialog.isShowing()).isTrue();
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/accessibility/MagnificationModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/MagnificationModePreferenceControllerTest.java
index e3940e7..30ba9b6 100644
--- a/tests/robotests/src/com/android/settings/accessibility/MagnificationModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/MagnificationModePreferenceControllerTest.java
@@ -16,7 +16,6 @@
 
 package com.android.settings.accessibility;
 
-import static com.android.settings.accessibility.AccessibilityDialogUtils.CustomButton;
 import static com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;
 import static com.android.settings.accessibility.MagnificationModePreferenceController.MagnificationModeInfo;
 import static com.android.settings.accessibility.MagnificationPreferenceFragment.ON;
@@ -28,17 +27,24 @@
 
 import android.app.Dialog;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.os.Bundle;
 import android.provider.Settings;
+import android.text.SpannableString;
+import android.text.TextUtils;
+import android.view.View;
 import android.widget.AdapterView;
 import android.widget.ListView;
+import android.widget.TextView;
 
 import androidx.preference.Preference;
 import androidx.preference.PreferenceManager;
 import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
 
 import com.android.settings.DialogCreatable;
 import com.android.settings.R;
+import com.android.settings.utils.AnnotationSpan;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -48,7 +54,6 @@
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 
 /** Tests for {@link MagnificationModePreferenceController}. */
 @RunWith(RobolectricTestRunner.class)
@@ -68,7 +73,8 @@
 
     @Before
     public void setUp() {
-        mContext = RuntimeEnvironment.application;
+        mContext = ApplicationProvider.getApplicationContext();
+        mContext.setTheme(R.style.Theme_AppCompat);
         final PreferenceManager preferenceManager = new PreferenceManager(mContext);
         mScreen = preferenceManager.createPreferenceScreen(mContext);
         mModePreference = new Preference(mContext);
@@ -83,8 +89,8 @@
     public void clickPreference_settingsModeIsDefault_checkedModeInDialogIsDefault() {
         mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference);
 
-        assertThat(getCheckedModeFromDialog()).isEqualTo(
-                MAGNIFICATION_MODE_DEFAULT);
+        assertThat(getCheckedModeFromDialog()).isEqualTo(MAGNIFICATION_MODE_DEFAULT);
+
     }
 
     @Test
@@ -109,52 +115,103 @@
     }
 
     @Test
-    public void chooseWindowMode_tripleTapEnabled_showSwitchShortcutDialog() {
+    public void chooseFullscreenMode_tripleTapEnabled_notShowTripleTapWarningDialog() {
+        enableTripleTap();
+        mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference);
+
+        performItemClickWith(MagnificationMode.FULLSCREEN);
+        mController.onMagnificationModeDialogPositiveButtonClicked(mDialogHelper.getDialog(),
+                DialogInterface.BUTTON_POSITIVE);
+
+        verify(mDialogHelper, never()).showDialog(
+                MagnificationModePreferenceController.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING);
+    }
+
+    @Test
+    public void chooseWindowMode_tripleTapEnabled_showTripleTapWarningDialog() {
         enableTripleTap();
         mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference);
 
         performItemClickWith(MagnificationMode.WINDOW);
+        mController.onMagnificationModeDialogPositiveButtonClicked(mDialogHelper.getDialog(),
+                DialogInterface.BUTTON_POSITIVE);
 
         verify(mDialogHelper).showDialog(
-                MagnificationModePreferenceController.DIALOG_MAGNIFICATION_SWITCH_SHORTCUT);
+                MagnificationModePreferenceController.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING);
     }
 
     @Test
-    public void chooseModeAll_modeAllInSettingsAndTripleTapEnabled_notShowShortcutDialog() {
+    public void chooseAllMode_tripleTapEnabled_showTripleTapWarningDialog() {
         enableTripleTap();
         mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference);
 
         performItemClickWith(MagnificationMode.ALL);
+        mController.onMagnificationModeDialogPositiveButtonClicked(mDialogHelper.getDialog(),
+                DialogInterface.BUTTON_POSITIVE);
 
-        verify(mDialogHelper, never()).showDialog(
-                MagnificationModePreferenceController.DIALOG_MAGNIFICATION_SWITCH_SHORTCUT);
+        verify(mDialogHelper).showDialog(
+                MagnificationModePreferenceController.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING);
     }
 
     @Test
-    public void onSwitchShortcutDialogPositiveButtonClicked_TripleTapEnabled_TripleTapDisabled() {
+    public void onTripleTapWarningDialogNegativeButtonClicked_showModeDialog() {
+        mDialogHelper.showDialog(
+                MagnificationModePreferenceController.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING);
+
+        mController.onMagnificationTripleTapWarningDialogNegativeButtonClicked(
+                mDialogHelper.getDialog(), DialogInterface.BUTTON_NEGATIVE);
+
+        verify(mDialogHelper).showDialog(
+                MagnificationModePreferenceController.DIALOG_MAGNIFICATION_MODE);
+    }
+
+    @Test
+    public void onTripleTapWarningDialogPositiveButtonClicked_chooseAllMode_returnAllSummary() {
         enableTripleTap();
+        mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference);
+        performItemClickWith(MagnificationMode.ALL);
+        mController.onMagnificationModeDialogPositiveButtonClicked(mDialogHelper.getDialog(),
+                DialogInterface.BUTTON_POSITIVE);
 
-        mController.onSwitchShortcutDialogButtonClicked(CustomButton.POSITIVE);
+        mController.onMagnificationTripleTapWarningDialogPositiveButtonClicked(
+                mDialogHelper.getDialog(), DialogInterface.BUTTON_POSITIVE);
 
-        assertThat(MagnificationModePreferenceController.isTripleTapEnabled(mContext)).isFalse();
+        final String allSummary = mContext.getString(
+                R.string.accessibility_magnification_area_settings_all_summary);
+        assertThat(TextUtils.equals(mController.getSummary(), allSummary)).isTrue();
+    }
+
+    @Test
+    public void checkSpansInTripleTapWarningDialog_existAnnotationSpan() {
+        mDialogHelper.showDialog(
+                MagnificationModePreferenceController.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING);
+        final View contentView = mDialogHelper.getDialog().findViewById(android.R.id.content);
+        final TextView messageView = contentView.findViewById(R.id.message);
+        final CharSequence textInTripleTapWarningDialog = messageView.getText();
+
+        final AnnotationSpan[] annotationSpans =
+                ((SpannableString) textInTripleTapWarningDialog).getSpans(/*queryStart= */ 0,
+                        textInTripleTapWarningDialog.length(), AnnotationSpan.class);
+
+        assertThat(annotationSpans[0]).isNotNull();
     }
 
     @Test
     public void getSummary_saveWindowScreen_shouldReturnWindowScreenSummary() {
         MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.WINDOW);
 
-        assertThat(mController.getSummary())
-                .isEqualTo(mContext.getString(
-                        R.string.accessibility_magnification_area_settings_window_screen_summary));
+        final String windowSummary = mContext.getString(
+                R.string.accessibility_magnification_area_settings_window_screen_summary);
+        assertThat(TextUtils.equals(mController.getSummary(), windowSummary)).isTrue();
     }
 
     @Test
     public void getSummary_saveAll_shouldReturnAllSummary() {
         MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.ALL);
 
-        assertThat(mController.getSummary())
-                .isEqualTo(mContext.getString(
-                        R.string.accessibility_magnification_area_settings_all_summary));
+        final String allSummary = mContext.getString(
+                R.string.accessibility_magnification_area_settings_all_summary);
+        assertThat(TextUtils.equals(mController.getSummary(), allSummary)).isTrue();
     }
 
     private int getCheckedModeFromDialog() {
@@ -208,10 +265,11 @@
     private static class TestDialogHelper implements DialogCreatable,
             MagnificationModePreferenceController.DialogHelper {
         private DialogCreatable mDialogDelegate;
+        private Dialog mDialog;
 
         @Override
         public void showDialog(int dialogId) {
-            onCreateDialog(dialogId);
+            mDialog = onCreateDialog(dialogId);
         }
 
         @Override
@@ -228,5 +286,9 @@
         public int getDialogMetricsCategory(int dialogId) {
             return mDialogDelegate.getDialogMetricsCategory(dialogId);
         }
+
+        public Dialog getDialog() {
+            return mDialog;
+        }
     }
 }
diff --git a/tests/robotests/src/com/android/settings/accessibility/ShortcutPreferenceTest.java b/tests/robotests/src/com/android/settings/accessibility/ShortcutPreferenceTest.java
index 714ef9a..ee271fe 100644
--- a/tests/robotests/src/com/android/settings/accessibility/ShortcutPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/ShortcutPreferenceTest.java
@@ -23,6 +23,7 @@
 import android.view.View;
 
 import androidx.preference.PreferenceViewHolder;
+import androidx.test.core.app.ApplicationProvider;
 
 import com.android.settings.R;
 
@@ -30,7 +31,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 
 /** Tests for {@link ShortcutPreference} */
 @RunWith(RobolectricTestRunner.class)
@@ -58,7 +58,7 @@
 
     @Before
     public void setUp() {
-        final Context context = RuntimeEnvironment.application;
+        final Context context = ApplicationProvider.getApplicationContext();
         mShortcutPreference = new ShortcutPreference(context, null);
 
         final LayoutInflater inflater = LayoutInflater.from(context);
@@ -95,4 +95,13 @@
 
         assertThat(mShortcutPreference.isChecked()).isEqualTo(true);
     }
+
+    @Test
+    public void performClickOnPreference_settingsClicked() {
+        mShortcutPreference.onBindViewHolder(mPreferenceViewHolder);
+        mShortcutPreference.setOnClickCallback(mListener);
+        mShortcutPreference.performClick();
+
+        assertThat(mResult).isEqualTo(SETTINGS_CLICKED);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/shortcut/CreateShortcutPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/shortcut/CreateShortcutPreferenceControllerTest.java
index cfc9f90..49c1551 100644
--- a/tests/robotests/src/com/android/settings/shortcut/CreateShortcutPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/shortcut/CreateShortcutPreferenceControllerTest.java
@@ -36,6 +36,7 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.ShortcutInfo;
 import android.content.pm.ShortcutManager;
+import android.os.SystemProperties;
 
 import com.android.settings.Settings;
 import com.android.settings.testutils.shadow.ShadowConnectivityManager;
@@ -62,6 +63,8 @@
 @Config(shadows = ShadowConnectivityManager.class)
 public class CreateShortcutPreferenceControllerTest {
 
+    static final String SUPPORT_ONE_HANDED_MODE = "ro.support_one_handed_mode";
+
     @Mock
     private ShortcutManager mShortcutManager;
     @Mock
@@ -152,4 +155,36 @@
         assertThat(info.get(0).activityInfo).isEqualTo(ri2.activityInfo);
         assertThat(info.get(1).activityInfo).isEqualTo(ri1.activityInfo);
     }
+
+    @Test
+    public void queryShortcuts_setSupportOneHandedMode_ShouldEnableShortcuts() {
+        SystemProperties.set(SUPPORT_ONE_HANDED_MODE, "true");
+
+        setupOneHandedModeActivityInfo();
+        final List<ResolveInfo> info = mController.queryShortcuts();
+
+        assertThat(info).hasSize(1);
+    }
+
+    @Test
+    public void queryShortcuts_setUnsupportOneHandedMode_ShouldDisableShortcuts() {
+        SystemProperties.set(SUPPORT_ONE_HANDED_MODE, "false");
+
+        setupOneHandedModeActivityInfo();
+        final List<ResolveInfo> info = mController.queryShortcuts();
+
+        assertThat(info).hasSize(0);
+    }
+
+    private void setupOneHandedModeActivityInfo() {
+        final ResolveInfo ri = new ResolveInfo();
+        ri.activityInfo = new ActivityInfo();
+        ri.activityInfo.name = Settings.OneHandedSettingsActivity.class.getSimpleName();
+        ri.activityInfo.applicationInfo = new ApplicationInfo();
+        ri.activityInfo.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
+
+        mPackageManager.setResolveInfosForIntent(
+                new Intent(CreateShortcutPreferenceController.SHORTCUT_PROBE),
+                Arrays.asList(ri));
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/users/UserSettingsTest.java b/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
index 1376712..bb7dd75 100644
--- a/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
@@ -354,7 +354,8 @@
         mFragment.updateUserList();
 
         verify(mAddUserPreference).setVisible(true);
-        verify(mAddUserPreference).setSummary("You can add up to 4 users");
+        verify(mAddUserPreference).setSummary(
+                "You can\u2019t add any more users. Remove a user to add a new one.");
         verify(mAddUserPreference).setEnabled(false);
         verify(mAddUserPreference).setSelectable(true);
     }
diff --git a/tests/unit/src/com/android/settings/deviceinfo/PublicVolumeSettingsTest.java b/tests/unit/src/com/android/settings/deviceinfo/PublicVolumeSettingsTest.java
index 03d2d5a..556ec5f 100644
--- a/tests/unit/src/com/android/settings/deviceinfo/PublicVolumeSettingsTest.java
+++ b/tests/unit/src/com/android/settings/deviceinfo/PublicVolumeSettingsTest.java
@@ -26,6 +26,7 @@
 
 import com.android.settings.Settings;
 
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -38,6 +39,7 @@
             new ActivityTestRule<>(Settings.PublicVolumeSettingsActivity.class, true, true);
 
     @Test
+    @Ignore
     public void test_invalidSetupDoesNotCrashSettings() {
         Intent intent = new Intent();
         intent.setAction(android.provider.Settings.ACTION_INTERNAL_STORAGE_SETTINGS);