Merge "Import translations. DO NOT MERGE ANYWHERE" into tm-qpr-dev
diff --git a/res/layout/face_enroll_button.xml b/res/layout/face_enroll_button.xml
index 09094d5..6266650 100644
--- a/res/layout/face_enroll_button.xml
+++ b/res/layout/face_enroll_button.xml
@@ -18,7 +18,9 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:minHeight="?android:attr/listPreferredItemHeight">
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart">
 
     <Button
         android:id="@+id/security_settings_face_settings_enroll_button"
@@ -26,7 +28,6 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="start"
-        android:layout_marginStart="20dp"
         android:text="@string/security_settings_face_settings_enroll"/>
 
 </LinearLayout>
\ No newline at end of file
diff --git a/res/layout/face_remove_button.xml b/res/layout/face_remove_button.xml
index ea860d5..2c2497a 100644
--- a/res/layout/face_remove_button.xml
+++ b/res/layout/face_remove_button.xml
@@ -18,7 +18,9 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:minHeight="?android:attr/listPreferredItemHeight">
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart">
 
     <Button
         android:id="@+id/security_settings_face_settings_remove_button"
@@ -26,7 +28,6 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="start"
-        android:layout_marginStart="20dp"
         android:text="@string/security_settings_face_settings_remove_face_model"/>
 
 </LinearLayout>
\ No newline at end of file
diff --git a/res/layout/locale_drag_cell.xml b/res/layout/locale_drag_cell.xml
index 7b932f3..47bf70a 100644
--- a/res/layout/locale_drag_cell.xml
+++ b/res/layout/locale_drag_cell.xml
@@ -56,6 +56,17 @@
         android:layout_toStartOf="@+id/dragHandle"
         android:layout_below="@id/label"/>
 
+    <TextView
+        android:id="@+id/default_locale"
+        style="@style/LanguageCheckboxAndLabel"
+        android:layout_marginTop="-28dp"
+        android:paddingStart="56dp"
+        android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+        android:textColor="?android:textColorSecondary"
+        android:text="@string/desc_current_default_language"
+        android:layout_toStartOf="@+id/dragHandle"
+        android:layout_below="@id/label"/>
+
     <ImageView
         android:id="@+id/dragHandle"
         android:layout_width="wrap_content"
diff --git a/res/layout/notification_history_app_layout.xml b/res/layout/notification_history_app_layout.xml
index 7d53b4d..143fff8 100644
--- a/res/layout/notification_history_app_layout.xml
+++ b/res/layout/notification_history_app_layout.xml
@@ -35,42 +35,36 @@
             android:id="@+id/icon"
             android:layout_width="24dp"
             android:layout_height="24dp"
-            android:layout_marginEnd="14dp"
             android:scaleType="centerInside"
             app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintEnd_toStartOf="@id/text_start_guideline"
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toTopOf="parent" />
 
-        <androidx.constraintlayout.widget.Guideline
-            android:id="@+id/text_start_guideline"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:orientation="vertical"
-            app:layout_constraintStart_toEndOf="@id/icon" />
-
         <TextView
             android:id="@+id/label"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
+            android:layout_marginStart="14dp"
             android:ellipsize="end"
             android:lines="1"
             android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title"
+            android:textDirection="locale"
             app:layout_constraintBottom_toTopOf="@id/count"
             app:layout_constraintEnd_toStartOf="@id/expand_button_wrapper"
-            app:layout_constraintStart_toEndOf="@id/text_start_guideline"
+            app:layout_constraintStart_toEndOf="@id/icon"
             app:layout_constraintTop_toTopOf="parent" />
 
         <TextView
             android:id="@+id/count"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
+            android:layout_marginStart="14dp"
             android:paddingTop="4dp"
             android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification"
             android:textDirection="locale"
             app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintEnd_toStartOf="@id/expand_button_wrapper"
-            app:layout_constraintStart_toEndOf="@id/text_start_guideline"
+            app:layout_constraintStart_toEndOf="@id/icon"
             app:layout_constraintTop_toBottomOf="@id/label" />
 
         <FrameLayout
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 921cb52..c4edf6b 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -489,6 +489,12 @@
     <!-- Title for the locale picker activity. [CHAR LIMIT=30]-->
     <string name="language_picker_title">Languages</string>
 
+    <!-- Title for category of the locale picker . [CHAR LIMIT=50]-->
+    <string name="language_picker_category_title">Preferred language order</string>
+
+    <!-- Description for indication of current system default language. [CHAR LIMIT=50]-->
+    <string name="desc_current_default_language">System language</string>
+
     <!-- Menu item in the locale menu. Will remove the selected locales. [CHAR LIMIT=30] -->
     <string name="locale_remove_menu">Remove</string>
 
