Merge "Reduce jank when revoking notification permission" into udc-dev
diff --git a/res/drawable/ic_important_outline.xml b/res/drawable/ic_important_outline.xml
index 7a628bb..642582c 100644
--- a/res/drawable/ic_important_outline.xml
+++ b/res/drawable/ic_important_outline.xml
@@ -20,6 +20,7 @@
         android:height="24dp"
         android:viewportWidth="24.0"
         android:viewportHeight="24.0"
+        android:autoMirrored="true"
         android:tint="?android:attr/colorControlNormal">
     <path
         android:fillColor="@android:color/white"
diff --git a/res/layout/panel_layout.xml b/res/layout/panel_layout.xml
index e55c1e6..0d5ccfb 100644
--- a/res/layout/panel_layout.xml
+++ b/res/layout/panel_layout.xml
@@ -20,6 +20,7 @@
     android:id="@+id/panel_container"
     android:layout_width="@dimen/settings_panel_width"
     android:layout_height="wrap_content"
+    android:fitsSystemWindows="true"
     android:layout_gravity="center_horizontal"
     android:background="@drawable/settings_panel_rounded_top_corner_background" >
 
diff --git a/res/layout/zen_mode_senders_overlay_image.xml b/res/layout/zen_mode_senders_overlay_image.xml
deleted file mode 100644
index eba98da..0000000
--- a/res/layout/zen_mode_senders_overlay_image.xml
+++ /dev/null
@@ -1,26 +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.
--->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content">
-    <RelativeLayout android:id="@+id/zen_mode_settings_senders_overlay_view"
-                    android:layout_centerInParent="true"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="@dimen/zen_conversations_image_margin_vertical"
-                    android:layout_marginBottom="@dimen/zen_conversations_image_margin_vertical">
-    </RelativeLayout>
-</RelativeLayout>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 57e47f2..2f3d875 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -51,9 +51,6 @@
     <dimen name="conversation_icon_size">32dp</dimen>
 
     <dimen name="zen_mode_settings_button_margin_vertical">24dp</dimen>
-    <dimen name="zen_conversations_image_margin_vertical">24dp</dimen>
-    <dimen name="zen_conversations_icon_offset">32dp</dimen>
-    <dimen name="zen_conversations_icon_size">50dp</dimen>
     <dimen name="zen_schedule_rule_checkbox_padding">7dp</dimen>
     <dimen name="zen_schedule_day_margin">17dp</dimen>
 
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 4ae9e67..a5b1aa1 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -8177,8 +8177,6 @@
 
     <!-- [CHAR LIMIT=120] Zen mode settings: Title for conversations settings page -->
     <string name="zen_mode_conversations_title">Conversations</string>
-    <!-- [CHAR LIMIT=120] Zen mode settings: Header for conversations settings page -->
-    <string name="zen_mode_conversations_section_title">Conversations that can interrupt</string>
     <string name="zen_mode_from_all_conversations">All conversations</string>
     <string name="zen_mode_from_important_conversations">Priority conversations</string>
     <!-- [CHAR LIMIT=40] Version of the above for "priority conversations" when it is a non-first member of a list -->
@@ -11698,6 +11696,10 @@
     <string name="dream_complications_toggle_title">Show additional information</string>
     <!-- The summary of what overlays this toggle controls [CHAR LIMIT=none] -->
     <string name="dream_complications_toggle_summary">Display things like the time, weather, or other information on the screen saver</string>
+    <!-- The title of the toggle which enables/disables the home controls button on top of the screen saver [CHAR LIMIT=none] -->
+    <string name="dream_home_controls_toggle_title">Show home controls</string>
+    <!-- The summary of the home controls toggle [CHAR LIMIT=none] -->
+    <string name="dream_home_controls_toggle_summary">Show home controls button from the screen saver</string>
     <!-- The title of the category to show for the screensaver miscellaneous settings [CHAR LIMIT=none] -->
     <string name="dream_more_settings_category">More settings</string>
     <!-- The title of the screen saver setup page [CHAR LIMIT=none] -->
diff --git a/res/values/themes.xml b/res/values/themes.xml
index dd3882e..eeba1c7 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -220,6 +220,7 @@
     <!-- Note that Dialog themes do not set list dividers -->
     <style name="Theme.Panel" parent="@*android:style/Theme.DeviceDefault.Settings.Dialog">
         <item name="android:windowBackground">@null</item>
+        <item name="android:windowTranslucentNavigation">true</item>
         <item name="android:dividerHorizontal">@*android:drawable/list_divider_material</item>
         <item name="android:windowNoTitle">true</item>
         <item name="android:listDivider">@*android:drawable/list_divider_material</item>
diff --git a/res/xml/dream_fragment_overview.xml b/res/xml/dream_fragment_overview.xml
index 3321fd1..8377a06 100644
--- a/res/xml/dream_fragment_overview.xml
+++ b/res/xml/dream_fragment_overview.xml
@@ -46,6 +46,12 @@
         android:summary="@string/dream_complications_toggle_summary"
         settings:controller="com.android.settings.dream.DreamComplicationPreferenceController"/>
 
+    <SwitchPreference
+        android:key="dream_home_controls_toggle"
+        android:title="@string/dream_home_controls_toggle_title"
+        android:summary="@string/dream_home_controls_toggle_summary"
+        settings:controller="com.android.settings.dream.DreamHomeControlsPreferenceController"/>
+
     <com.android.settings.applications.SpacePreference
         android:layout_height="16dp" />
 
diff --git a/res/xml/language_settings.xml b/res/xml/language_settings.xml
index 69fa4d2..ff41a0b 100644
--- a/res/xml/language_settings.xml
+++ b/res/xml/language_settings.xml
@@ -37,5 +37,13 @@
                 android:name="classname"
                 android:value="com.android.settings.applications.appinfo.AppLocaleDetails" />
         </Preference>
+
+        <Preference
+            android:key="regional_preferences"
+            android:title="@string/regional_preferences_title"
+            android:summary="@string/regional_preferences_summary"
+            android:fragment="com.android.settings.regionalpreferences.RegionalPreferencesEntriesFragment"
+            settings:controller="com.android.settings.regionalpreferences.RegionalPreferencesController" />
+
     </PreferenceCategory>
 </PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/zen_mode_conversations_settings.xml b/res/xml/zen_mode_conversations_settings.xml
deleted file mode 100644
index e72d03c..0000000
--- a/res/xml/zen_mode_conversations_settings.xml
+++ /dev/null
@@ -1,31 +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.
--->
-<PreferenceScreen
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:key="zen_mode_conversations_settings"
-    android:title="@string/zen_mode_conversations_title">
-    <!-- Conversations -->
-    <PreferenceCategory
-        android:key="zen_mode_conversations_radio_buttons"
-        android:title="@string/zen_mode_conversations_section_title">
-
-        <!-- Senders image -->
-        <com.android.settingslib.widget.LayoutPreference
-            android:key="zen_mode_conversations_image"
-            android:layout="@layout/zen_mode_senders_overlay_image"
-            android:selectable="false"/>
-    </PreferenceCategory>
-</PreferenceScreen>
\ No newline at end of file
diff --git a/src/com/android/settings/accessibility/AccessibilityHearingAidsFragment.java b/src/com/android/settings/accessibility/AccessibilityHearingAidsFragment.java
index 85783b73..4641a15 100644
--- a/src/com/android/settings/accessibility/AccessibilityHearingAidsFragment.java
+++ b/src/com/android/settings/accessibility/AccessibilityHearingAidsFragment.java
@@ -18,6 +18,7 @@
 
 import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;
 
+import android.app.settings.SettingsEnums;
 import android.content.ComponentName;
 import android.content.Context;
 import android.os.Bundle;
@@ -72,8 +73,7 @@
 
     @Override
     public int getMetricsCategory() {
-        // TODO(b/262839191): To be updated settings_enums.proto
-        return 0;
+        return SettingsEnums.ACCESSIBILITY_HEARING_AID_SETTINGS;
     }
 
     @Override
diff --git a/src/com/android/settings/accessibility/FlashNotificationsPreferenceFragment.java b/src/com/android/settings/accessibility/FlashNotificationsPreferenceFragment.java
index f35d1a1..f796474 100644
--- a/src/com/android/settings/accessibility/FlashNotificationsPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/FlashNotificationsPreferenceFragment.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.accessibility;
 
+import android.app.settings.SettingsEnums;
 import android.content.Context;
 
 import com.android.settings.R;
@@ -41,8 +42,7 @@
 
     @Override
     public int getMetricsCategory() {
-        // TODO: Flash notifications have to add SettingsEnums.
-        return 0;
+        return SettingsEnums.FLASH_NOTIFICATION_SETTINGS;
     }
 
     @Override
diff --git a/src/com/android/settings/accessibility/HearingDevicePairingDetail.java b/src/com/android/settings/accessibility/HearingDevicePairingDetail.java
index aa9b587..35997dd 100644
--- a/src/com/android/settings/accessibility/HearingDevicePairingDetail.java
+++ b/src/com/android/settings/accessibility/HearingDevicePairingDetail.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.accessibility;
 
+import android.app.settings.SettingsEnums;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothUuid;
 import android.bluetooth.le.ScanFilter;
@@ -61,8 +62,7 @@
 
     @Override
     public int getMetricsCategory() {
-        // TODO(b/262839191): To be updated settings_enums.proto
-        return 0;
+        return SettingsEnums.HEARING_AID_PAIRING;
     }
 
     @Override
diff --git a/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java b/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
index f8c1f64..8621e6f 100644
--- a/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
+++ b/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
@@ -24,7 +24,9 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
 import android.credentials.CredentialManager;
 import android.credentials.CredentialProviderInfo;
 import android.credentials.SetEnabledProvidersException;
@@ -32,6 +34,7 @@
 import android.os.Bundle;
 import android.os.OutcomeReceiver;
 import android.os.UserHandle;
+import android.text.TextUtils;
 import android.util.IconDrawableFactory;
 import android.util.Log;
 
@@ -162,10 +165,54 @@
 
         PreferenceGroup group = screen.findPreference(getPreferenceKey());
         Context context = screen.getContext();
+        mPrefs.putAll(buildPreferenceList(context, group));
+    }
 
