Merge "[Panlingual] set direction and textAlignment for the locale dialog" into udc-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 844d8ce..a67c713 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -427,6 +427,12 @@
     <string name="friday_first_day_of_week">Friday</string>
     <!-- The title of saturday for preference of first day of week. [CHAR LIMIT=50] -->
     <string name="saturday_first_day_of_week">Saturday</string>
+    <!-- Title for regional preference footer. [CHAR LIMIT=NONE] -->
+    <string name="title_regional_pref_footer">If an app doesn’t support regional preferences, the app will use its default locale settings.</string>
+    <!-- Description for text in regional preference footer. [CHAR LIMIT=NONE] -->
+    <string name="desc_regional_pref_footer_learn_more">Learn more about language preferences.</string>
+    <!-- TODO(b/277573274): Update the learn more url in the regional preference. -->
+    <string name="regional_pref_footer_learn_more_link" translatable="false">https://support.google.com/android</string>
 
     <!-- The title of the confirmation dialog shown when the user selects one / several languages and tries to remove them [CHAR LIMIT=60] -->
     <string name="dlg_remove_locales_title">{count, plural,
diff --git a/res/xml/regional_preference_main_page.xml b/res/xml/regional_preference_main_page.xml
index de9d3d8..27a1d83 100644
--- a/res/xml/regional_preference_main_page.xml
+++ b/res/xml/regional_preference_main_page.xml
@@ -66,4 +66,11 @@
             android:value="arg_value_language_select" />
     </Preference>
 
+    <com.android.settingslib.widget.FooterPreference
+        android:key="regional_pref_footer"
+        android:title="@string/title_regional_pref_footer"
+        android:selectable="false"
+        settings:searchable="false"
+        settings:controller="com.android.settings.regionalpreferences.RegionalFooterPreferenceController"/>
+
 </PreferenceScreen>
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index 68fe08e..acc0e7c 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.development;
 
+import static android.provider.Settings.Global.DEVELOPMENT_SETTINGS_ENABLED;
 import static android.service.quicksettings.TileService.ACTION_QS_TILE_PREFERENCES;
 
 import android.app.Activity;
@@ -27,12 +28,18 @@
 import android.bluetooth.BluetoothProfile;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.net.Uri;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
 import android.os.SystemProperties;
 import android.os.UserManager;
+import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.LayoutInflater;
@@ -173,11 +180,48 @@
         }
     };
 
+    private final Uri mDevelopEnabled = Settings.Global.getUriFor(DEVELOPMENT_SETTINGS_ENABLED);
+    private final ContentObserver mDeveloperSettingsObserver = new ContentObserver(new Handler(
+            Looper.getMainLooper())) {
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            super.onChange(selfChange, uri);
+            final boolean developmentEnabledState =
+                    DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(getContext());
+            final boolean switchState = mSwitchBar.isChecked();
+
+            // when developer options is enabled, but it is disabled by other privilege apps like:
+            // adb command, we should disable all items and finish the activity.
+            if (developmentEnabledState != switchState) {
+                if (developmentEnabledState) {
+                    return;
+                }
+                disableDeveloperOptions();
+                getActivity().runOnUiThread(() -> finishFragment());
+            }
+        }
+    };
+
     public DevelopmentSettingsDashboardFragment() {
         super(UserManager.DISALLOW_DEBUGGING_FEATURES);
     }
 
     @Override
+    public void onStart() {
+        super.onStart();
+        final ContentResolver cr = getContext().getContentResolver();
+        cr.registerContentObserver(mDevelopEnabled, false, mDeveloperSettingsObserver);
+    }
+
+    @Override
+    public void onStop() {
+        super.onStop();
+        final ContentResolver cr = getContext().getContentResolver();
+        cr.unregisterContentObserver(mDeveloperSettingsObserver);
+    }
+
+    @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
         SearchMenuController.init(this);
diff --git a/src/com/android/settings/inputmethod/ModifierKeysPickerDialogFragment.java b/src/com/android/settings/inputmethod/ModifierKeysPickerDialogFragment.java
index f1d7e7f..14578af 100644
--- a/src/com/android/settings/inputmethod/ModifierKeysPickerDialogFragment.java
+++ b/src/com/android/settings/inputmethod/ModifierKeysPickerDialogFragment.java
@@ -18,6 +18,7 @@
 
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
 