@@ -502,13 +508,13 @@
     <string name="locale_picker_category_title">Preferred Language</string>
 
     <!-- Title for the Apps' locale menu entry [CHAR LIMIT=50]-->
-    <string name="app_locales_picker_menu_title">App Languages</string>
+    <string name="app_locales_picker_menu_title">App languages</string>
 
     <!-- Summary for the app's locale picker activity. [CHAR LIMIT=50]-->
     <string name="app_locale_picker_summary">Set the language for each app</string>
 
     <!-- Title for the App's locale picker activity. [CHAR LIMIT=50]-->
-    <string name="app_locale_picker_title">App Language</string>
+    <string name="app_locale_picker_title">App language</string>
 
     <!-- Category for the suggested app's locales. [CHAR LIMIT=50]-->
     <string name="suggested_app_locales_title">Suggested languages</string>
@@ -531,6 +537,18 @@
     <!-- Description for introduction of the locale selection supported of app list [CHAR LIMIT=NONE]-->
     <string name="desc_app_locale_selection_supported">Only apps that support language selection are shown here.</string>
 
+    <!-- Description for the introduction to language picker activity. [CHAR LIMIT=NONE]-->
+    <string name="desc_introduction_of_language_picker">Your system, apps, and websites use the first supported language from your preferred languages.</string>
+
+    <!-- Description for the notice of language picker. [CHAR LIMIT=NONE]-->
+    <string name="desc_notice_of_language_picker">To select a language for each app, go to app language settings.</string>
+
+    <!-- Title for locale helper page [CHAR LIMIT=NONE] -->
+    <string name="desc_locale_helper_footer_general">Learn more about languages</string>
+
+    <!-- Link for Locale helper page. [CHAR LIMIT=NONE]-->
+    <string name="link_locale_picker_footer_learn_more" translatable="false">https://support.google.com/android?p=per_language_app_settings</string>
+
     <!-- The title of the confirmation dialog shown when the user selects one / several languages and tries to remove them [CHAR LIMIT=60] -->
     <plurals name="dlg_remove_locales_title">
         <item quantity="one">Remove selected language?</item>
@@ -546,7 +564,7 @@
     <string name="dlg_remove_locales_error_message">Keep at least one preferred language</string>
 
     <!-- This text shows in the language picker when the system is not translated into that languages [CHAR LIMIT=80] -->
-    <string name="locale_not_translated">May not be available in some apps</string>
+    <string name="locale_not_translated">Not available as system language</string>
 
     <!-- Label for an accessibility action that moves a language up in the ordered language list [CHAR LIMIT=20] -->
     <string name="action_drag_label_move_up">Move up</string>
@@ -1184,11 +1202,11 @@
     <!-- Title shown in fingerprint enrollment dialog once enrollment is completed [CHAR LIMIT=29] -->
     <string name="security_settings_fingerprint_enroll_finish_title">Fingerprint added</string>
     <!-- Message shown in fingerprint enrollment dialog once enrollment is completed (tablet) [CHAR LIMIT=NONE] -->
-    <string name="security_settings_fingerprint_enroll_finish_v2_message" product="tablet">Fingerprint Unlock improves the more you use it to unlock your tablet or verify it\u2019s you in apps</string>
+    <string name="security_settings_fingerprint_enroll_finish_v2_message" product="tablet">Now you can use your fingerprint to unlock your tablet or verify it\u2019s you, like when you sign in to apps</string>
     <!-- Message shown in fingerprint enrollment dialog once enrollment is completed (device) [CHAR LIMIT=NONE] -->
-    <string name="security_settings_fingerprint_enroll_finish_v2_message" product="device">Fingerprint Unlock improves the more you use it to unlock your device or verify it\u2019s you in apps</string>
+    <string name="security_settings_fingerprint_enroll_finish_v2_message" product="device">Now you can use your fingerprint to unlock your device or verify it\u2019s you, like when you sign in to apps</string>
     <!-- Message shown in fingerprint enrollment dialog once enrollment is completed (default) [CHAR LIMIT=NONE] -->
-    <string name="security_settings_fingerprint_enroll_finish_v2_message" product="default">Fingerprint Unlock improves the more you use it to unlock your phone or verify it\u2019s you in apps</string>
+    <string name="security_settings_fingerprint_enroll_finish_v2_message" product="default">Now you can use your fingerprint to unlock your phone or verify it\u2019s you, like when you sign in to apps</string>
     <!-- Button text to skip enrollment of fingerprint [CHAR LIMIT=40] -->
     <string name="security_settings_fingerprint_enroll_enrolling_skip">Do it later</string>
     <!-- Accessibility message for fingerprint enrollment asking the user to place the tip of their finger on the fingerprint sensor [CHAR LIMIT=NONE] -->