-        for (CredentialProviderInfo service : mServices) {
-            group.addPreference(createPreference(context, service));
+    /** Aggregates the list of services and builds a list of UI prefs to show. */
+    @VisibleForTesting
+    public Map<String, SwitchPreference> buildPreferenceList(
+            Context context, PreferenceGroup group) {
+        // Group the services by package name.
+        Map<String, List<CredentialProviderInfo>> groupedInfos = new HashMap<>();
+        for (CredentialProviderInfo cpi : mServices) {
+            String packageName = cpi.getServiceInfo().packageName;
+            if (!groupedInfos.containsKey(packageName)) {
+                groupedInfos.put(packageName, new ArrayList<>());
+            }
+
+            groupedInfos.get(packageName).add(cpi);
         }
+
+        // Build the pref list.
+        Map<String, SwitchPreference> output = new HashMap<>();
+        for (String packageName : groupedInfos.keySet()) {
+            List<CredentialProviderInfo> infos = groupedInfos.get(packageName);
+            CredentialProviderInfo firstInfo = infos.get(0);
+            ServiceInfo firstServiceInfo = firstInfo.getServiceInfo();
+            CharSequence title = firstInfo.getLabel(context);
+            Drawable icon = firstInfo.getServiceIcon(context);
+
+            if (infos.size() > 1) {
+                // If there is more than one then group them under the package.
+                ApplicationInfo appInfo = firstServiceInfo.applicationInfo;
+                if (appInfo.nonLocalizedLabel != null) {
+                    title = appInfo.loadLabel(mPm);
+                }
+                icon = mIconFactory.getBadgedIcon(appInfo, getUser());
+            }
+
+            // If there is no title then don't show anything.
+            if (TextUtils.isEmpty(title)) {
+                continue;
+            }
+
+            // Build the pref and add it to the output & group.
+            SwitchPreference pref = addProviderPreference(context, title, icon, packageName);
+            output.put(packageName, pref);
+            group.addPreference(pref);
+        }
+
+        return output;
     }
 
     /** Creates a preference object based on the provider info. */
@@ -238,7 +285,6 @@
         final SwitchPreference pref = new SwitchPreference(prefContext);
         pref.setTitle(title);
         pref.setChecked(mEnabledPackageNames.contains(packageName));
-        mPrefs.put(packageName, pref);
 
         if (icon != null) {
             pref.setIcon(Utils.getSafeIcon(icon));
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingFragment.java b/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingFragment.java
index ea89053..6c435a2 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingFragment.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingFragment.java
@@ -20,6 +20,7 @@
 
 import static com.android.settings.bluetooth.BluetoothDeviceDetailsFragment.KEY_DEVICE_ADDRESS;
 
+import android.app.settings.SettingsEnums;
 import android.bluetooth.BluetoothDevice;
 import android.content.Context;
 import android.util.Log;
@@ -32,10 +33,8 @@
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
-import com.android.settingslib.search.SearchIndexable;
 
 /** Settings fragment containing bluetooth audio routing. */
-@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
 public class BluetoothDetailsAudioRoutingFragment extends RestrictedDashboardFragment {
 
     public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
@@ -73,8 +72,7 @@
 
     @Override
     public int getMetricsCategory() {
-        // TODO(b/262839191): To be updated settings_enums.proto
-        return 0;
+        return SettingsEnums.BLUETOOTH_AUDIO_ROUTING;
     }
 
     @Override
diff --git a/src/com/android/settings/dream/DreamHomeControlsPreferenceController.java b/src/com/android/settings/dream/DreamHomeControlsPreferenceController.java
new file mode 100644
index 0000000..b39f3b1
--- /dev/null
+++ b/src/com/android/settings/dream/DreamHomeControlsPreferenceController.java
@@ -0,0 +1,68 @@
+/*
+ * 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.dream;
+
+import android.content.Context;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.R;
+import com.android.settings.core.TogglePreferenceController;
+import com.android.settingslib.dream.DreamBackend;
+
+/**
+ * Controller for the {@link androidx.preference.SwitchPreference} which controls if dream
+ * overlays should be enabled.
+ */
+public class DreamHomeControlsPreferenceController extends TogglePreferenceController {
+    private final DreamBackend mBackend;
+
+    public DreamHomeControlsPreferenceController(Context context, String key) {
+        this(context, key, DreamBackend.getInstance(context));
+    }
+
+    @VisibleForTesting
+    public DreamHomeControlsPreferenceController(Context context, String key,
+            DreamBackend dreamBackend) {
+        super(context, key);
+        mBackend = dreamBackend;
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        final boolean supported =
+                mBackend.getSupportedComplications()
+                        .contains(DreamBackend.COMPLICATION_TYPE_HOME_CONTROLS);
+        return supported ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
+    }
+
+    @Override
+    public boolean isChecked() {
+        return mBackend.getEnabledComplications().contains(
+                DreamBackend.COMPLICATION_TYPE_HOME_CONTROLS);
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        mBackend.setHomeControlsEnabled(isChecked);
+        return true;
+    }
+
+    @Override
+    public int getSliceHighlightMenuRes() {
+        return R.string.menu_key_display;
+    }
+}
diff --git a/src/com/android/settings/inputmethod/NewKeyboardLayoutEnabledLocalesFragment.java b/src/com/android/settings/inputmethod/NewKeyboardLayoutEnabledLocalesFragment.java
index 2db3382..0f49ee1 100644
--- a/src/com/android/settings/inputmethod/NewKeyboardLayoutEnabledLocalesFragment.java
+++ b/src/com/android/settings/inputmethod/NewKeyboardLayoutEnabledLocalesFragment.java
@@ -37,10 +37,10 @@
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.inputmethod.NewKeyboardSettingsUtils.KeyboardInfo;
 
-import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
-import java.util.Locale;
-import java.util.Map;
 
 public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
         implements InputManager.InputDeviceListener {
@@ -53,7 +53,7 @@
     private int mUserId;
     private int mInputDeviceId;
     private Context mContext;
-    private Map<String, KeyboardInfo> mKeyboardLanguageLayouts = new HashMap<>();
+    private ArrayList<KeyboardInfo> mKeyboardInfoList = new ArrayList<>();
 
     @Override
     public void onActivityCreated(final Bundle icicle) {
@@ -74,8 +74,16 @@
         PreferenceScreen preferenceScreen = getPreferenceScreen();
         preferenceScreen.removeAll();
         List<InputMethodInfo> infoList = mImm.getEnabledInputMethodListAsUser(mUserId);
+        Collections.sort(infoList, new Comparator<InputMethodInfo>() {
+            public int compare(InputMethodInfo o1, InputMethodInfo o2) {
+                String s1 = o1.loadLabel(mContext.getPackageManager()).toString();
+                String s2 = o2.loadLabel(mContext.getPackageManager()).toString();
+                return s1.compareTo(s2);
+            }
+        });
+
         for (InputMethodInfo info : infoList) {
-            mKeyboardLanguageLayouts.clear();
+            mKeyboardInfoList.clear();
             List<InputMethodSubtype> subtypes =
                     mImm.getEnabledInputMethodSubtypeList(info, true);
             for (InputMethodSubtype subtype : subtypes) {
@@ -88,51 +96,58 @@
     }
 
     private void mapLanguageWithLayout(InputMethodInfo info, InputMethodSubtype subtype) {
+        CharSequence subtypeLabel = getSubtypeLabel(mContext, info, subtype);
         KeyboardLayout[] keyboardLayouts = getKeyboardLayouts(info, subtype);
         String layout = getKeyboardLayout(info, subtype);
-        String language = getLanguage(info, subtype);
+
         if (layout != null) {
             for (int i = 0; i < keyboardLayouts.length; i++) {
                 if (keyboardLayouts[i].getDescriptor().equals(layout)) {
                     KeyboardInfo keyboardInfo = new KeyboardInfo(
-                            language,
+                            subtypeLabel,
                             keyboardLayouts[i].getLabel(),
                             info,
                             subtype);
-                    mKeyboardLanguageLayouts.put(subtype.getLanguageTag(), keyboardInfo);
+                    mKeyboardInfoList.add(keyboardInfo);
                     break;
                 }
             }
         } else {
             // if there is no auto-selected layout, we should show "Default"
             KeyboardInfo keyboardInfo = new KeyboardInfo(
-                    language,
+                    subtypeLabel,
                     mContext.getString(R.string.keyboard_default_layout),
                     info,
                     subtype);
-            mKeyboardLanguageLayouts.put(subtype.getLanguageTag(), keyboardInfo);
+            mKeyboardInfoList.add(keyboardInfo);
         }
     }
 
     private void updatePreferenceLayout(PreferenceScreen preferenceScreen, InputMethodInfo info) {
-        if (mKeyboardLanguageLayouts.isEmpty()) {
+        if (mKeyboardInfoList.isEmpty()) {
             return;
         }
         PreferenceCategory preferenceCategory = new PreferenceCategory(mContext);
-        preferenceCategory.setTitle(info.loadLabel(mContext.getPackageManager()).toString());
+        preferenceCategory.setTitle(info.loadLabel(mContext.getPackageManager()));
         preferenceCategory.setKey(info.getPackageName());
         preferenceScreen.addPreference(preferenceCategory);
-        for (Map.Entry<String, KeyboardInfo> entry : mKeyboardLanguageLayouts.entrySet()) {
+        Collections.sort(mKeyboardInfoList, new Comparator<KeyboardInfo>() {
+            public int compare(KeyboardInfo o1, KeyboardInfo o2) {
+                String s1 = o1.getSubtypeLabel().toString();
+                String s2 = o2.getSubtypeLabel().toString();
+                return s1.compareTo(s2);
+            }
+        });
+
+        for (KeyboardInfo keyboardInfo : mKeyboardInfoList) {
             final Preference pref = new Preference(mContext);
-            String key = "keyboard_language_" + entry.getKey();
-            NewKeyboardSettingsUtils.KeyboardInfo keyboardInfo = entry.getValue();
-            pref.setKey(key);
-            pref.setTitle(keyboardInfo.getLanguage());
+            pref.setKey(keyboardInfo.getPrefId());
+            pref.setTitle(keyboardInfo.getSubtypeLabel());
             pref.setSummary(keyboardInfo.getLayout());
             pref.setOnPreferenceClickListener(
                     preference -> {
                         showKeyboardLayoutPicker(
-                                keyboardInfo.getLanguage(),
+                                keyboardInfo.getSubtypeLabel(),
                                 keyboardInfo.getLayout(),
                                 mInputDeviceIdentifier,
                                 mUserId,
@@ -215,7 +230,7 @@
     }
 
     private void showKeyboardLayoutPicker(
-            String language,
+            CharSequence subtypeLabel,
             String layout,
             InputDeviceIdentifier inputDeviceIdentifier,
             int userId,
@@ -229,7 +244,7 @@
         arguments.putParcelable(
                 NewKeyboardSettingsUtils.EXTRA_INPUT_METHOD_SUBTYPE, inputMethodSubtype);
         arguments.putInt(NewKeyboardSettingsUtils.EXTRA_USER_ID, userId);
-        arguments.putString(NewKeyboardSettingsUtils.EXTRA_TITLE, language);
+        arguments.putCharSequence(NewKeyboardSettingsUtils.EXTRA_TITLE, subtypeLabel);
         arguments.putString(NewKeyboardSettingsUtils.EXTRA_KEYBOARD_LAYOUT, layout);
         new SubSettingLauncher(mContext)
                 .setSourceMetricsCategory(getMetricsCategory())
@@ -248,16 +263,9 @@
                 mInputDeviceIdentifier, mUserId, info, subtype);
     }
 
-    private String getLanguage(InputMethodInfo info, InputMethodSubtype subtype) {
-        String language;
-        if (subtype.getLanguageTag().isEmpty()) {
-            language = subtype.getDisplayName(
-                    mContext,
-                    info.getPackageName(),
-                    info.getServiceInfo().applicationInfo).toString();
-        } else {
-            language = Locale.forLanguageTag(subtype.getLanguageTag()).getDisplayName();
-        }
-        return language;
+    private CharSequence getSubtypeLabel(
+            Context context, InputMethodInfo info, InputMethodSubtype subtype) {
+        return subtype.getDisplayName(
+                context, info.getPackageName(), info.getServiceInfo().applicationInfo);
     }
 }
diff --git a/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerContent.java b/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerContent.java
index 605095f..761e95e 100644
--- a/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerContent.java
+++ b/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerContent.java
@@ -36,7 +36,7 @@
         super.onAttach(context);
         InputManager inputManager = getContext().getSystemService(InputManager.class);
         Bundle arguments = getArguments();
-        final String title = arguments.getString(NewKeyboardSettingsUtils.EXTRA_TITLE);
+        final CharSequence title = arguments.getCharSequence(NewKeyboardSettingsUtils.EXTRA_TITLE);
         final String layout = arguments.getString(NewKeyboardSettingsUtils.EXTRA_KEYBOARD_LAYOUT);
         final int userId = arguments.getInt(NewKeyboardSettingsUtils.EXTRA_USER_ID);
         final InputDeviceIdentifier identifier =
diff --git a/src/com/android/settings/inputmethod/NewKeyboardSettingsUtils.java b/src/com/android/settings/inputmethod/NewKeyboardSettingsUtils.java
index dda5500..506d1e7 100644
--- a/src/com/android/settings/inputmethod/NewKeyboardSettingsUtils.java
+++ b/src/com/android/settings/inputmethod/NewKeyboardSettingsUtils.java
@@ -72,24 +72,28 @@
     }
 
     static class KeyboardInfo {
-        String mLanguage;
+        CharSequence mSubtypeLabel;
         String mLayout;
         InputMethodInfo mInputMethodInfo;
         InputMethodSubtype mInputMethodSubtype;
 
         KeyboardInfo(
-                String language,
+                CharSequence subtypeLabel,
                 String layout,
                 InputMethodInfo inputMethodInfo,
                 InputMethodSubtype inputMethodSubtype) {
-            mLanguage = language;
+            mSubtypeLabel = subtypeLabel;
             mLayout = layout;
             mInputMethodInfo = inputMethodInfo;
             mInputMethodSubtype = inputMethodSubtype;
         }
 
-        String getLanguage() {
-            return mLanguage;
+        String getPrefId() {
+            return mInputMethodInfo.getId() + "_" + mInputMethodSubtype.hashCode();
+        }
+
+        CharSequence getSubtypeLabel() {
+            return mSubtypeLabel;
         }
 
         String getLayout() {
diff --git a/src/com/android/settings/language/LanguagePreferenceController.java b/src/com/android/settings/language/LanguagePreferenceController.java
index 08033cd..cbccb00 100644
--- a/src/com/android/settings/language/LanguagePreferenceController.java
+++ b/src/com/android/settings/language/LanguagePreferenceController.java
@@ -16,12 +16,22 @@
 
 package com.android.settings.language;
 
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.util.FeatureFlagUtils;
 
+import com.android.settings.Settings;
 import com.android.settings.core.BasePreferenceController;
 
+/**
+ * This is a display controller for new language activity entry.
+ * TODO(b/273642892): When new layout is on board, this class shall be removed.
+ */
 public class LanguagePreferenceController extends BasePreferenceController {
+    private static final String TAG = LanguagePreferenceController.class.getSimpleName();
+
+    private boolean mCacheIsFeatureOn = false;
 
     public LanguagePreferenceController(Context context, String key) {
         super(context, key);
@@ -31,6 +41,27 @@
     public int getAvailabilityStatus() {
         boolean isFeatureOn = FeatureFlagUtils
                 .isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
+
+        // LanguageSettingsActivity is a new entry page for new language layout.
+        // LanguageAndInputSettingsActivity is existed entry page for current language layout.
+        if (mCacheIsFeatureOn != isFeatureOn) {
+            setActivityEnabled(
+                    mContext, Settings.LanguageAndInputSettingsActivity.class, !isFeatureOn);
+            setActivityEnabled(mContext, Settings.LanguageSettingsActivity.class, isFeatureOn);
+            mCacheIsFeatureOn = isFeatureOn;
+        }
         return isFeatureOn ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
     }
+
+    private static void setActivityEnabled(Context context, Class klass, final boolean isEnabled) {
+        PackageManager packageManager = context.getPackageManager();
+
+        ComponentName componentName =
+                new ComponentName(context, klass);
+        final int flag = isEnabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED :
+                PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+
+        packageManager.setComponentEnabledSetting(
+                componentName, flag, PackageManager.DONT_KILL_APP);
+    }
 }
\ No newline at end of file
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
index d5b2c2e..a9c9218 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -272,7 +272,7 @@
                 use(OpenNetworkSelectPagePreferenceController.class).init(mSubId);
         final AutoSelectPreferenceController autoSelectPreferenceController =
                 use(AutoSelectPreferenceController.class)
-                        .init(mSubId)
+                        .init(getLifecycle(), mSubId)
                         .addListener(openNetworkSelectPagePreferenceController);
         use(NetworkPreferenceCategoryController.class).init(mSubId)
                 .setChildren(Arrays.asList(autoSelectPreferenceController));
diff --git a/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java b/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java
index 72d9e91..f46a452 100644
--- a/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java
+++ b/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java
@@ -34,8 +34,10 @@
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.util.Log;
 
 import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.Lifecycle;
 import androidx.lifecycle.LifecycleObserver;
 import androidx.lifecycle.OnLifecycleEvent;
 import androidx.preference.Preference;
@@ -45,6 +47,7 @@
 import com.android.settings.R;
 import com.android.settings.network.AllowedNetworkTypesListener;
 import com.android.settings.network.CarrierConfigCache;
+import com.android.settings.network.helper.ServiceStateStatus;
 import com.android.settings.network.telephony.MobileNetworkUtils;
 import com.android.settings.network.telephony.TelephonyTogglePreferenceController;
 import com.android.settingslib.utils.ThreadUtils;
@@ -62,6 +65,9 @@
 public class AutoSelectPreferenceController extends TelephonyTogglePreferenceController
         implements LifecycleObserver{
     private static final long MINIMUM_DIALOG_TIME_MILLIS = TimeUnit.SECONDS.toMillis(1);
+    private static final String LOG_TAG = "AutoSelectPreferenceController";
+    private static final String INTERNAL_LOG_TAG_INIT = "Init";
+    private static final String INTERNAL_LOG_TAG_AFTERSET = "AfterSet";
 
     private final Handler mUiHandler;
     private PreferenceScreen mPreferenceScreen;
@@ -76,6 +82,7 @@
     private AtomicBoolean mUpdatingConfig;
     private int mCacheOfModeStatus;
     private AtomicLong mRecursiveUpdate;
+    ServiceStateStatus mServiceStateStatus;
 
     public AutoSelectPreferenceController(Context context, String key) {
         super(context, key);
@@ -129,12 +136,6 @@
 
     @Override
     public boolean isChecked() {
-        if (!mUpdatingConfig.get()) {
-            mCacheOfModeStatus = mTelephonyManager.getNetworkSelectionMode();
-            for (OnNetworkSelectModeListener lsn : mListeners) {
-                lsn.onNetworkSelectModeUpdated(mCacheOfModeStatus);
-            }
-        }
         return mCacheOfModeStatus == TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
     }
 
@@ -197,12 +198,22 @@
 
             //Update UI in UI thread
             final long durationMillis = SystemClock.elapsedRealtime() - startMillis;
+
             mUiHandler.postDelayed(() -> {
-                mRecursiveUpdate.getAndIncrement();
-                mSwitchPreference.setEnabled(true);
-                mSwitchPreference.setChecked(isChecked());
-                mRecursiveUpdate.decrementAndGet();
-                dismissProgressBar();
+                ThreadUtils.postOnBackgroundThread(() -> {
+                    queryNetworkSelectionMode(INTERNAL_LOG_TAG_AFTERSET);
+
+                    //Update UI in UI thread
+                    mUiHandler.post(() -> {
+                        mRecursiveUpdate.getAndIncrement();
+                        if (mSwitchPreference != null) {
+                            mSwitchPreference.setEnabled(true);
+                            mSwitchPreference.setChecked(isChecked());
+                        }
+                        mRecursiveUpdate.decrementAndGet();
+                        dismissProgressBar();
+                    });
+                });
             }, Math.max(MINIMUM_DIALOG_TIME_MILLIS - durationMillis, 0));
         });
     }
@@ -210,7 +221,7 @@
     /**
      * Initialization based on given subscription id.
      **/
-    public AutoSelectPreferenceController init(int subId) {
+    public AutoSelectPreferenceController init(Lifecycle lifecycle, int subId) {
         mSubId = subId;
         mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
                 .createForSubscriptionId(mSubId);
@@ -221,6 +232,29 @@
                 CarrierConfigManager.KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL)
                 : false;
 
+        mServiceStateStatus = new ServiceStateStatus(lifecycle, mTelephonyManager,
+                new HandlerExecutor(mUiHandler)) {
+            @Override
+            protected void setValue(ServiceState status) {
+                if (status == null) {
+                    return;
+                }
+                updateUiAutoSelectValue(status);
+            }
+        };
+
+        ThreadUtils.postOnBackgroundThread(() -> {
+            queryNetworkSelectionMode(INTERNAL_LOG_TAG_INIT);
+
+            //Update UI in UI thread
+            mUiHandler.post(() -> {
+                if (mSwitchPreference != null) {
+                    mRecursiveUpdate.getAndIncrement();
+                    mSwitchPreference.setChecked(isChecked());
+                    mRecursiveUpdate.decrementAndGet();
+                }
+            });
+        });
         return this;
     }
 
@@ -230,6 +264,41 @@
         return this;
     }
 
+    private void queryNetworkSelectionMode(String tag) {
+        mCacheOfModeStatus = mTelephonyManager.getNetworkSelectionMode();
+        Log.d(LOG_TAG, tag + ": query commend done. mCacheOfModeStatus: " + mCacheOfModeStatus);
+        updateListenerValue();
+    }
+
+    @VisibleForTesting
+    void updateUiAutoSelectValue(ServiceState status) {
+        if (status == null) {
+            return;
+        }
+        if (!mUpdatingConfig.get()) {
+            int networkSelectionMode = status.getIsManualSelection()
+                    ? TelephonyManager.NETWORK_SELECTION_MODE_MANUAL
+                    : TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
+            if (mCacheOfModeStatus == networkSelectionMode) {
+                return;
+            }
+            mCacheOfModeStatus = networkSelectionMode;
+            Log.d(LOG_TAG, "updateUiAutoSelectValue: mCacheOfModeStatus: " + mCacheOfModeStatus);
+            updateListenerValue();
+
+            mRecursiveUpdate.getAndIncrement();
+            updateState(mSwitchPreference);
+            mRecursiveUpdate.decrementAndGet();
+
+        }
+    }
+
+    private void updateListenerValue() {
+        for (OnNetworkSelectModeListener lsn : mListeners) {
+            lsn.onNetworkSelectModeUpdated(mCacheOfModeStatus);
+        }
+    }
+
     private void showAutoSelectProgressBar() {
         if (mProgressDialog == null) {
             mProgressDialog = new ProgressDialog(mContext);
diff --git a/src/com/android/settings/notification/DockAudioMediaPreferenceController.java b/src/com/android/settings/notification/DockAudioMediaPreferenceController.java
index d9367d5..7170434 100644
--- a/src/com/android/settings/notification/DockAudioMediaPreferenceController.java
+++ b/src/com/android/settings/notification/DockAudioMediaPreferenceController.java
@@ -19,6 +19,8 @@
 import static com.android.settings.notification.SettingPref.TYPE_GLOBAL;
 
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.res.Resources;
 import android.provider.Settings.Global;
 
@@ -41,7 +43,7 @@
             DEFAULT_DOCK_AUDIO_MEDIA, DOCK_AUDIO_MEDIA_DISABLED, DOCK_AUDIO_MEDIA_ENABLED) {
             @Override
             public boolean isApplicable(Context context) {
-                return context.getResources().getBoolean(
+                return isLeDesk() && context.getResources().getBoolean(
                     com.android.settings.R.bool.has_dock_settings);
             }
 
@@ -60,4 +62,18 @@
             }
         };
     }
+
+    /**
+     * Checks the state of docking type
+     * @return true if it is low-end dock types
+     */
+    private boolean isLeDesk() {
+        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_DOCK_EVENT);
+        Intent dockStatus = mContext.registerReceiver(null, intentFilter);
+        if (dockStatus == null) {
+            return false;
+        }
+        int dockState = dockStatus.getIntExtra(Intent.EXTRA_DOCK_STATE, -1);
+        return dockState == Intent.EXTRA_DOCK_STATE_LE_DESK;
+    }
 }
diff --git a/src/com/android/settings/notification/zen/ZenModeBackend.java b/src/com/android/settings/notification/zen/ZenModeBackend.java
index 85f9aee..1079865 100644
--- a/src/com/android/settings/notification/zen/ZenModeBackend.java
+++ b/src/com/android/settings/notification/zen/ZenModeBackend.java
@@ -312,21 +312,6 @@
         return R.string.zen_mode_from_no_conversations;
     }
 
-    protected int getConversationSummary() {
-        int conversationType = getPriorityConversationSenders();
-
-        switch (conversationType) {
-            case NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE:
-                return R.string.zen_mode_from_all_conversations;
-            case NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT:
-                return R.string.zen_mode_from_important_conversations;
-            case NotificationManager.Policy.CONVERSATION_SENDERS_NONE:
-                return R.string.zen_mode_from_no_conversations;
-            default:
-                return R.string.zen_mode_from_no_conversations;
-        }
-    }
-
     protected int getContactsCallsSummary(ZenPolicy policy) {
         int peopleType = policy.getPriorityCallSenders();
         switch (peopleType) {
diff --git a/src/com/android/settings/notification/zen/ZenModeConversationsImagePreferenceController.java b/src/com/android/settings/notification/zen/ZenModeConversationsImagePreferenceController.java
deleted file mode 100644
index 78c8134..0000000
--- a/src/com/android/settings/notification/zen/ZenModeConversationsImagePreferenceController.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.settings.notification.zen;
-
-import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE;
-import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
-import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_NONE;
-
-import android.content.Context;
-import android.content.pm.ParceledListSlice;
-import android.graphics.drawable.Drawable;
-import android.os.AsyncTask;
-import android.service.notification.ConversationChannelWrapper;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.R;
-import com.android.settings.notification.NotificationBackend;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.widget.LayoutPreference;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Updates the DND Settings conversations image resource based on the conversations channels.
- */
-public class ZenModeConversationsImagePreferenceController
-        extends AbstractZenModePreferenceController {
-    private static final int MAX_CONVERSATIONS_SHOWN = 5;
-    private final int mIconSizePx;
-    private final int mIconOffsetPx;
-    private final ArrayList<Drawable> mConversationDrawables = new ArrayList<>();
-    private final NotificationBackend mNotificationBackend;
-
-    private ViewGroup mViewGroup;
-    private LayoutPreference mPreference;
-
-    public ZenModeConversationsImagePreferenceController(Context context, String key,
-            Lifecycle lifecycle, NotificationBackend notificationBackend) {
-        super(context, key, lifecycle);
-        mNotificationBackend = notificationBackend;
-        mIconSizePx =
-                mContext.getResources().getDimensionPixelSize(R.dimen.zen_conversations_icon_size);
-        mIconOffsetPx = mContext.getResources()
-                .getDimensionPixelSize(R.dimen.zen_conversations_icon_offset);
-    }
-
-    @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        mPreference = (LayoutPreference) screen.findPreference(KEY);
-        mViewGroup =
-                (ViewGroup) mPreference.findViewById(R.id.zen_mode_settings_senders_overlay_view);
-        loadConversations();
-    }
-
-    @Override
-    public boolean isAvailable() {
-        return true;
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return KEY;
-    }
-
-    @Override
-    public void updateState(Preference preference) {
-        loadConversations();
-
-        mViewGroup.removeAllViews();
-        final int conversationSenders = mBackend.getPriorityConversationSenders();
-        if (conversationSenders == CONVERSATION_SENDERS_ANYONE) {
-            mViewGroup.setContentDescription(
-                    mContext.getResources().getString(R.string.zen_mode_from_all_conversations));
-        } else if (conversationSenders == CONVERSATION_SENDERS_IMPORTANT) {
-            mViewGroup.setContentDescription(
-                    mContext.getResources().getString(
-                            R.string.zen_mode_from_important_conversations));
-        } else {
-            mViewGroup.setContentDescription(null);
-            mViewGroup.setVisibility(View.GONE);
-            return;
-        }
-
-        final int numDrawablesToShow = Math.min(MAX_CONVERSATIONS_SHOWN,
-                mConversationDrawables.size());
-        for (int i = 0; i < numDrawablesToShow; i++) {
-            ImageView iv = new ImageView(mContext);
-            iv.setImageDrawable(mConversationDrawables.get(i));
-            iv.setLayoutParams(new ViewGroup.LayoutParams(mIconSizePx, mIconSizePx));
-
-            FrameLayout fl = new FrameLayout(mContext);
-            fl.addView(iv);
-            fl.setPadding((numDrawablesToShow - i - 1) * mIconOffsetPx, 0, 0, 0);
-            mViewGroup.addView(fl);
-        }
-
-        mViewGroup.setVisibility(numDrawablesToShow > 0 ? View.VISIBLE : View.GONE);
-    }
-
-    private void loadConversations() {
-        // Load conversations
-        new AsyncTask<Void, Void, Void>() {
-            private List<Drawable> mDrawables = new ArrayList<>();
-            @Override
-            protected Void doInBackground(Void... unused) {
-                mDrawables.clear();
-                final int conversationSenders = mBackend.getPriorityConversationSenders();
-                if (conversationSenders == CONVERSATION_SENDERS_NONE) {
-                    return null;
-                }
-                ParceledListSlice<ConversationChannelWrapper> conversations =
-                        mNotificationBackend.getConversations(
-                                conversationSenders == CONVERSATION_SENDERS_IMPORTANT);
-                if (conversations != null) {
-                    for (ConversationChannelWrapper conversation : conversations.getList()) {
-                        if (!conversation.getNotificationChannel().isDemoted()) {
-                            Drawable drawable = mNotificationBackend.getConversationDrawable(
-                                    mContext,
-                                    conversation.getShortcutInfo(),
-                                    conversation.getPkg(),
-                                    conversation.getUid(),
-                                    conversation.getNotificationChannel()
-                                            .isImportantConversation());
-                            if (drawable != null) {
-                                mDrawables.add(drawable);
-                            }
-                        }
-                    }
-                }
-
-                return null;
-            }
-
-            @Override
-            protected void onPostExecute(Void unused) {
-                if (mContext == null) {
-                    return;
-                }
-                mConversationDrawables.clear();
-                mConversationDrawables.addAll(mDrawables);
-                updateState(mPreference);
-            }
-        }.execute();
-    }
-}
diff --git a/src/com/android/settings/notification/zen/ZenModeConversationsPreferenceController.java b/src/com/android/settings/notification/zen/ZenModeConversationsPreferenceController.java
deleted file mode 100644
index f23bf61..0000000
--- a/src/com/android/settings/notification/zen/ZenModeConversationsPreferenceController.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.settings.notification.zen;
-
-import android.app.NotificationManager;
-import android.content.Context;
-import android.provider.Settings;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
-/**
- * Controls the summary for preference found at:
- *  Settings > Sound > Do Not Disturb > People > Conversations
- */
-public class ZenModeConversationsPreferenceController extends AbstractZenModePreferenceController {
-    private final ZenModeBackend mBackend;
-    private Preference mPreference;
-
-    public ZenModeConversationsPreferenceController(Context context,
-            String key, Lifecycle lifecycle) {
-        super(context, key, lifecycle);
-        mBackend = ZenModeBackend.getInstance(context);
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return KEY;
-    }
-
-    @Override
-    public boolean isAvailable() {
-        return true;
-    }
-
-    @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        mPreference = screen.findPreference(KEY);
-    }
-
-    @Override
-    public void updateState(Preference preference) {
-        super.updateState(preference);
-        switch (getZenMode()) {
-            case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
-            case Settings.Global.ZEN_MODE_ALARMS:
-                mPreference.setEnabled(false);
-                mPreference.setSummary(mBackend.getAlarmsTotalSilencePeopleSummary(
-                        NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS));
-                break;
-            default:
-                preference.setEnabled(true);
-                preference.setSummary(mBackend.getConversationSummary());
-        }
-    }
-}
diff --git a/src/com/android/settings/notification/zen/ZenModeConversationsSettings.java b/src/com/android/settings/notification/zen/ZenModeConversationsSettings.java
deleted file mode 100644
index 5c68126..0000000
--- a/src/com/android/settings/notification/zen/ZenModeConversationsSettings.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.settings.notification.zen;
-
-import android.app.settings.SettingsEnums;
-import android.content.Context;
-
-import com.android.settings.R;
-import com.android.settings.notification.NotificationBackend;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.search.SearchIndexable;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Settings > Sound > Do Not Disturb > Conversations
- */
-@SearchIndexable
-public class ZenModeConversationsSettings extends ZenModeSettingsBase {
-    private final NotificationBackend mNotificationBackend = new NotificationBackend();
-
-    @Override
-    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
-        return buildPreferenceControllers(context, getSettingsLifecycle(), mNotificationBackend);
-    }
-
-    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
-            Lifecycle lifecycle, NotificationBackend notificationBackend) {
-        List<AbstractPreferenceController> controllers = new ArrayList<>();
-        controllers.add(new ZenModeConversationsImagePreferenceController(context,
-                "zen_mode_conversations_image", lifecycle, notificationBackend));
-        controllers.add(new ZenModePriorityConversationsPreferenceController(context,
-                "zen_mode_conversations_radio_buttons", lifecycle, notificationBackend));
-        return controllers;
-    }
-
-    @Override
-    protected int getPreferenceScreenResId() {
-        return R.xml.zen_mode_conversations_settings;
-    }
-
-    @Override
-    public int getMetricsCategory() {
-        return SettingsEnums.DND_CONVERSATIONS;
-    }
-
-    /**
-     * For Search.
-     */
-    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider(R.xml.zen_mode_conversations_settings) {
-
-                @Override
-                public List<AbstractPreferenceController> createPreferenceControllers(
-                        Context context) {
-                    return buildPreferenceControllers(context, null, null);
-                }
-            };
-}
diff --git a/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java b/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java
deleted file mode 100644
index a8387a3..0000000
--- a/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceController.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.settings.notification.zen;
-
-import android.app.NotificationManager;
-import android.app.settings.SettingsEnums;
-import android.content.Context;
-import android.content.pm.ParceledListSlice;
-import android.icu.text.MessageFormat;
-import android.os.AsyncTask;
-import android.service.notification.ConversationChannelWrapper;
-import android.view.View;
-
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.R;
-import com.android.settings.core.SubSettingLauncher;
-import com.android.settings.notification.NotificationBackend;
-import com.android.settings.notification.app.ConversationListSettings;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.widget.SelectorWithWidgetPreference;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-/**
- * Options to choose the priority conversations that are allowed to bypass DND.
- */
-public class ZenModePriorityConversationsPreferenceController
-        extends AbstractZenModePreferenceController {
-    private static final int UNSET = -1;
-    @VisibleForTesting static final String KEY_ALL = "conversations_all";
-    @VisibleForTesting static final String KEY_IMPORTANT = "conversations_important";
-    @VisibleForTesting static final String KEY_NONE = "conversations_none";
-
-    private final NotificationBackend mNotificationBackend;
-
-    private int mNumImportantConversations = UNSET;
-    private int mNumConversations = UNSET;
-    private PreferenceCategory mPreferenceCategory;
-    private List<SelectorWithWidgetPreference> mSelectorWithWidgetPreferences = new ArrayList<>();
-    private Context mPreferenceScreenContext;
-
-    public ZenModePriorityConversationsPreferenceController(Context context, String key,
-            Lifecycle lifecycle, NotificationBackend notificationBackend) {
-        super(context, key, lifecycle);
-        mNotificationBackend = notificationBackend;
-    }
-
-    @Override
-    public void displayPreference(PreferenceScreen screen) {
-        mPreferenceScreenContext = screen.getContext();
-        mPreferenceCategory = screen.findPreference(getPreferenceKey());
-        if (mPreferenceCategory.findPreference(KEY_ALL) == null) {
-            makeRadioPreference(KEY_ALL, R.string.zen_mode_from_all_conversations);
-            makeRadioPreference(KEY_IMPORTANT, R.string.zen_mode_from_important_conversations);
-            makeRadioPreference(KEY_NONE, R.string.zen_mode_from_no_conversations);
-            updateChannelCounts();
-        }
-
-        super.displayPreference(screen);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        updateChannelCounts();
-    }
-
-    @Override
-    public boolean isAvailable() {
-        return true;
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return KEY;
-    }
-
-    @Override
-    public void updateState(Preference preference) {
-        final int currSetting = mBackend.getPriorityConversationSenders();
-
-        for (SelectorWithWidgetPreference pref : mSelectorWithWidgetPreferences) {
-            pref.setChecked(keyToSetting(pref.getKey()) == currSetting);
-            pref.setSummary(getSummary(pref.getKey()));
-        }
-    }
-
-    private static int keyToSetting(String key) {
-        switch (key) {
-            case KEY_ALL:
-                return NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE;
-            case KEY_IMPORTANT:
-                return NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
-            default:
-                return NotificationManager.Policy.CONVERSATION_SENDERS_NONE;
-        }
-    }
-
-    private String getSummary(String key) {
-        int numConversations;
-        if (KEY_ALL.equals(key)) {
-            numConversations = mNumConversations;
-        } else if (KEY_IMPORTANT.equals(key)) {
-            numConversations = mNumImportantConversations;
-        } else {
-            return null;
-        }
-
-        if (numConversations == UNSET) {
-            return null;
-        } else {
-            MessageFormat msgFormat = new MessageFormat(
-                    mContext.getString(R.string.zen_mode_conversations_count),
-                    Locale.getDefault());
-            Map<String, Object> args = new HashMap<>();
-            args.put("count", numConversations);
-            return msgFormat.format(args);
-        }
-    }
-
-    private void updateChannelCounts() {
-        // Load conversations
-        new AsyncTask<Void, Void, Void>() {
-            @Override
-            protected Void doInBackground(Void... unused) {
-                ParceledListSlice<ConversationChannelWrapper> allConversations =
-                        mNotificationBackend.getConversations(false);
-                int numConversations = 0;
-                if (allConversations != null) {
-                    for (ConversationChannelWrapper conversation : allConversations.getList()) {
-                        if (!conversation.getNotificationChannel().isDemoted()) {
-                            numConversations++;
-                        }
-                    }
-                }
-                mNumConversations = numConversations;
-
-                ParceledListSlice<ConversationChannelWrapper> impConversations =
-                        mNotificationBackend.getConversations(true);
-                int numImportantConversations = 0;
-                if (impConversations != null) {
-                    for (ConversationChannelWrapper conversation : impConversations.getList()) {
-                        if (!conversation.getNotificationChannel().isDemoted()) {
-                            numImportantConversations++;
-                        }
-                    }
-                }
-                mNumImportantConversations = numImportantConversations;
-                return null;
-            }
-
-            @Override
-            protected void onPostExecute(Void unused) {
-                if (mContext == null) {
-                    return;
-                }
-                updateState(mPreferenceCategory);
-            }
-        }.execute();
-    }
-
-    private SelectorWithWidgetPreference makeRadioPreference(String key, int titleId) {
-        final SelectorWithWidgetPreference pref =
-                new SelectorWithWidgetPreference(mPreferenceCategory.getContext());
-        if (KEY_ALL.equals(key) || KEY_IMPORTANT.equals(key)) {
-            pref.setExtraWidgetOnClickListener(mConversationSettingsWidgetClickListener);
-        }
-        pref.setKey(key);
-        pref.setTitle(titleId);
-        pref.setOnClickListener(mRadioButtonClickListener);
-        mPreferenceCategory.addPreference(pref);
-        mSelectorWithWidgetPreferences.add(pref);
-        return pref;
-    }
-
-    private View.OnClickListener mConversationSettingsWidgetClickListener =
-            new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            new SubSettingLauncher(mPreferenceScreenContext)
-                    .setDestination(ConversationListSettings.class.getName())
-                    .setSourceMetricsCategory(SettingsEnums.DND_CONVERSATIONS)
-                    .launch();
-        }
-    };
-
-    private SelectorWithWidgetPreference.OnClickListener mRadioButtonClickListener =
-            new SelectorWithWidgetPreference.OnClickListener() {
-        @Override
-        public void onRadioButtonClicked(SelectorWithWidgetPreference preference) {
-            int selectedConversationSetting = keyToSetting(preference.getKey());
-            if (selectedConversationSetting != mBackend.getPriorityConversationSenders()) {
-                mBackend.saveConversationSenders(selectedConversationSetting);
-            }
-        }
-    };
-}
diff --git a/src/com/android/settings/panel/SettingsPanelActivity.java b/src/com/android/settings/panel/SettingsPanelActivity.java
index 77949eb..60b8f88 100644
--- a/src/com/android/settings/panel/SettingsPanelActivity.java
+++ b/src/com/android/settings/panel/SettingsPanelActivity.java
@@ -29,12 +29,15 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsControllerCompat;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentActivity;
 import androidx.fragment.app.FragmentManager;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
+import com.android.settings.Utils;
 import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
 
 /**
@@ -144,9 +147,33 @@
             window.setGravity(Gravity.BOTTOM);
             window.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
                     WindowManager.LayoutParams.WRAP_CONTENT);
+            setupNavigationBar();
             mPanelFragment = new PanelFragment();
             mPanelFragment.setArguments(new Bundle(mBundle));
             fragmentManager.beginTransaction().add(R.id.main_content, mPanelFragment).commit();
         }
     }
+
+    /**
+     * Adjust bottom edge and color.
+     */
+    private void setupNavigationBar() {
+        // Extend the panel all the way to the bottom of the screen, as opposed to sitting on top of
+        // the navigation bar.
+        ViewCompat.setOnApplyWindowInsetsListener(getWindow().getDecorView(),
+                (v, windowInsets) -> {
+                    v.setPadding(v.getPaddingLeft(), v.getPaddingTop(), v.getPaddingRight(), 0);
+                    return windowInsets; // propagate down to panel layout root element
+                });
+
+        // When using 3-button navigation in light mode, the system picks white navigation buttons
+        // which are not sufficiently contrasted from the panel background.
+        WindowInsetsControllerCompat windowInsetsController =
+                ViewCompat.getWindowInsetsController(getWindow().getDecorView());
+
+        if (windowInsetsController != null) {
+            boolean forceNavigationButtonsDark = !Utils.isNightMode(this);
+            windowInsetsController.setAppearanceLightNavigationBars(forceNavigationButtonsDark);
+        }
+    }
 }
diff --git a/src/com/android/settings/password/ChooseLockSettingsHelper.java b/src/com/android/settings/password/ChooseLockSettingsHelper.java
index 020b725..26e84be 100644
--- a/src/com/android/settings/password/ChooseLockSettingsHelper.java
+++ b/src/com/android/settings/password/ChooseLockSettingsHelper.java
@@ -21,12 +21,14 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Activity;
+import android.app.ActivityOptions;
 import android.app.KeyguardManager;
 import android.app.RemoteLockscreenValidationSession;
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.IntentSender;
+import android.os.Bundle;
 import android.os.UserManager;
 import android.util.Log;
 
@@ -147,7 +149,8 @@
         private boolean mRemoteLockscreenValidation;
         @Nullable private RemoteLockscreenValidationSession mRemoteLockscreenValidationSession;
         @Nullable private ComponentName mRemoteLockscreenValidationServiceComponent;
-        boolean mRequestGatekeeperPasswordHandle;
+        private boolean mRequestGatekeeperPasswordHandle;
+        private boolean mTaskOverlay;
 
         public Builder(@NonNull Activity activity) {
             mActivity = activity;
@@ -253,6 +256,14 @@
         }
 
         /**
+         * @param taskOverlay specifies whether the activity should be launched as a task overlay.
+         */
+        @NonNull public Builder setTaskOverlay(boolean taskOverlay) {
+            mTaskOverlay = taskOverlay;
+            return this;
+        }
+
+        /**
          * @param foregroundOnly if true, the confirmation activity will be finished if it loses
          *                       foreground.
          */
@@ -371,7 +382,8 @@
                 mBuilder.mCheckBoxLabel, mBuilder.mRemoteLockscreenValidation,
                 mBuilder.mRemoteLockscreenValidationSession,
                 mBuilder.mRemoteLockscreenValidationServiceComponent, mBuilder.mAllowAnyUserId,
-                mBuilder.mForegroundOnly, mBuilder.mRequestGatekeeperPasswordHandle);
+                mBuilder.mForegroundOnly, mBuilder.mRequestGatekeeperPasswordHandle,
+                mBuilder.mTaskOverlay);
     }
 
     private boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
@@ -381,7 +393,8 @@
             @Nullable CharSequence checkboxLabel, boolean remoteLockscreenValidation,
             @Nullable RemoteLockscreenValidationSession remoteLockscreenValidationSession,
             @Nullable ComponentName remoteLockscreenValidationServiceComponent,
-            boolean allowAnyUser, boolean foregroundOnly, boolean requestGatekeeperPasswordHandle) {
+            boolean allowAnyUser, boolean foregroundOnly, boolean requestGatekeeperPasswordHandle,
+            boolean taskOverlay) {
         Optional<Class<?>> activityClass = determineAppropriateActivityClass(
                 returnCredentials, forceVerifyPath, userId, remoteLockscreenValidationSession);
         if (activityClass.isEmpty()) {
@@ -392,7 +405,7 @@
                 returnCredentials, external, forceVerifyPath, userId, alternateButton,
                 checkboxLabel, remoteLockscreenValidation, remoteLockscreenValidationSession,
                 remoteLockscreenValidationServiceComponent, allowAnyUser, foregroundOnly,
-                requestGatekeeperPasswordHandle);
+                requestGatekeeperPasswordHandle, taskOverlay);
     }
 
     private boolean launchConfirmationActivity(int request, CharSequence title, CharSequence header,
@@ -402,7 +415,8 @@
             boolean remoteLockscreenValidation,
             @Nullable RemoteLockscreenValidationSession remoteLockscreenValidationSession,
             @Nullable ComponentName remoteLockscreenValidationServiceComponent,
-            boolean allowAnyUser, boolean foregroundOnly, boolean requestGatekeeperPasswordHandle) {
+            boolean allowAnyUser, boolean foregroundOnly, boolean requestGatekeeperPasswordHandle,
+            boolean taskOverlay) {
         final Intent intent = new Intent();
         intent.putExtra(ConfirmDeviceCredentialBaseFragment.TITLE_TEXT, title);
         intent.putExtra(ConfirmDeviceCredentialBaseFragment.HEADER_TEXT, header);
@@ -434,28 +448,39 @@
         Intent inIntent = mFragment != null ? mFragment.getActivity().getIntent() :
                 mActivity.getIntent();
         copyInternalExtras(inIntent, intent);
+        Bundle launchOptions = createLaunchOptions(taskOverlay);
         if (external) {
             intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
             copyOptionalExtras(inIntent, intent);
             if (mActivityResultLauncher != null) {
                 mActivityResultLauncher.launch(intent);
             } else if (mFragment != null) {
-                mFragment.startActivity(intent);
+                mFragment.startActivity(intent, launchOptions);
             } else {
-                mActivity.startActivity(intent);
+                mActivity.startActivity(intent, launchOptions);
             }
         } else {
             if (mActivityResultLauncher != null) {
                 mActivityResultLauncher.launch(intent);
             } else if (mFragment != null) {
-                mFragment.startActivityForResult(intent, request);
+                mFragment.startActivityForResult(intent, request, launchOptions);
             } else {
-                mActivity.startActivityForResult(intent, request);
+                mActivity.startActivityForResult(intent, request, launchOptions);
             }
         }
         return true;
     }
 