+import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.content.Context;
@@ -52,11 +53,13 @@
 
 public class ModifierKeysPickerDialogFragment extends DialogFragment {
 
+    static final String DEFAULT_KEY = "default_key";
+    static final String SELECTION_KEY = "delection_key";
+
     private Preference mPreference;
     private String mKeyDefaultName;
     private String mKeyFocus;
-    private Context mContext;
-    private InputManager mIm;
+    private Activity mActivity;
 
     private List<int[]> mRemappableKeyList =
             new ArrayList<>(Arrays.asList(
@@ -67,36 +70,41 @@
 
     private Map<String, int[]> mRemappableKeyMap = new HashMap<>();
 
-    public ModifierKeysPickerDialogFragment() {
-    }
+    public ModifierKeysPickerDialogFragment() {}
 
-    public ModifierKeysPickerDialogFragment(Preference preference, InputManager inputManager) {
-        mPreference = preference;
-        mKeyDefaultName = preference.getTitle().toString();
-        mKeyFocus = preference.getSummary().toString();
-        mIm = inputManager;
+    @Override
+    public void onSaveInstanceState(Bundle savedInstanceState) {
+        savedInstanceState.putString(SELECTION_KEY, mKeyFocus);
+        super.onSaveInstanceState(savedInstanceState);
     }
 
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
         super.onCreateDialog(savedInstanceState);
-        mContext = getActivity();
+
+        mActivity = getActivity();
+        InputManager inputManager = mActivity.getSystemService(InputManager.class);
+        mKeyDefaultName = getArguments().getString(DEFAULT_KEY);
+        mKeyFocus = getArguments().getString(SELECTION_KEY);
+        if (savedInstanceState != null) {
+            mKeyFocus = savedInstanceState.getString(SELECTION_KEY);
+        }
         List<String> modifierKeys = new ArrayList<String>(Arrays.asList(
-                mContext.getString(R.string.modifier_keys_caps_lock),
-                mContext.getString(R.string.modifier_keys_ctrl),
-                mContext.getString(R.string.modifier_keys_meta),
-                mContext.getString(R.string.modifier_keys_alt)));
+                mActivity.getString(R.string.modifier_keys_caps_lock),
+                mActivity.getString(R.string.modifier_keys_ctrl),
+                mActivity.getString(R.string.modifier_keys_meta),
+                mActivity.getString(R.string.modifier_keys_alt)));
         for (int i = 0; i < modifierKeys.size(); i++) {
             mRemappableKeyMap.put(modifierKeys.get(i), mRemappableKeyList.get(i));
         }
 
         View dialoglayout  =
-                LayoutInflater.from(mContext).inflate(R.layout.modifier_key_picker_dialog, null);
-        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(mContext);
+                LayoutInflater.from(mActivity).inflate(R.layout.modifier_key_picker_dialog, null);
+        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(mActivity);
         dialogBuilder.setView(dialoglayout);
 
         TextView summary = dialoglayout.findViewById(R.id.modifier_key_picker_summary);
-        CharSequence summaryText = mContext.getString(
+        CharSequence summaryText = mActivity.getString(
                 R.string.modifier_keys_picker_summary, mKeyDefaultName);
         summary.setText(summaryText);
 
@@ -119,14 +127,14 @@
             Spannable itemSummary;
             if (selectedItem.equals(mKeyDefaultName)) {
                 itemSummary = new SpannableString(
-                        mContext.getString(R.string.modifier_keys_default_summary));
+                        mActivity.getString(R.string.modifier_keys_default_summary));
                 itemSummary.setSpan(
                         new ForegroundColorSpan(getColorOfTextColorSecondary()),
                         0, itemSummary.length(), 0);
                 // Set keys to default.
                 int[] keys = mRemappableKeyMap.get(mKeyDefaultName);
                 for (int i = 0; i < keys.length; i++) {
-                    mIm.remapModifierKey(keys[i], keys[i]);
+                    inputManager.remapModifierKey(keys[i], keys[i]);
                 }
             } else {
                 itemSummary = new SpannableString(selectedItem);
@@ -136,29 +144,29 @@
                 int[] fromKeys = mRemappableKeyMap.get(mKeyDefaultName);
                 int[] toKeys = mRemappableKeyMap.get(selectedItem);
                 // CAPS_LOCK only one key, so always choose the left key for remapping.
-                if (isKeyCapsLock(mContext, mKeyDefaultName)) {
-                    mIm.remapModifierKey(fromKeys[0], toKeys[0]);
+                if (isKeyCapsLock(mActivity, mKeyDefaultName)) {
+                    inputManager.remapModifierKey(fromKeys[0], toKeys[0]);
                 }
                 // Remap KEY_LEFT and KEY_RIGHT to CAPS_LOCK.
-                if (!isKeyCapsLock(mContext, mKeyDefaultName)
-                        && isKeyCapsLock(mContext, selectedItem)) {
-                    mIm.remapModifierKey(fromKeys[0], toKeys[0]);
-                    mIm.remapModifierKey(fromKeys[1], toKeys[0]);
+                if (!isKeyCapsLock(mActivity, mKeyDefaultName)
+                        && isKeyCapsLock(mActivity, selectedItem)) {
+                    inputManager.remapModifierKey(fromKeys[0], toKeys[0]);
+                    inputManager.remapModifierKey(fromKeys[1], toKeys[0]);
                 }
                 // Auto handle left and right keys remapping.
-                if (!isKeyCapsLock(mContext, mKeyDefaultName)
-                        && !isKeyCapsLock(mContext, selectedItem)) {
-                    mIm.remapModifierKey(fromKeys[0], toKeys[0]);
-                    mIm.remapModifierKey(fromKeys[1], toKeys[1]);
+                if (!isKeyCapsLock(mActivity, mKeyDefaultName)
+                        && !isKeyCapsLock(mActivity, selectedItem)) {
+                    inputManager.remapModifierKey(fromKeys[0], toKeys[0]);
+                    inputManager.remapModifierKey(fromKeys[1], toKeys[1]);
                 }
             }
-            mPreference.setSummary(itemSummary);
-            modifierKeyDialog.dismiss();
+            dismiss();
+            mActivity.recreate();
         });
 
         Button cancelButton = dialoglayout.findViewById(R.id.modifier_key_cancel_button);
         cancelButton.setOnClickListener(v -> {
-            modifierKeyDialog.dismiss();
+            dismiss();
         });
 
         final Window window = modifierKeyDialog.getWindow();
@@ -207,16 +215,17 @@
         @Override
         public View getView(int i, View view, ViewGroup viewGroup) {
             if (view == null) {
-                view = LayoutInflater.from(mContext).inflate(R.layout.modifier_key_item, null);
+                view = LayoutInflater.from(mActivity).inflate(R.layout.modifier_key_item, null);
             }
             TextView textView = view.findViewById(R.id.modifier_key_text);
             ImageView checkIcon = view.findViewById(R.id.modifier_key_check_icon);
             textView.setText(mList.get(i));
             if (mCurrentItem == i) {
+                mKeyFocus = mList.get(i);
                 textView.setTextColor(getColorOfColorAccentPrimaryVariant());
                 checkIcon.setImageAlpha(255);
                 view.setBackground(
-                        mContext.getDrawable(R.drawable.modifier_key_lisetview_background));
+                        mActivity.getDrawable(R.drawable.modifier_key_lisetview_background));
             } else {
                 textView.setTextColor(getColorOfTextColorPrimary());
                 checkIcon.setImageAlpha(0);
@@ -235,15 +244,15 @@
     }
 
     private int getColorOfTextColorPrimary() {
-        return Utils.getColorAttrDefaultColor(mContext, android.R.attr.textColorPrimary);
+        return Utils.getColorAttrDefaultColor(mActivity, android.R.attr.textColorPrimary);
     }
 
     private int getColorOfTextColorSecondary() {
-        return Utils.getColorAttrDefaultColor(mContext, android.R.attr.textColorSecondary);
+        return Utils.getColorAttrDefaultColor(mActivity, android.R.attr.textColorSecondary);
     }
 
     private int getColorOfColorAccentPrimaryVariant() {
         return Utils.getColorAttrDefaultColor(
-                mContext, com.android.internal.R.attr.materialColorPrimaryContainer);
+                mActivity, com.android.internal.R.attr.materialColorPrimaryContainer);
     }
 }
diff --git a/src/com/android/settings/inputmethod/ModifierKeysPreferenceController.java b/src/com/android/settings/inputmethod/ModifierKeysPreferenceController.java
index 780a980..91caf29 100644
--- a/src/com/android/settings/inputmethod/ModifierKeysPreferenceController.java
+++ b/src/com/android/settings/inputmethod/ModifierKeysPreferenceController.java
@@ -18,12 +18,12 @@
 
 import android.content.Context;
 import android.hardware.input.InputManager;
+import android.os.Bundle;
 import android.text.Spannable;
 import android.text.SpannableString;
 import android.text.style.ForegroundColorSpan;
 import android.view.KeyEvent;
 
-import androidx.fragment.app.DialogFragment;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentManager;
 import androidx.preference.Preference;
@@ -41,8 +41,8 @@
 
 public class ModifierKeysPreferenceController extends BasePreferenceController {
 
-    private static String KEY_TAG = "modifier_keys_dialog_tag";
-    private static String KEY_RESTORE_PREFERENCE = "modifier_keys_restore";
+    private static final String KEY_TAG = "modifier_keys_dialog_tag";
+    private static final String KEY_RESTORE_PREFERENCE = "modifier_keys_restore";
 
     private static final String KEY_PREFERENCE_CAPS_LOCK = "modifier_keys_caps_lock";
     private static final String KEY_PREFERENCE_CTRL = "modifier_keys_ctrl";
@@ -52,6 +52,7 @@
     private Fragment mParent;
     private FragmentManager mFragmentManager;
     private final InputManager mIm;
+    private PreferenceScreen mScreen;
 
     private final List<Integer> mRemappableKeys = new ArrayList<>(
             Arrays.asList(
@@ -82,40 +83,39 @@
     @Override
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
-
         if (mParent == null) {
             return;
         }
+        mScreen = screen;
+        refreshUi();
+    }
 
+    private void refreshUi() {
         for (Map.Entry<Integer, Integer> entry : mIm.getModifierKeyRemapping().entrySet()) {
             int fromKey = entry.getKey();
             int toKey = entry.getValue();
             int index = mRemappableKeys.indexOf(toKey);
 
             if (isCtrl(fromKey) && mRemappableKeys.contains(toKey)) {
-                Preference preference = screen.findPreference(KEY_PREFERENCE_CTRL);
+                Preference preference = mScreen.findPreference(KEY_PREFERENCE_CTRL);
                 preference.setSummary(changeSummaryColor(mKeyNames[index]));
             }
 
             if (isMeta(fromKey) && mRemappableKeys.contains(toKey)) {
-                Preference preference = screen.findPreference(KEY_PREFERENCE_META);
+                Preference preference = mScreen.findPreference(KEY_PREFERENCE_META);
                 preference.setSummary(changeSummaryColor(mKeyNames[index]));
             }
 
             if (isAlt(fromKey) && mRemappableKeys.contains(toKey)) {
-                Preference preference = screen.findPreference(KEY_PREFERENCE_ALT);
+                Preference preference = mScreen.findPreference(KEY_PREFERENCE_ALT);
                 preference.setSummary(changeSummaryColor(mKeyNames[index]));
             }
 
             if (isCapLock(fromKey) && mRemappableKeys.contains(toKey)) {
-                Preference preference = screen.findPreference(KEY_PREFERENCE_CAPS_LOCK);
+                Preference preference = mScreen.findPreference(KEY_PREFERENCE_CAPS_LOCK);
                 preference.setSummary(changeSummaryColor(mKeyNames[index]));
             }
         }
-
-        // The dialog screen depends on the previous selected key's fragment.
-        // In the rotation scenario, we should remove the previous dialog screen first.
-        clearPreviousDialog();
     }
 
     @Override
@@ -133,19 +133,18 @@
     }
 
     private void showModifierKeysDialog(Preference preference) {
-        ModifierKeysPickerDialogFragment fragment =
-                new ModifierKeysPickerDialogFragment(preference, mIm);
-        fragment.setTargetFragment(mParent, 0);
-        fragment.show(mFragmentManager, KEY_TAG);
-    }
-
-    private void clearPreviousDialog() {
         mFragmentManager = mParent.getFragmentManager();
-        DialogFragment preKeysDialogFragment =
-                (DialogFragment) mFragmentManager.findFragmentByTag(KEY_TAG);
-        if (preKeysDialogFragment != null) {
-            preKeysDialogFragment.dismiss();
-        }
+        ModifierKeysPickerDialogFragment fragment = new ModifierKeysPickerDialogFragment();
+        fragment.setTargetFragment(mParent, 0);
+        Bundle bundle = new Bundle();
+        bundle.putString(
+                ModifierKeysPickerDialogFragment.DEFAULT_KEY,
+                preference.getTitle().toString());
+        bundle.putString(
+                ModifierKeysPickerDialogFragment.SELECTION_KEY,
+                preference.getSummary().toString());
+        fragment.setArguments(bundle);
+        fragment.show(mFragmentManager, KEY_TAG);
     }
 
     private Spannable changeSummaryColor(String summary) {
diff --git a/src/com/android/settings/inputmethod/ModifierKeysResetDialogFragment.java b/src/com/android/settings/inputmethod/ModifierKeysResetDialogFragment.java
index 4ca5ddd..755e9dd 100644
--- a/src/com/android/settings/inputmethod/ModifierKeysResetDialogFragment.java
+++ b/src/com/android/settings/inputmethod/ModifierKeysResetDialogFragment.java
@@ -18,25 +18,19 @@
 
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
 
+import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
-import android.content.Context;
 import android.hardware.input.InputManager;
 import android.os.Bundle;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.style.ForegroundColorSpan;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.Window;
 import android.widget.Button;
 
 import androidx.fragment.app.DialogFragment;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settingslib.Utils;
 
 public class ModifierKeysResetDialogFragment extends DialogFragment {
     private static final String MODIFIER_KEYS_CAPS_LOCK = "modifier_keys_caps_lock";
@@ -44,41 +38,36 @@
     private static final String MODIFIER_KEYS_META = "modifier_keys_meta";
     private static final String MODIFIER_KEYS_ALT = "modifier_keys_alt";
 
-    private PreferenceScreen mScreen;
-    private InputManager mIm;
     private String[] mKeys = {
             MODIFIER_KEYS_CAPS_LOCK,
             MODIFIER_KEYS_CTRL,
             MODIFIER_KEYS_META,
             MODIFIER_KEYS_ALT};
 
-    public ModifierKeysResetDialogFragment() {
-    }
-
-    public ModifierKeysResetDialogFragment(PreferenceScreen screen, InputManager inputManager) {
-        mScreen = screen;
-        mIm = inputManager;
-    }
+    public ModifierKeysResetDialogFragment() {}
 
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
         super.onCreateDialog(savedInstanceState);
-        Context mContext = getActivity();
+
+        Activity activity = getActivity();
+        InputManager inputManager = activity.getSystemService(InputManager.class);
         View dialoglayout =
-                LayoutInflater.from(mContext).inflate(R.layout.modifier_key_reset_dialog, null);
-        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(mContext);
+                LayoutInflater.from(activity).inflate(R.layout.modifier_key_reset_dialog, null);
+        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(activity);
         dialogBuilder.setView(dialoglayout);
         AlertDialog modifierKeyResetDialog = dialogBuilder.create();
 
         Button restoreButton = dialoglayout.findViewById(R.id.modifier_key_reset_restore_button);
         restoreButton.setOnClickListener(v -> {
-            resetToDefault();
-            modifierKeyResetDialog.dismiss();
+            inputManager.clearAllModifierKeyRemappings();
+            dismiss();
+            activity.recreate();
         });
 
         Button cancelButton = dialoglayout.findViewById(R.id.modifier_key_reset_cancel_button);
         cancelButton.setOnClickListener(v -> {
-            modifierKeyResetDialog.dismiss();
+            dismiss();
         });
 
         final Window window = modifierKeyResetDialog.getWindow();
@@ -86,25 +75,4 @@
 
         return modifierKeyResetDialog;
     }
-
-    private void resetToDefault() {
-        Context mContext = getActivity();
-        for (int i = 0; i < mKeys.length; i++) {
-            Preference preference = mScreen.findPreference(mKeys[i]);
-            Spannable title = new SpannableString(
-                    mContext.getString(R.string.modifier_keys_default_summary));
-            title.setSpan(
-                    new ForegroundColorSpan(getColorOfTextColorSecondary()),
-                    0, title.length(), 0);
-            preference.setSummary(title);
-        }
-
-        if (mIm != null) {
-            mIm.clearAllModifierKeyRemappings();
-        }
-    }
-
-    private int getColorOfTextColorSecondary() {
-        return Utils.getColorAttrDefaultColor(getActivity(), android.R.attr.textColorSecondary);
-    }
 }
diff --git a/src/com/android/settings/inputmethod/ModifierKeysRestorePreferenceController.java b/src/com/android/settings/inputmethod/ModifierKeysRestorePreferenceController.java
index 4e72fbd..3171487 100644
--- a/src/com/android/settings/inputmethod/ModifierKeysRestorePreferenceController.java
+++ b/src/com/android/settings/inputmethod/ModifierKeysRestorePreferenceController.java
@@ -17,12 +17,10 @@
 package com.android.settings.inputmethod;
 
 import android.content.Context;
-import android.hardware.input.InputManager;
 import android.text.Spannable;
 import android.text.SpannableString;
 import android.text.style.ForegroundColorSpan;
 
-import androidx.fragment.app.DialogFragment;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentManager;
 import androidx.preference.Preference;
@@ -34,16 +32,14 @@
 
 public class ModifierKeysRestorePreferenceController extends BasePreferenceController {
 
-    private static String KEY_TAG = "modifier_keys_dialog_tag";
+    private static final String KEY_TAG = "modifier_keys_restore_dialog_tag";
 
     private Fragment mParent;
     private FragmentManager mFragmentManager;
     private PreferenceScreen mScreen;
-    private final InputManager mIm;
 
     public ModifierKeysRestorePreferenceController(Context context, String key) {
         super(context, key);
-        mIm = context.getSystemService(InputManager.class);
     }
 
     public void setFragment(Fragment parent) {
@@ -57,9 +53,6 @@
             return;
         }
         mScreen = screen;
-        // The dialog screen depends on the previous selected key's fragment.
-        // In the rotation scenario, we should remove the previous dialog first.
-        clearPreviousDialog();
         setResetKeyColor();
     }
 
@@ -78,8 +71,8 @@
     }
 
     private void showResetDialog() {
-        ModifierKeysResetDialogFragment fragment =
-                new ModifierKeysResetDialogFragment(mScreen, mIm);
+        mFragmentManager = mParent.getFragmentManager();
+        ModifierKeysResetDialogFragment fragment = new ModifierKeysResetDialogFragment();
         fragment.setTargetFragment(mParent, 0);
         fragment.show(mFragmentManager, KEY_TAG);
     }
@@ -98,13 +91,4 @@
         return Utils.getColorAttrDefaultColor(
                 mParent.getActivity(), com.android.internal.R.attr.materialColorPrimaryContainer);
     }