diff --git a/res/xml/languages.xml b/res/xml/languages.xml
new file mode 100644
index 0000000..0f45540
--- /dev/null
+++ b/res/xml/languages.xml
@@ -0,0 +1,42 @@
+<?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.
+  -->
+
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    android:title="@string/language_settings">
+
+    <com.android.settingslib.widget.TopIntroPreference
+        android:title="@string/desc_introduction_of_language_picker"
+        android:persistent="false"
+        android:selectable="false"/>
+
+    <PreferenceCategory
+        android:title="@string/language_picker_category_title">
+        <com.android.settingslib.widget.LayoutPreference
+            android:key="languages_picker"
+            android:layout="@layout/locale_order_list" />
+    </PreferenceCategory>
+
+    <com.android.settingslib.widget.FooterPreference
+        android:key="footer_languages_picker"
+        android:title="@string/desc_notice_of_language_picker"
+        android:persistent="false"
+        android:selectable="false"
+        settings:controller="com.android.settings.localepicker.LocaleHelperPreferenceController"/>
+
+</PreferenceScreen>
diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentForSetupWizard.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentForSetupWizard.java
index cb5ca75..12a9886 100644
--- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentForSetupWizard.java
+++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentForSetupWizard.java
@@ -52,11 +52,17 @@
      */
     private void hidePreferenceSettingComponents() {
         // Intro
-        mTopIntroPreference.setVisible(false);
+        if (mTopIntroPreference != null) {
+            mTopIntroPreference.setVisible(false);
+        }
         // Setting of magnification type
-        mSettingsPreference.setVisible(false);
+        if (mSettingsPreference != null) {
+            mSettingsPreference.setVisible(false);
+        }
         // Setting of following typing
-        mFollowingTypingSwitchPreference.setVisible(false);
+        if (mFollowingTypingSwitchPreference != null) {
+            mFollowingTypingSwitchPreference.setVisible(false);
+        }
     }
 
     @Override