+    private Bundle createLaunchOptions(boolean taskOverlay) {
+        if (!taskOverlay) {
+            return null;
+        }
+        ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchTaskId(mActivity.getTaskId());
+        options.setTaskOverlay(true /* taskOverlay */, true /* canResume */);
+        return options.toBundle();
+    }
+
     private Optional<Integer> passwordQualityToLockTypes(int quality) {
         switch (quality) {
             case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
index 328e440..fbcebb8 100644
--- a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
+++ b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
@@ -24,8 +24,6 @@
 import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_CONFIRM_PATTERN;
 import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_CONFIRM_PIN;
 
-import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME;
-
 import android.app.Activity;
 import android.app.KeyguardManager;
 import android.app.RemoteLockscreenValidationSession;
@@ -63,13 +61,6 @@
 public class ConfirmDeviceCredentialActivity extends FragmentActivity {
     public static final String TAG = ConfirmDeviceCredentialActivity.class.getSimpleName();
 
-    /**
-     * If the intent is sent from {@link com.android.systemui.keyguard.WorkLockActivityController}
-     * then check for device policy management flags.
-     */
-    public static final String EXTRA_FROM_WORK_LOCK_ACTIVITY_CONTROLLER =
-            "from_work_lock_activity_controller";
-
     // The normal flow that apps go through
     private static final int CREDENTIAL_NORMAL = 1;
     // Unlocks the managed profile when the primary profile is unlocked
@@ -80,15 +71,6 @@
     public static class InternalActivity extends ConfirmDeviceCredentialActivity {
     }
 
-    public static Intent createIntent(CharSequence title, CharSequence details) {
-        Intent intent = new Intent();
-        intent.setClassName(SETTINGS_PACKAGE_NAME,
-                ConfirmDeviceCredentialActivity.class.getName());
-        intent.putExtra(KeyguardManager.EXTRA_TITLE, title);
-        intent.putExtra(KeyguardManager.EXTRA_DESCRIPTION, details);
-        return intent;
-    }
-
     private BiometricFragment mBiometricFragment;
     private DevicePolicyManager mDevicePolicyManager;
     private LockPatternUtils mLockPatternUtils;
@@ -97,6 +79,7 @@
     private Handler mHandler = new Handler(Looper.getMainLooper());
     private Context mContext;
     private boolean mCheckDevicePolicyManager;
+    private boolean mTaskOverlay;
 
     private String mTitle;
     private CharSequence mDetails;
@@ -186,6 +169,8 @@
         boolean frp = KeyguardManager.ACTION_CONFIRM_FRP_CREDENTIAL.equals(intent.getAction());
         boolean remoteValidation =
                 KeyguardManager.ACTION_CONFIRM_REMOTE_DEVICE_CREDENTIAL.equals(intent.getAction());
+        mTaskOverlay = isInternalActivity()
+                && intent.getBooleanExtra(KeyguardManager.EXTRA_FORCE_TASK_OVERLAY, false);
 
         mUserId = UserHandle.myUserId();
         if (isInternalActivity()) {
@@ -417,6 +402,12 @@
      */
     private void showConfirmCredentials() {
         boolean launched = false;
+        ChooseLockSettingsHelper.Builder builder = new ChooseLockSettingsHelper.Builder(this)
+                .setHeader(mTitle)
+                .setDescription(mDetails)
+                .setExternal(true)
+                .setUserId(mUserId)
+                .setTaskOverlay(mTaskOverlay);
         // The only difference between CREDENTIAL_MANAGED and CREDENTIAL_NORMAL is that for
         // CREDENTIAL_MANAGED, we launch the real confirm credential activity with an explicit
         // but fake challenge value (0L). This will result in ConfirmLockPassword calling
@@ -429,22 +420,9 @@
         // LockPatternChecker and LockPatternUtils. verifyPassword should be the only API to use,
         // which optionally accepts a challenge.
         if (mCredentialMode == CREDENTIAL_MANAGED) {
-            final ChooseLockSettingsHelper.Builder builder =
-                    new ChooseLockSettingsHelper.Builder(this);
-            launched = builder.setHeader(mTitle)
-                    .setDescription(mDetails)
-                    .setExternal(true)
-                    .setUserId(mUserId)
-                    .setForceVerifyPath(true)
-                    .show();
+            launched = builder.setForceVerifyPath(true).show();
         } else if (mCredentialMode == CREDENTIAL_NORMAL) {
-            final ChooseLockSettingsHelper.Builder builder =
-                    new ChooseLockSettingsHelper.Builder(this);
-            launched = builder.setHeader(mTitle) // Show the title string in the header area
-                    .setDescription(mDetails)
-                    .setExternal(true)
-                    .setUserId(mUserId)
-                    .show();
+            launched = builder.show();
         }
         if (!launched) {
             Log.d(TAG, "No pin/pattern/pass set");
diff --git a/src/com/android/settings/regionalpreferences/NumberingPreferencesFragment.java b/src/com/android/settings/regionalpreferences/NumberingPreferencesFragment.java
index 20d7f58..1c5015f 100644
--- a/src/com/android/settings/regionalpreferences/NumberingPreferencesFragment.java
+++ b/src/com/android/settings/regionalpreferences/NumberingPreferencesFragment.java
@@ -23,6 +23,7 @@
 
 import androidx.annotation.VisibleForTesting;
 
+import com.android.internal.app.LocaleHelper;
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settingslib.core.AbstractPreferenceController;
@@ -53,9 +54,8 @@
                 Log.w(getLogTag(), "No selected language.");
                 return "";
             }
-            return Locale.forLanguageTag(selectedLanguage)
-                    .stripExtensions()
-                    .getDisplayName(Locale.forLanguageTag(selectedLanguage));
+            Locale locale = Locale.forLanguageTag(selectedLanguage);
+            return LocaleHelper.getDisplayName(locale.stripExtensions(), locale, true);
         }
         Log.w(getLogTag(), "Incorrect option : " + option);
         return "";
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingFragmentTest.java
index b2da579..9bd4f1b 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsAudioRoutingFragmentTest.java
@@ -26,8 +26,6 @@
 
 import androidx.test.core.app.ApplicationProvider;
 
-import com.android.settings.R;
-import com.android.settings.testutils.XmlTestUtils;
 import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
@@ -44,8 +42,6 @@
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
 
-import java.util.List;
-
 /** Tests for {@link BluetoothDetailsAudioRoutingFragment}. */
 @RunWith(RobolectricTestRunner.class)
 @Config(shadows = {ShadowBluetoothUtils.class})
@@ -92,17 +88,6 @@
         assertThat(mFragment.mCachedDevice.getAddress()).isEqualTo(TEST_ADDRESS);
     }
 
-    @Test
-    public void getNonIndexableKeys_existInXmlLayout() {
-        final List<String> niks = BluetoothDetailsAudioRoutingFragment.SEARCH_INDEX_DATA_PROVIDER
-                .getNonIndexableKeys(mContext);
-        final List<String> keys =
-                XmlTestUtils.getKeysFromPreferenceXml(mContext,
-                        R.xml.bluetooth_audio_routing_fragment);
-
-        assertThat(keys).containsAtLeastElementsIn(niks);
-    }
-
     private void setupEnvironment() {
         ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
         when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
diff --git a/tests/robotests/src/com/android/settings/dream/DreamHomeControlsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/dream/DreamHomeControlsPreferenceControllerTest.java
new file mode 100644
index 0000000..452604c
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/dream/DreamHomeControlsPreferenceControllerTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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.dream;
+
+import static com.android.settingslib.dream.DreamBackend.COMPLICATION_TYPE_HOME_CONTROLS;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.util.ArraySet;
+
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settingslib.dream.DreamBackend;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowContentResolver;
+import org.robolectric.shadows.ShadowSettings;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {ShadowSettings.ShadowSecure.class})
+public class DreamHomeControlsPreferenceControllerTest {
+
+    private Context mContext;
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private PreferenceScreen mScreen;
+    private DreamHomeControlsPreferenceController mController;
+    private SwitchPreference mPreference;
+    private DreamBackend mBackend;
+    private ShadowContentResolver mShadowContentResolver;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = ApplicationProvider.getApplicationContext();
+        mShadowContentResolver = Shadow.extract(mContext.getContentResolver());
+        mBackend = new DreamBackend(mContext);
+        mController = new DreamHomeControlsPreferenceController(mContext, "key", mBackend);
+        mPreference = new SwitchPreference(mContext);
+        mPreference.setKey(mController.getPreferenceKey());
+        when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference);
+        mController.displayPreference(mScreen);
+
+        // Make home controls supported by default
+        mBackend.setSupportedComplications(
+                new ArraySet<>(new Integer[]{COMPLICATION_TYPE_HOME_CONTROLS}));
+    }
+
+    @After
+    public void tearDown() {
+        ShadowSettings.ShadowSecure.reset();
+    }
+
+    @Test
+    public void testSetChecked_setTrue_enablesSetting() {
+        mBackend.setHomeControlsEnabled(false);
+        assertThat(mBackend.getEnabledComplications())
+                .doesNotContain(COMPLICATION_TYPE_HOME_CONTROLS);
+
+        mController.setChecked(true);
+        assertThat(mBackend.getEnabledComplications())
+                .contains(COMPLICATION_TYPE_HOME_CONTROLS);
+    }
+
+    @Test
+    public void testSetChecked_setFalse_disablesSetting() {
+        mBackend.setHomeControlsEnabled(true);
+        assertThat(mBackend.getEnabledComplications())
+                .contains(COMPLICATION_TYPE_HOME_CONTROLS);
+
+        mController.setChecked(false);
+        assertThat(mBackend.getEnabledComplications())
+                .doesNotContain(COMPLICATION_TYPE_HOME_CONTROLS);
+    }
+
+    @Test
+    public void testIsChecked_returnsFalse() {
+        mBackend.setHomeControlsEnabled(false);
+        assertThat(mController.isChecked()).isFalse();
+    }
+
+    @Test
+    public void testIsChecked_returnsTrue() {
+        mBackend.setHomeControlsEnabled(true);
+        assertThat(mBackend.getEnabledComplications())
+                .contains(COMPLICATION_TYPE_HOME_CONTROLS);
+        assertThat(mController.isChecked()).isTrue();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/DockAudioMediaPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/DockAudioMediaPreferenceControllerTest.java
index d237b27..5e4efd0 100644
--- a/tests/robotests/src/com/android/settings/notification/DockAudioMediaPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/DockAudioMediaPreferenceControllerTest.java
@@ -19,14 +19,19 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Answers.RETURNS_DEEP_STUBS;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.provider.Settings.Global;
 
 import androidx.fragment.app.FragmentActivity;
@@ -72,6 +77,7 @@
         mController = new DockAudioMediaPreferenceController(mContext, mSetting, null);
         when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
         doReturn(mScreen).when(mSetting).getPreferenceScreen();
+        fakeDockState(Intent.EXTRA_DOCK_STATE_LE_DESK);
     }
 
     @Test
@@ -91,6 +97,34 @@
     }
 
     @Test
+    public void isAvailable_undocked_shouldReturnFalse() {
+        when(mContext.registerReceiver(nullable(BroadcastReceiver.class),
+            any(IntentFilter.class))).thenReturn(null);
+        when(mContext.getResources().getBoolean(com.android.settings.R.bool.has_dock_settings))
+            .thenReturn(true);
+
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void isAvailable_highEndDock_shouldReturnFalse() {
+        fakeDockState(Intent.EXTRA_DOCK_STATE_HE_DESK);
+        when(mContext.getResources().getBoolean(com.android.settings.R.bool.has_dock_settings))
+            .thenReturn(true);
+
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void isAvailable_lowEndDock_shouldReturnTrue() {
+        fakeDockState(Intent.EXTRA_DOCK_STATE_LE_DESK);
+        when(mContext.getResources().getBoolean(com.android.settings.R.bool.has_dock_settings))
+            .thenReturn(true);
+
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
     public void displayPreference_dockAudioDisabled_shouldSelectFirstItem() {
         Global.putInt(mContentResolver, Global.DOCK_AUDIO_MEDIA_ENABLED, 0);
 
@@ -127,4 +161,11 @@
         assertThat(Global.getInt(mContentResolver, Global.DOCK_AUDIO_MEDIA_ENABLED, 0))
             .isEqualTo(1);
     }
+
+    private void fakeDockState(int dockState) {
+        Intent intent = new Intent(Intent.ACTION_DOCK_EVENT);
+        intent.putExtra(Intent.EXTRA_DOCK_STATE, dockState);
+        when(mContext.registerReceiver(nullable(BroadcastReceiver.class),
+            any(IntentFilter.class))).thenReturn(intent);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceControllerTest.java
deleted file mode 100644
index d5834f9..0000000
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenModePriorityConversationsPreferenceControllerTest.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.settings.notification.zen;
-
-import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE;
-import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
-import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_NONE;
-
-import static com.android.settings.notification.zen.ZenModePriorityConversationsPreferenceController.KEY_ALL;
-import static com.android.settings.notification.zen.ZenModePriorityConversationsPreferenceController.KEY_IMPORTANT;
-import static com.android.settings.notification.zen.ZenModePriorityConversationsPreferenceController.KEY_NONE;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.NotificationManager;
-import android.content.ContentResolver;
-import android.content.Context;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.notification.NotificationBackend;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.widget.SelectorWithWidgetPreference;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.util.ReflectionHelpers;
-
-import java.util.List;
-
-@RunWith(RobolectricTestRunner.class)
-public class ZenModePriorityConversationsPreferenceControllerTest {
-
-    private ZenModePriorityConversationsPreferenceController mController;
-
-    @Mock
-    private ZenModeBackend mZenBackend;
-    @Mock
-    private PreferenceCategory mMockPrefCategory;
-    @Mock
-    private NotificationManager.Policy mPolicy;
-    @Mock
-    private PreferenceScreen mPreferenceScreen;
-    @Mock
-    private NotificationBackend mNotifBackend;
-
-    private List<SelectorWithWidgetPreference> mSelectorWithWidgetPreferences;
-    private ContentResolver mContentResolver;
-    private Context mContext;
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
-        mController = new ZenModePriorityConversationsPreferenceController(
-                mContext, "test_key", mock(Lifecycle.class), mNotifBackend);
-        ReflectionHelpers.setField(mController, "mBackend", mZenBackend);
-
-        when(mMockPrefCategory.getContext()).thenReturn(mContext);
-        when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
-                .thenReturn(mMockPrefCategory);
-        captureRadioButtons();
-    }
-
-    @Test
-    public void displayPreference_radioButtonsCreatedOnlyOnce() {
-        when(mMockPrefCategory.findPreference(any())).thenReturn(mock(Preference.class));
-
-        // radio buttons were already created, so don't re-create them
-        mController.displayPreference(mPreferenceScreen);
-        verify(mMockPrefCategory, never()).addPreference(any());
-    }
-
-    @Test
-    public void clickAllConversations() {
-        SelectorWithWidgetPreference allConversationsRb = getButton(KEY_ALL);
-        allConversationsRb.onClick();
-
-        verify(mZenBackend).saveConversationSenders(CONVERSATION_SENDERS_ANYONE);
-    }
-
-    @Test
-    public void clickImportantConversations() {
-        SelectorWithWidgetPreference importantConversationsRb = getButton(KEY_IMPORTANT);
-        importantConversationsRb.onClick();
-
-        verify(mZenBackend).saveConversationSenders(CONVERSATION_SENDERS_IMPORTANT);
-    }
-
-    @Test
-    public void clickNoConversations() {
-        SelectorWithWidgetPreference noConversationsRb = getButton(KEY_NONE);
-        noConversationsRb.onClick();
-
-        verify(mZenBackend)
-                .saveConversationSenders(CONVERSATION_SENDERS_NONE);
-    }
-
-    private void captureRadioButtons() {
-        ArgumentCaptor<SelectorWithWidgetPreference> rbCaptor =
-                ArgumentCaptor.forClass(SelectorWithWidgetPreference.class);
-        mController.displayPreference(mPreferenceScreen);
-
-        // verifies 3 buttons were added
-        verify(mMockPrefCategory, times(3)).addPreference(rbCaptor.capture());
-        mSelectorWithWidgetPreferences = rbCaptor.getAllValues();
-        assertThat(mSelectorWithWidgetPreferences.size()).isEqualTo(3);
-
-        reset(mMockPrefCategory);
-    }
-
-    private SelectorWithWidgetPreference getButton(String key) {
-        for (SelectorWithWidgetPreference pref : mSelectorWithWidgetPreferences) {
-            if (key.equals(pref.getKey())) {
-                return pref;
-            }
-        }
-        return null;
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java b/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
index 5cdc12a..ea55b90 100644
--- a/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
+++ b/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
@@ -16,11 +16,13 @@
 
 package com.android.settings.panel;
 
+import static android.content.res.Configuration.UI_MODE_NIGHT_NO;
 import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
 
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -30,15 +32,20 @@
 
 import android.content.res.Configuration;
 import android.os.Build;
+import android.view.View;
 import android.view.Window;
 import android.view.WindowManager;
 
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsControllerCompat;
 import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
 
 import com.android.settings.R;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -61,6 +68,9 @@
     private PanelFragment mPanelFragment;
     @Mock
     private FragmentManager mFragmentManager;
+    @Mock
+    private FragmentTransaction mTransaction;
+    private int mOriginalUiMode;
 
     @Before
     public void setUp() {
@@ -76,6 +86,15 @@
         mSettingsPanelActivity.mPanelFragment = mPanelFragment;
         when(mFragmentManager.findFragmentById(R.id.main_content)).thenReturn(mPanelFragment);
         when(mSettingsPanelActivity.getSupportFragmentManager()).thenReturn(mFragmentManager);
+        mOriginalUiMode = mSettingsPanelActivity.getResources().getConfiguration().uiMode;
+        when(mFragmentManager.beginTransaction()).thenReturn(mTransaction);
+        when(mTransaction.add(anyInt(), any())).thenReturn(mTransaction);
+        when(mTransaction.commit()).thenReturn(0); // don't care about return value
+    }
+
+    @After
+    public void tearDown() {
+        mSettingsPanelActivity.getResources().getConfiguration().uiMode = mOriginalUiMode;
     }
 
     @Test
@@ -179,4 +198,24 @@
 
         verify(mPanelFragment, never()).updatePanelWithAnimation();
     }
+
+    @Test
+    public void onCreated_isWindowBottomPaddingZero() {
+        int paddingBottom = mSettingsPanelActivity.getWindow().getDecorView().getPaddingBottom();
+        assertThat(paddingBottom).isEqualTo(0);
+    }
+
+    @Test
+    public void notInNightMode_lightNavigationBarAppearance() {
+        Configuration config = mSettingsPanelActivity.getResources().getConfiguration();
+        config.uiMode = UI_MODE_NIGHT_NO;
+        mSettingsPanelActivity.onConfigurationChanged(config); // forces creation
+
+        mSettingsPanelActivity.onNewIntent(mSettingsPanelActivity.getIntent());
+        verify(mFragmentManager).beginTransaction();
+
+        View decorView = mSettingsPanelActivity.getWindow().getDecorView();
+        WindowInsetsControllerCompat controller = ViewCompat.getWindowInsetsController(decorView);
+        assertThat(controller.isAppearanceLightNavigationBars()).isTrue();
+    }
 }
diff --git a/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java
index 2633ea7..5f7f45b 100644
--- a/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java
@@ -46,6 +46,7 @@
 
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 @RunWith(AndroidJUnit4.class)
@@ -55,6 +56,13 @@
     private PreferenceScreen mScreen;
     private PreferenceCategory mCredentialsPreferenceCategory;
 
+    private static final String TEST_PACKAGE_NAME_A = "com.android.providerA";
+    private static final String TEST_PACKAGE_NAME_B = "com.android.providerB";
+    private static final String TEST_PACKAGE_NAME_C = "com.android.providerC";
+    private static final String TEST_TITLE_APP_A = "test app A";
+    private static final String TEST_TITLE_APP_B = "test app B";
+    private static final String TEST_TITLE_SERVICE_C = "test service C1";
+
     @Before
     public void setUp() {
         mContext = spy(ApplicationProvider.getApplicationContext());
@@ -114,10 +122,10 @@
     @Test
     public void buildSwitchPreference() {
         CredentialProviderInfo providerInfo1 =
-                createCredentialProviderInfo(
+                createCredentialProviderInfoWithIsEnabled(
                         "com.android.provider1", "ClassA", "Service Title", false);
         CredentialProviderInfo providerInfo2 =
-                createCredentialProviderInfo(
+                createCredentialProviderInfoWithIsEnabled(
                         "com.android.provider2", "ClassA", "Service Title", false);
         CredentialManagerPreferenceController controller =
                 createControllerWithServices(Lists.newArrayList(providerInfo1, providerInfo2));
@@ -217,10 +225,10 @@
     @Test
     public void handlesCredentialProviderInfoEnabledDisabled() {
         CredentialProviderInfo providerInfo1 =
-                createCredentialProviderInfo(
+                createCredentialProviderInfoWithIsEnabled(
                         "com.android.provider1", "ClassA", "Service Title", false);
         CredentialProviderInfo providerInfo2 =
-                createCredentialProviderInfo(
+                createCredentialProviderInfoWithIsEnabled(
                         "com.android.provider2", "ClassA", "Service Title", true);
         CredentialManagerPreferenceController controller =
                 createControllerWithServices(Lists.newArrayList(providerInfo1, providerInfo2));
@@ -244,6 +252,63 @@
         assertThat(enabledServices.contains("com.android.provider2/ClassA")).isTrue();
     }
 
+    @Test
+    public void displayPreference_withServices_preferencesAdded_sameAppShouldBeMerged() {
+        CredentialProviderInfo serviceA1 =
+                createCredentialProviderInfoWithAppLabel(
+                        TEST_PACKAGE_NAME_A,
+                        "CredManProviderA1",
+                        TEST_TITLE_APP_A,
+                        "test service A1");
+        CredentialProviderInfo serviceB1 =
+                createCredentialProviderInfoWithAppLabel(
+                        TEST_PACKAGE_NAME_B,
+                        "CredManProviderB1",
+                        TEST_TITLE_APP_B,
+                        "test service B");
+        CredentialProviderInfo serviceC1 =
+                createCredentialProviderInfoWithAppLabel(
+                        TEST_PACKAGE_NAME_C,
+                        "CredManProviderC1",
+                        "test app C1",
+                        TEST_TITLE_SERVICE_C);
+        CredentialProviderInfo serviceC2 =
+                createCredentialProviderInfoWithAppLabel(
+                        TEST_PACKAGE_NAME_C,
+                        "CredManProviderC2",
+                        "test app C2",
+                        TEST_TITLE_SERVICE_C);
+        CredentialProviderInfo serviceC3 =
+                createCredentialProviderInfoBuilder(
+                                TEST_PACKAGE_NAME_C,
+                                "CredManProviderC3",
+                                "test app C3",
+                                TEST_TITLE_SERVICE_C)
+                        .setEnabled(true)
+                        .build();
+
+        CredentialManagerPreferenceController controller =
+                createControllerWithServices(
+                        Lists.newArrayList(serviceA1, serviceB1, serviceC1, serviceC2, serviceC3));
+        controller.displayPreference(mScreen);
+
+        assertThat(controller.isConnected()).isFalse();
+        assertThat(mCredentialsPreferenceCategory.getPreferenceCount()).isEqualTo(3);
+
+        Map<String, SwitchPreference> prefs =
+                controller.buildPreferenceList(mContext, mCredentialsPreferenceCategory);
+        assertThat(prefs.size()).isEqualTo(3);
+        assertThat(prefs.containsKey(TEST_PACKAGE_NAME_A));
+        assertThat(prefs.get(TEST_PACKAGE_NAME_A).getTitle()).isEqualTo(TEST_TITLE_APP_A);
+        assertThat(prefs.get(TEST_PACKAGE_NAME_A).isChecked()).isFalse();
+        assertThat(prefs.containsKey(TEST_PACKAGE_NAME_B));
+        assertThat(prefs.get(TEST_PACKAGE_NAME_B).getTitle()).isEqualTo(TEST_TITLE_APP_B);
+        assertThat(prefs.get(TEST_PACKAGE_NAME_B).isChecked()).isFalse();
+        assertThat(prefs.containsKey(TEST_PACKAGE_NAME_C));
+        assertThat(prefs.get(TEST_PACKAGE_NAME_C).getTitle()).isEqualTo(TEST_TITLE_SERVICE_C);
+        assertThat(prefs.get(TEST_PACKAGE_NAME_C).isChecked()).isTrue();
+    }
+
     private CredentialManagerPreferenceController createControllerWithServices(
             List<CredentialProviderInfo> availableServices) {
         CredentialManagerPreferenceController controller =
@@ -259,23 +324,34 @@
 
     private CredentialProviderInfo createCredentialProviderInfo(
             String packageName, String className) {
-        return createCredentialProviderInfo(packageName, className, null, false);
+        return createCredentialProviderInfoBuilder(packageName, className, null, "App Name")
+                .build();
     }
 
-    private CredentialProviderInfo createCredentialProviderInfo(
-            String packageName, String className, CharSequence label, boolean isEnabled) {
+    private CredentialProviderInfo createCredentialProviderInfoWithIsEnabled(
+            String packageName, String className, CharSequence serviceLabel, boolean isEnabled) {
+        return createCredentialProviderInfoBuilder(packageName, className, serviceLabel, "App Name")
+                .setEnabled(isEnabled)
+                .build();
+    }
+
+    private CredentialProviderInfo createCredentialProviderInfoWithAppLabel(
+            String packageName, String className, CharSequence serviceLabel, String appLabel) {
+        return createCredentialProviderInfoBuilder(packageName, className, serviceLabel, appLabel)
+                .build();
+    }
+
+    private CredentialProviderInfo.Builder createCredentialProviderInfoBuilder(
+            String packageName, String className, CharSequence serviceLabel, String appLabel) {
         ServiceInfo si = new ServiceInfo();
         si.packageName = packageName;
         si.name = className;
-        si.nonLocalizedLabel = "test";
+        si.nonLocalizedLabel = serviceLabel;
 
         si.applicationInfo = new ApplicationInfo();
         si.applicationInfo.packageName = packageName;
-        si.applicationInfo.nonLocalizedLabel = "test";
+        si.applicationInfo.nonLocalizedLabel = appLabel;
 
-        return new CredentialProviderInfo.Builder(si)
-                .setOverrideLabel(label)
-                .setEnabled(isEnabled)
-                .build();
+        return new CredentialProviderInfo.Builder(si).setOverrideLabel(serviceLabel);
     }
 }
diff --git a/tests/unit/src/com/android/settings/language/LanguagePreferenceControllerTest.java b/tests/unit/src/com/android/settings/language/LanguagePreferenceControllerTest.java
new file mode 100644
index 0000000..6622753
--- /dev/null
+++ b/tests/unit/src/com/android/settings/language/LanguagePreferenceControllerTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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.language;
+
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.util.FeatureFlagUtils;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.Settings;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class LanguagePreferenceControllerTest {
+    private boolean mCacheFeatureFlagSwitch = false;
+    private Context mContext;
+    private LanguagePreferenceController mController;
+
+    @Before
+    public void setup() {
+        mContext = ApplicationProvider.getApplicationContext();
+        mCacheFeatureFlagSwitch =
+                FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
+        mController = new LanguagePreferenceController(mContext, "key");
+
+    }
+
+    @After
+    public void tearDown() {
+        FeatureFlagUtils.setEnabled(
+                mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI, mCacheFeatureFlagSwitch);
+    }
+
+    @Test
+    public void getAvailabilityStatus_featureFlagOff_returnUnavailable() {
+        FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI,
+                false);
+
+        int result = mController.getAvailabilityStatus();
+
+        assertEquals(CONDITIONALLY_UNAVAILABLE, result);
+    }
+
+    @Test
+    public void getAvailabilityStatus_featureFlagOff_LanguageAndInputSettingsActivityEnabled() {
+        FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI,
+                false);
+
+        mController.getAvailabilityStatus();
+
+        assertTrue(isActivityEnable(mContext, Settings.LanguageAndInputSettingsActivity.class));
+        assertFalse(isActivityEnable(mContext, Settings.LanguageSettingsActivity.class));
+    }
+
+    @Test
+    public void getAvailabilityStatus_featureFlagOff_LanguageAndInputSettingsActivitydisabled() {
+        FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI,
+                true);
+
+        mController.getAvailabilityStatus();
+
+        assertFalse(isActivityEnable(mContext, Settings.LanguageAndInputSettingsActivity.class));
+        assertTrue(isActivityEnable(mContext, Settings.LanguageSettingsActivity.class));
+    }
+
+    private static boolean isActivityEnable(Context context, Class klazz) {
+        PackageManager packageManager = context.getPackageManager();
+        ComponentName componentName =
+                new ComponentName(context, klazz);
+        int flag = packageManager.getComponentEnabledSetting(componentName);
+        return flag == PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+    }
+}
diff --git a/tests/unit/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceControllerTest.java
index 292b4a9..39f2050 100644
--- a/tests/unit/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceControllerTest.java
@@ -28,9 +28,11 @@
 import android.content.Context;
 import android.os.PersistableBundle;
 import android.telephony.CarrierConfigManager;
+import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 
+import androidx.lifecycle.Lifecycle;
 import androidx.preference.SwitchPreference;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -61,6 +63,10 @@
     private CarrierConfigCache mCarrierConfigCache;
     @Mock
     private ProgressDialog mProgressDialog;
+    @Mock
+    private ServiceState mTestServiceState;
+    @Mock
+    private Lifecycle mLifecycle;
 
     private PersistableBundle mCarrierConfig;
     private AutoSelectPreferenceController mController;
@@ -88,7 +94,16 @@
         mController = new AutoSelectPreferenceController(mContext, "auto_select");
         mController.mProgressDialog = mProgressDialog;
         mController.mSwitchPreference = mSwitchPreference;
-        mController.init(SUB_ID);
+        mController.init(mLifecycle, SUB_ID);
+        sleepAfterInit();
+    }
+
+    private void sleepAfterInit() {
+        try {
+            Thread.sleep(2000);
+        } catch (Exception e) {
+            fail("Sleep timeout " + e);
+        }
     }
 
     @Test
@@ -111,7 +126,8 @@
 
     @Test
     public void updateState_isRoaming_enabled() {
-        when(mTelephonyManager.getServiceState().getRoaming()).thenReturn(true);
+        when(mTelephonyManager.getServiceState()).thenReturn(mTestServiceState);
+        when(mTestServiceState.getRoaming()).thenReturn(true);
 
         mController.updateState(mSwitchPreference);
 
@@ -120,7 +136,8 @@
 
     @Test
     public void updateState_notRoamingWithAutoSelectOn_disabled() {
-        when(mTelephonyManager.getServiceState().getRoaming()).thenReturn(false);
+        when(mTelephonyManager.getServiceState()).thenReturn(mTestServiceState);
+        when(mTestServiceState.getRoaming()).thenReturn(false);
         doReturn(OPERATOR_NAME).when(mTelephonyManager).getSimOperatorName();
 
         mController.updateState(mSwitchPreference);
@@ -136,6 +153,34 @@
         when(mCarrierConfigCache.getConfigForSubId(SUB_ID)).thenReturn(null);
 
         // Should not crash
-        mController.init(SUB_ID);
+        mController.init(mLifecycle, SUB_ID);
+    }
+
+    @Test
+    public void updateUiAutoSelectValue_serviceStateGetIsManualSelection_isCheckedFalse() {
+        when(mTelephonyManager.getNetworkSelectionMode()).thenReturn(
+                TelephonyManager.NETWORK_SELECTION_MODE_AUTO);
+        when(mTestServiceState.getIsManualSelection()).thenReturn(true);
+        mController.init(mLifecycle, SUB_ID);
+        sleepAfterInit();
+
+        mController.updateUiAutoSelectValue(mTestServiceState);
+
+        assertThat(mController.isChecked()).isFalse();
+        assertThat(mSwitchPreference.isChecked()).isFalse();
+    }
+
+    @Test
+    public void updateUiAutoSelectValue_serviceStateGetIsAutoSelection_isCheckedTrue() {
+        when(mTelephonyManager.getNetworkSelectionMode()).thenReturn(
+                TelephonyManager.NETWORK_SELECTION_MODE_MANUAL);
+        when(mTestServiceState.getIsManualSelection()).thenReturn(false);
+        mController.init(mLifecycle, SUB_ID);
+        sleepAfterInit();
+
+        mController.updateUiAutoSelectValue(mTestServiceState);
+
+        assertThat(mController.isChecked()).isTrue();
+        assertThat(mSwitchPreference.isChecked()).isTrue();
     }
 }