-
-    private void clearPreviousDialog() {
-        mFragmentManager = mParent.getFragmentManager();
-        DialogFragment preResetDialogFragment =
-                (DialogFragment) mFragmentManager.findFragmentByTag(KEY_TAG);
-        if (preResetDialogFragment != null) {
-            preResetDialogFragment.dismiss();
-        }
-    }
 }
diff --git a/src/com/android/settings/localepicker/LocaleHelperPreferenceController.java b/src/com/android/settings/localepicker/LocaleHelperPreferenceController.java
index 05c7401..a639c9d 100644
--- a/src/com/android/settings/localepicker/LocaleHelperPreferenceController.java
+++ b/src/com/android/settings/localepicker/LocaleHelperPreferenceController.java
@@ -17,6 +17,8 @@
 package com.android.settings.localepicker;
 
 import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
 
 import androidx.annotation.VisibleForTesting;
 import androidx.preference.PreferenceScreen;
@@ -65,10 +67,14 @@
     }
 
     private void openLocaleLearnMoreLink() {
-        mContext.startActivity(
-                HelpUtils.getHelpIntent(
-                        mContext,
-                        mContext.getString(R.string.link_locale_picker_footer_learn_more),
-                        /*backupContext=*/""));
+        Intent intent = HelpUtils.getHelpIntent(
+                mContext,
+                mContext.getString(R.string.link_locale_picker_footer_learn_more),
+                mContext.getClass().getName());
+        if (intent != null) {
+            mContext.startActivity(intent);
+        } else {
+            Log.w(TAG, "HelpIntent is null");
+        }
     }
 }