diff --git a/src/com/android/settings/applications/AppLocaleUtil.java b/src/com/android/settings/applications/AppLocaleUtil.java
index 8c3671e..79406f0 100644
--- a/src/com/android/settings/applications/AppLocaleUtil.java
+++ b/src/com/android/settings/applications/AppLocaleUtil.java
@@ -100,8 +100,8 @@
      */
     public static boolean isAppLocaleSupported(Context context, String packageName) {
         LocaleList localeList = getPackageLocales(context, packageName);
-        if (localeList != null && localeList.size() > 0) {
-            return true;
+        if (localeList != null) {
+            return localeList.size() > 0;
         }
 
         if (FeatureFlagUtils.isEnabled(
diff --git a/src/com/android/settings/applications/appinfo/AppLocalePreferenceController.java b/src/com/android/settings/applications/appinfo/AppLocalePreferenceController.java
index f406d87..6bf94a6 100644
--- a/src/com/android/settings/applications/appinfo/AppLocalePreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/AppLocalePreferenceController.java
@@ -22,7 +22,6 @@
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
 import android.text.TextUtils;
-import android.util.FeatureFlagUtils;
 import android.util.Log;
 
 import androidx.annotation.VisibleForTesting;
@@ -51,9 +50,7 @@
 
     @Override
     public int getAvailabilityStatus() {
-        boolean isFeatureOn = FeatureFlagUtils
-                .isEnabled(mContext, FeatureFlagUtils.SETTINGS_APP_LANGUAGE_SELECTION);
-        return isFeatureOn && canDisplayLocaleUi() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
+        return canDisplayLocaleUi() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
     }
 
     @Override
diff --git a/src/com/android/settings/applications/appinfo/ManageAppLocalePreferenceController.java b/src/com/android/settings/applications/appinfo/ManageAppLocalePreferenceController.java
deleted file mode 100644
index aa12b62..0000000
--- a/src/com/android/settings/applications/appinfo/ManageAppLocalePreferenceController.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2021 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.applications.appinfo;
-
-import android.content.Context;
-import android.util.FeatureFlagUtils;
-
-import com.android.settings.core.BasePreferenceController;
-
-/**
- * A controller to update current locale information of application
- * and a entry to launch {@link ManageApplications}.
- * TODO(209775925) After feature release, this class may be removed.
- */
-public class ManageAppLocalePreferenceController extends BasePreferenceController {
-    public ManageAppLocalePreferenceController(Context context, String key) {
-        super(context, key);
-    }
-
-    @Override
-    public int getAvailabilityStatus() {
-        return FeatureFlagUtils
-                .isEnabled(mContext, FeatureFlagUtils.SETTINGS_APP_LANGUAGE_SELECTION)
-                ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
-    }
-}
diff --git a/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollFindSensor.java b/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollFindSensor.java
index 7256511..1ae5dae 100644
--- a/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollFindSensor.java
+++ b/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollFindSensor.java
@@ -77,7 +77,7 @@
 
         @NonNull
         public AlertDialog.Builder onCreateDialogBuilder() {
-            return new AlertDialog.Builder(getContext())
+            return new AlertDialog.Builder(getActivity(), R.style.GlifV2ThemeAlertDialog)
                     .setTitle(R.string.setup_fingerprint_enroll_skip_title)
                     .setPositiveButton(R.string.skip_anyway_button_label, this)
                     .setNegativeButton(R.string.go_back_button_label, this)
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java
index 45ae8c5..f3fec8e 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java
@@ -697,12 +697,13 @@
 
         final Map<Integer, Map<Integer, BatteryDiffData>> batteryUsageData =
                 DataProcessor.getBatteryUsageData(context, batteryHistoryMap);
-        return batteryUsageData == null
-                ? null
-                : batteryUsageData
-                        .get(BatteryChartViewModel.SELECTED_INDEX_ALL)
-                        .get(BatteryChartViewModel.SELECTED_INDEX_ALL)
-                        .getAppDiffEntryList();
+        if (batteryUsageData == null) {
+            return null;
+        }
+        BatteryDiffData allBatteryDiffData = batteryUsageData.get(
+                BatteryChartViewModel.SELECTED_INDEX_ALL).get(
+                BatteryChartViewModel.SELECTED_INDEX_ALL);
+        return allBatteryDiffData == null ? null : allBatteryDiffData.getAppDiffEntryList();
     }
 
     /** Used for {@link AppBatteryPreferenceController}. */
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java
index e668b37..cfdd851 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java
@@ -595,6 +595,9 @@
 
     // Searches the corresponding trapezoid index from x location.
     private int getTrapezoidIndex(float x) {
+        if (mTrapezoidSlots == null) {
+            return BatteryChartViewModel.SELECTED_INDEX_INVALID;
+        }
         for (int index = 0; index < mTrapezoidSlots.length; index++) {
             final TrapezoidSlot slot = mTrapezoidSlots[index];
             if (x >= slot.mLeft - mTrapezoidHOffset
diff --git a/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java b/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java
index ab9110d..b3c2e30 100644
--- a/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java
+++ b/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java
@@ -43,7 +43,6 @@
 import java.util.List;
 import java.util.Locale;
 
-
 class LocaleDragAndDropAdapter
         extends RecyclerView.Adapter<LocaleDragAndDropAdapter.CustomViewHolder> {
 
@@ -154,8 +153,10 @@
         final LocaleDragCell dragCell = holder.getLocaleDragCell();
         final String label = feedItem.getFullNameNative();
         final String description = feedItem.getFullNameInUiLanguage();
+
         dragCell.setLabelAndDescription(label, description);
         dragCell.setLocalized(feedItem.isTranslated());
+        dragCell.setCurrentDefault(feedItem.getLocale().equals(Locale.getDefault()));
         dragCell.setMiniLabel(mNumberFormatter.format(i + 1));
         dragCell.setShowCheckbox(mRemoveMode);
         dragCell.setShowMiniLabel(!mRemoveMode);
diff --git a/src/com/android/settings/localepicker/LocaleDragCell.java b/src/com/android/settings/localepicker/LocaleDragCell.java
index ea86189..2f4cfef 100644
--- a/src/com/android/settings/localepicker/LocaleDragCell.java
+++ b/src/com/android/settings/localepicker/LocaleDragCell.java
@@ -33,6 +33,7 @@
     private CheckBox mCheckbox;
     private TextView mMiniLabel;
     private TextView mLocalized;
+    private TextView mCurrentDefault;
     private ImageView mDragHandle;
 
     public LocaleDragCell(Context context, AttributeSet attrs) {
@@ -44,6 +45,7 @@
         super.onFinishInflate();
         mLabel = (TextView) findViewById(R.id.label);
         mLocalized = (TextView) findViewById(R.id.l10nWarn);
+        mCurrentDefault = (TextView) findViewById(R.id.default_locale);
         mMiniLabel = (TextView) findViewById(R.id.miniLabel);
         mCheckbox = (CheckBox) findViewById(R.id.checkbox);
         mDragHandle = (ImageView) findViewById(R.id.dragHandle);
@@ -100,6 +102,14 @@
         invalidate();
     }
 
+    /**
+     * Indicate current locale is system default.
+     */
+    public void setCurrentDefault(boolean isCurrentDefault) {
+        mCurrentDefault.setVisibility(isCurrentDefault ? VISIBLE : GONE);
+        invalidate();
+    }
+
     public ImageView getDragHandle() {
         return mDragHandle;
     }
diff --git a/src/com/android/settings/localepicker/LocaleHelperPreferenceController.java b/src/com/android/settings/localepicker/LocaleHelperPreferenceController.java
new file mode 100644
index 0000000..05c7401
--- /dev/null
+++ b/src/com/android/settings/localepicker/LocaleHelperPreferenceController.java
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+package com.android.settings.localepicker;
+
+import android.content.Context;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settingslib.HelpUtils;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.widget.FooterPreference;
+
+/**
+ * A controller to update current locale information of application.
+ */
+public class LocaleHelperPreferenceController extends AbstractPreferenceController {
+    private static final String TAG = LocaleHelperPreferenceController.class.getSimpleName();
+
+    private static final String KEY_FOOTER_LANGUAGE_PICKER = "footer_languages_picker";
+
+    public LocaleHelperPreferenceController(Context context) {
+        super(context);
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return true;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_FOOTER_LANGUAGE_PICKER;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        FooterPreference footerPreference = screen.findPreference(getPreferenceKey());
+        updateFooterPreference(footerPreference);
+    }
+
+    @VisibleForTesting
+    void updateFooterPreference(FooterPreference footerPreference) {
+        if (footerPreference != null) {
+            footerPreference.setLearnMoreAction(v -> openLocaleLearnMoreLink());
+            footerPreference.setLearnMoreText(mContext.getString(
+                    R.string.desc_locale_helper_footer_general));
+        }
+    }
+
+    private void openLocaleLearnMoreLink() {
+        mContext.startActivity(
+                HelpUtils.getHelpIntent(
+                        mContext,
+                        mContext.getString(R.string.link_locale_picker_footer_learn_more),
+                        /*backupContext=*/""));
+    }
+}
diff --git a/src/com/android/settings/localepicker/LocaleListEditor.java b/src/com/android/settings/localepicker/LocaleListEditor.java
index eac2dd1..9db3468 100644
--- a/src/com/android/settings/localepicker/LocaleListEditor.java
+++ b/src/com/android/settings/localepicker/LocaleListEditor.java
@@ -36,6 +36,7 @@
 
 import androidx.annotation.VisibleForTesting;
 import androidx.appcompat.app.AlertDialog;
+import androidx.preference.PreferenceScreen;
 import androidx.recyclerview.widget.RecyclerView;
 
 import com.android.internal.app.LocalePicker;
@@ -46,6 +47,7 @@
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.search.SearchIndexable;
 import com.android.settingslib.search.SearchIndexableRaw;
+import com.android.settingslib.widget.LayoutPreference;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -64,6 +66,7 @@
     private static final int REQUEST_LOCALE_PICKER = 0;
 
     private static final String INDEX_KEY_ADD_LANGUAGE = "add_language";
+    private static final String KEY_LANGUAGES_PICKER = "languages_picker";
 
     private LocaleDragAndDropAdapter mAdapter;
     private Menu mMenu;
@@ -72,6 +75,9 @@
     private boolean mShowingRemoveDialog;
     private boolean mIsUiRestricted;
 
+    private LayoutPreference mLocalePickerPreference;
+    private LocaleHelperPreferenceController mLocaleHelperPreferenceController;
+
     public LocaleListEditor() {
         super(DISALLOW_CONFIG_LOCALE);
     }
@@ -86,6 +92,14 @@
         super.onCreate(savedInstanceState);
         setHasOptionsMenu(true);
 
+        addPreferencesFromResource(R.xml.languages);
+        final Activity activity = getActivity();
+        activity.setTitle(R.string.language_picker_title);
+        mLocaleHelperPreferenceController = new LocaleHelperPreferenceController(activity);
+        final PreferenceScreen screen = getPreferenceScreen();
+        mLocalePickerPreference = screen.findPreference(KEY_LANGUAGES_PICKER);
+        mLocaleHelperPreferenceController.displayPreference(screen);
+
         LocaleStore.fillCache(this.getContext());
         final List<LocaleStore.LocaleInfo> feedsList = getUserLocaleList();
         mAdapter = new LocaleDragAndDropAdapter(this.getContext(), feedsList);
@@ -93,11 +107,8 @@
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstState) {
-        final View result = super.onCreateView(inflater, container, savedInstState);
-        final View myLayout = inflater.inflate(R.layout.locale_order_list, (ViewGroup) result);
-
-        configureDragAndDrop(myLayout);
-        return result;
+        configureDragAndDrop(mLocalePickerPreference);
+        return super.onCreateView(inflater, container, savedInstState);
     }
 
     @Override
@@ -287,8 +298,8 @@
         return result;
     }
 
-    private void configureDragAndDrop(View view) {
-        final RecyclerView list = view.findViewById(R.id.dragList);
+    private void configureDragAndDrop(LayoutPreference layout) {
+        final RecyclerView list = layout.findViewById(R.id.dragList);
         final LocaleLinearLayoutManager llm = new LocaleLinearLayoutManager(getContext(), mAdapter);
         llm.setAutoMeasureEnabled(true);
         list.setLayoutManager(llm);
@@ -297,7 +308,7 @@
         mAdapter.setRecyclerView(list);
         list.setAdapter(mAdapter);
 
-        mAddLanguage = view.findViewById(R.id.add_language);
+        mAddLanguage = layout.findViewById(R.id.add_language);
         mAddLanguage.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
diff --git a/src/com/android/settings/network/apn/ApnEditor.java b/src/com/android/settings/network/apn/ApnEditor.java
index 926c77e..bfb4943 100644
--- a/src/com/android/settings/network/apn/ApnEditor.java
+++ b/src/com/android/settings/network/apn/ApnEditor.java
@@ -78,7 +78,8 @@
     private static final String KEY_MVNO_TYPE = "mvno_type";
     private static final String KEY_PASSWORD = "apn_password";
 
-    private static final int MENU_DELETE = Menu.FIRST;
+    @VisibleForTesting
+    static final int MENU_DELETE = Menu.FIRST;
     private static final int MENU_SAVE = Menu.FIRST + 1;
     private static final int MENU_CANCEL = Menu.FIRST + 2;
 
@@ -148,6 +149,17 @@
     String mDefaultApnRoamingProtocol;
     private String[] mReadOnlyApnFields;
     private boolean mReadOnlyApn;
+    /**
+     * The APN deletion feature within menu is aligned with the APN adding feature.
+     * Having only one of them could lead to a UX which not that make sense from user's
+     * perspective.
+     *
+     * mIsAddApnAllowed stores the configuration value reading from
+     * CarrierConfigManager.KEY_ALLOW_ADDING_APNS_BOOL to support the presentation
+     * control of the menu options. When false, delete option would be invisible to
+     * the end user.
+     */
+    private boolean mIsAddApnAllowed;
     private Uri mCarrierUri;
     private boolean mIsCarrierIdApn;
 
@@ -282,7 +294,7 @@
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
 
         initApnEditorUi();
-        getCarrierCustomizedConfig();
+        getCarrierCustomizedConfig(getContext());
 
         Uri uri = null;
         if (action.equals(Intent.ACTION_EDIT)) {
@@ -826,7 +838,8 @@
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         super.onCreateOptionsMenu(menu, inflater);
         // If it's a new APN, then cancel will delete the new entry in onPause
-        if (!mNewApn && !mReadOnlyApn) {
+        // If APN add is not allowed, delete might lead to issue regarding recovery
+        if (!mNewApn && !mReadOnlyApn && mIsAddApnAllowed) {
             menu.add(0, MENU_DELETE, 0, R.string.menu_delete)
                 .setIcon(R.drawable.ic_delete);
         }
@@ -1319,13 +1332,15 @@
         mMvnoMatchData = (EditTextPreference) findPreference("mvno_match_data");
     }
 
-    private void getCarrierCustomizedConfig() {
+    @VisibleForTesting
+    protected void getCarrierCustomizedConfig(Context context) {
         mReadOnlyApn = false;
         mReadOnlyApnTypes = null;
         mReadOnlyApnFields = null;
+        mIsAddApnAllowed = true;
 
         final CarrierConfigManager configManager = (CarrierConfigManager)
-                getSystemService(Context.CARRIER_CONFIG_SERVICE);
+            context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
         if (configManager != null) {
             final PersistableBundle b = configManager.getConfigForSubId(mSubId);
             if (b != null) {
@@ -1357,6 +1372,11 @@
                     Log.d(TAG, "onCreate: default apn roaming protocol: "
                             + mDefaultApnRoamingProtocol);
                 }
+
+                mIsAddApnAllowed = b.getBoolean(CarrierConfigManager.KEY_ALLOW_ADDING_APNS_BOOL);
+                if (!mIsAddApnAllowed) {
+                    Log.d(TAG, "onCreate: not allow to add new APN");
+                }
             }
         }
     }
diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollFindSensorTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollFindSensorTest.java
index a198d86..54a7fb1 100644
--- a/tests/robotests/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollFindSensorTest.java
+++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollFindSensorTest.java
@@ -22,7 +22,6 @@
 
 import android.content.Intent;
 import android.hardware.fingerprint.FingerprintManager;
-import android.widget.Button;
 
 import androidx.appcompat.app.AlertDialog;
 
@@ -66,6 +65,23 @@
 
     @Test
     public void fingerprintEnroll_showsAlert_whenClickingSkip() {
+        final AlertDialog alertDialog = setupAlertDialog();
+        final ShadowAlertDialogCompat shadowAlertDialog = ShadowAlertDialogCompat.shadowOf(
+                alertDialog);
+        final int titleRes = R.string.setup_fingerprint_enroll_skip_title;
+
+        assertThat(application.getString(titleRes)).isEqualTo(shadowAlertDialog.getTitle());
+    }
+
+    @Test
+    public void fingerprintEnroll_showsAlert_setSudTheme() {
+        final AlertDialog alertDialog = setupAlertDialog();
+
+        assertThat(alertDialog.getContext().getThemeResId()).isEqualTo(
+                R.style.GlifV2ThemeAlertDialog);
+    }
+
+    private AlertDialog setupAlertDialog() {
         final Intent intent = new Intent()
                 // Set the challenge token so the confirm screen will not be shown
                 .putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, new byte[0]);
@@ -80,9 +96,6 @@
         final AlertDialog alertDialog = ShadowAlertDialogCompat.getLatestAlertDialog();
         assertThat(alertDialog).isNotNull();
 
-        final ShadowAlertDialogCompat shadowAlertDialog = ShadowAlertDialogCompat.shadowOf(
-                alertDialog);
-        final int titleRes = R.string.setup_fingerprint_enroll_skip_title;
-        assertThat(application.getString(titleRes)).isEqualTo(shadowAlertDialog.getTitle());
+        return alertDialog;
     }
 }
diff --git a/tests/robotests/src/com/android/settings/network/apn/ApnEditorTest.java b/tests/robotests/src/com/android/settings/network/apn/ApnEditorTest.java
index 0a430cd..f03b6d8 100644
--- a/tests/robotests/src/com/android/settings/network/apn/ApnEditorTest.java
+++ b/tests/robotests/src/com/android/settings/network/apn/ApnEditorTest.java
@@ -17,14 +17,15 @@
 package com.android.settings.network.apn;
 
 import static com.google.common.truth.Truth.assertThat;
-
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doNothing;
 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 android.content.ContentResolver;
@@ -34,22 +35,21 @@
 import android.content.res.Resources;
 import android.database.Cursor;
 import android.net.Uri;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
 import android.view.KeyEvent;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
-
 import androidx.fragment.app.FragmentActivity;
 import androidx.preference.EditTextPreference;
 import androidx.preference.ListPreference;
 import androidx.preference.MultiSelectListPreference;
 import androidx.preference.SwitchPreference;
-
 import com.android.settings.R;
 import com.android.settings.network.ProxySubscriptionManager;
 import com.android.settings.network.apn.ApnEditor.ApnData;
 import com.android.settings.testutils.shadow.ShadowFragment;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -103,13 +103,15 @@
     private FragmentActivity mActivity;
     @Mock
     private ProxySubscriptionManager mProxySubscriptionMgr;
-
+    @Mock
+    private CarrierConfigManager mCarrierConfigManager;
     @Captor
     private ArgumentCaptor<Uri> mUriCaptor;
 
     private ApnEditor mApnEditorUT;
     private Context mContext;
     private Resources mResources;
+    private PersistableBundle mBundle = new PersistableBundle();
 
     @Before
     public void setUp() {
@@ -127,6 +129,10 @@
         doReturn(mContext.getTheme()).when(mActivity).getTheme();
         doReturn(mContext.getContentResolver()).when(mActivity).getContentResolver();
 
+        doReturn(mCarrierConfigManager).when(mContext)
+                .getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt());
+
         setMockPreference(mContext);
         mApnEditorUT.mApnData = new FakeApnData(APN_DATA);
         mApnEditorUT.sNotSet = "Not Set";
@@ -379,6 +385,20 @@
         verify(mApnEditorUT).finish();
     }
 
+    @Test
+    public void testDeleteApnData_shouldNotPresentMenuWhenNotSupportAdding() {
+        mBundle.putBoolean(CarrierConfigManager.KEY_ALLOW_ADDING_APNS_BOOL, false);
+
+        MenuItem item = Mockito.mock(MenuItem.class);
+        Menu menu = Mockito.mock(Menu.class);
+        doReturn(item).when(menu).add(anyInt(), anyInt(), anyInt(), anyInt());
+
+        mApnEditorUT.getCarrierCustomizedConfig(mContext);
+        mApnEditorUT.onCreateOptionsMenu(menu, null);
+
+        verify(menu, times(0)).add(anyInt(), eq(ApnEditor.MENU_DELETE), anyInt(), anyInt());
+    }
+
     @Test(expected = ClassCastException.class)
     public void testApnData_invalidIntegerType_throwsInvalidTypeException() {
         // GIVEN a ApnData constructed from cursor
diff --git a/tests/unit/src/com/android/settings/applications/appinfo/AppLocalePreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/appinfo/AppLocalePreferenceControllerTest.java
index 526b6cc..805041c 100644
--- a/tests/unit/src/com/android/settings/applications/appinfo/AppLocalePreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/applications/appinfo/AppLocalePreferenceControllerTest.java
@@ -19,7 +19,6 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import android.content.Context;
-import android.util.FeatureFlagUtils;
 
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -49,22 +48,10 @@
                 return mCanDisplayLocaleUi;
             }
         };
-        FeatureFlagUtils
-                .setEnabled(mContext, FeatureFlagUtils.SETTINGS_APP_LANGUAGE_SELECTION, true);
     }
 
     @Test
-    public void getAvailabilityStatus_canShowUiButFeatureFlagOff_shouldReturnUnavailable() {
-        mCanDisplayLocaleUi = true;
-        FeatureFlagUtils
-                .setEnabled(mContext, FeatureFlagUtils.SETTINGS_APP_LANGUAGE_SELECTION, false);
-
-        assertThat(mController.getAvailabilityStatus())
-                .isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
-    }
-
-    @Test
-    public void getAvailabilityStatus_canShowUiAndFeatureFlagOn_shouldReturnAvailable() {
+    public void getAvailabilityStatus_canShowUi_shouldReturnAvailable() {
         mCanDisplayLocaleUi = true;
 
         assertThat(mController.getAvailabilityStatus())
@@ -72,20 +59,10 @@
     }
 
     @Test
-    public void getAvailabilityStatus_featureFlagOnButCanNotShowUi_shouldReturnUnavailable() {
+    public void getAvailabilityStatus_canNotShowUi_shouldReturnUnavailable() {
         mCanDisplayLocaleUi = false;
 
         assertThat(mController.getAvailabilityStatus())
                 .isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
     }
-
-    @Test
-    public void getAvailabilityStatus_featureFlagOffAndCanNotShowUi_shouldReturnUnavailable() {
-        mCanDisplayLocaleUi = false;
-        FeatureFlagUtils
-                .setEnabled(mContext, FeatureFlagUtils.SETTINGS_APP_LANGUAGE_SELECTION, false);
-
-        assertThat(mController.getAvailabilityStatus())
-                .isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
-    }
 }
diff --git a/tests/unit/src/com/android/settings/applications/appinfo/ManageAppLocalePreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/appinfo/ManageAppLocalePreferenceControllerTest.java
deleted file mode 100644
index 648c757..0000000
--- a/tests/unit/src/com/android/settings/applications/appinfo/ManageAppLocalePreferenceControllerTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2021 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.applications.appinfo;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.spy;
-
-import android.content.Context;
-import android.util.FeatureFlagUtils;
-
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-
-import com.android.settings.core.BasePreferenceController;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(AndroidJUnit4.class)
-public class ManageAppLocalePreferenceControllerTest {
-    private Context mContext;
-    private ManageAppLocalePreferenceController mController;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContext = spy(ApplicationProvider.getApplicationContext());
-        mController = spy(new ManageAppLocalePreferenceController(mContext, "a key"));
-
-        FeatureFlagUtils
-                .setEnabled(mContext, FeatureFlagUtils.SETTINGS_APP_LANGUAGE_SELECTION, true);
-    }
-
-    @Test
-    public void getAvailabilityStatus_featureFlagOff_shouldReturnUnavailable() {
-        FeatureFlagUtils
-                .setEnabled(mContext, FeatureFlagUtils.SETTINGS_APP_LANGUAGE_SELECTION, false);
-
-        assertThat(mController.getAvailabilityStatus())
-                .isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
-    }
-
-    @Test
-    public void getAvailabilityStatus_featureFlagOn_shouldReturnAvailable() {
-        assertThat(mController.getAvailabilityStatus())
-                .isEqualTo(BasePreferenceController.AVAILABLE);
-    }
-}
diff --git a/tests/unit/src/com/android/settings/localepicker/LocaleHelperPreferenceControllerTest.java b/tests/unit/src/com/android/settings/localepicker/LocaleHelperPreferenceControllerTest.java
new file mode 100644
index 0000000..31b8e79
--- /dev/null
+++ b/tests/unit/src/com/android/settings/localepicker/LocaleHelperPreferenceControllerTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+package com.android.settings.localepicker;
+
+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 LocaleHelperPreferenceControllerTest {
+    private Context mContext;
+    private LocaleHelperPreferenceController mLocaleHelperPreferenceController;
+
+    @Mock
+    private FooterPreference mMockFooterPreference;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+        mContext = ApplicationProvider.getApplicationContext();
+        mLocaleHelperPreferenceController = new LocaleHelperPreferenceController(mContext);
+    }
+
+    @Test
+    public void updateFooterPreference_setFooterPreference_hasClickAction() {
+        mLocaleHelperPreferenceController.updateFooterPreference(mMockFooterPreference);
+        verify(mMockFooterPreference).setLearnMoreText(anyString());
+    }
+}