diff --git a/src/com/android/settings/regionalpreferences/RegionalFooterPreferenceController.java b/src/com/android/settings/regionalpreferences/RegionalFooterPreferenceController.java
new file mode 100644
index 0000000..6ba9d18
--- /dev/null
+++ b/src/com/android/settings/regionalpreferences/RegionalFooterPreferenceController.java
@@ -0,0 +1,74 @@
+/**
+ * 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.regionalpreferences;
+
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.HelpUtils;
+import com.android.settingslib.widget.FooterPreference;
+
+/**
+ * Preference controller for regional preference footer.
+ */
+public class RegionalFooterPreferenceController extends BasePreferenceController {
+
+    private static final String TAG = "RegionalFooterPreferenceController";
+
+    public RegionalFooterPreferenceController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE_UNSEARCHABLE;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        FooterPreference footerPreference = screen.findPreference(getPreferenceKey());
+        setupFooterPreference(footerPreference);
+    }
+
+    @VisibleForTesting
+    void setupFooterPreference(FooterPreference footerPreference) {
+        if (footerPreference != null) {
+            footerPreference.setLearnMoreAction(v -> openLocaleLearnMoreLink());
+            footerPreference.setLearnMoreText(mContext.getString(
+                    R.string.desc_regional_pref_footer_learn_more));
+        }
+    }
+
+    private void openLocaleLearnMoreLink() {
+        Intent intent = HelpUtils.getHelpIntent(
+                mContext,
+                mContext.getString(R.string.regional_pref_footer_learn_more_link),
+                mContext.getClass().getName());
+        if (intent != null) {
+            mContext.startActivity(intent);
+        } else {
+            Log.w(TAG, "HelpIntent is null");
+        }
+    }
+}
diff --git a/tests/unit/src/com/android/settings/regionalpreferences/RegionalFooterPreferenceControllerTest.java b/tests/unit/src/com/android/settings/regionalpreferences/RegionalFooterPreferenceControllerTest.java
new file mode 100644
index 0000000..f019793
--- /dev/null
+++ b/tests/unit/src/com/android/settings/regionalpreferences/RegionalFooterPreferenceControllerTest.java
@@ -0,0 +1,62 @@
+/**
+ * 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.regionalpreferences;
+
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.os.Looper;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.settingslib.widget.FooterPreference;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class RegionalFooterPreferenceControllerTest {
+
+    private static String KEY_FOOTER_PREFERENCE = "regional_pref_footer";
+    private Context mContext;
+    private RegionalFooterPreferenceController mRegionalFooterPreferenceController;
+
+    @Mock
+    private FooterPreference mMockFooterPreference;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+        mContext = ApplicationProvider.getApplicationContext();
+        mRegionalFooterPreferenceController = new RegionalFooterPreferenceController(mContext,
+                KEY_FOOTER_PREFERENCE);
+    }
+
+    @Test
+    public void setupFooterPreference_shouldSetAsTextInLearnMore() {
+        mRegionalFooterPreferenceController.setupFooterPreference(mMockFooterPreference);
+        verify(mMockFooterPreference).setLearnMoreText(anyString());
+    }
+}