Merge "Check P2P channel before requesting network info" into udc-qpr-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 9c5d6c6..4a80dd0 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -4840,7 +4840,7 @@
         </activity>
 
         <activity android:name="Settings$FactoryResetActivity"
-                  android:permission="android.permission.BACKUP"
+                  android:permission="android.permission.MASTER_CLEAR"
                   android:label="@string/main_clear_title"
                   android:exported="true"
                   android:theme="@style/SudThemeGlif.Light">
diff --git a/res/layout/preference_check_icon.xml b/res/layout/preference_check_icon.xml
index 1b759fc..bd0dd79 100644
--- a/res/layout/preference_check_icon.xml
+++ b/res/layout/preference_check_icon.xml
@@ -20,4 +20,5 @@
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_centerVertical="true"
-    android:layout_marginHorizontal="16dp"/>
\ No newline at end of file
+    android:layout_marginHorizontal="16dp"
+    android:contentDescription="@*android:string/checked"/>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 3184a1f..897d76a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1526,8 +1526,6 @@
     <string name="bluetooth_companion_app_remove_association_dialog_title">Disconnect App?</string>
     <!-- Bluetooth device details companion apps. The body of confirmation dialog for remove association. [CHAR LIMIT=60] -->
     <string name="bluetooth_companion_app_body"><xliff:g id="app_name" example="App Name">%1$s</xliff:g> app will no longer connect to your <xliff:g id="device_name" example="Device Name">%2$s</xliff:g></string>
-    <!-- Summary of Bluetooth LE Audio toggle in Device Details. [CHAR LIMIT=40] -->
-    <string name="device_details_leaudio_toggle_summary">Experimental. Improves audio quality.</string>
 
     <!--  Bluetooth device details. In the confirmation dialog for unpairing a paired device, this is the label on the button that will complete the unpairing action. -->
     <string name="bluetooth_unpair_dialog_forget_confirm_button">Forget device</string>
@@ -6431,7 +6429,7 @@
     <!-- Search keywords for the "Delete Guest Activity" section in Multiple Users Screen. [CHAR LIMIT=NONE] -->
     <string name="remove_guest_on_exit_keywords">delete, guest, activity, remove, data, visitor, erase</string>
     <!-- Title of preference to enable guest calling[CHAR LIMIT=40] -->
-    <string name="enable_guest_calling">Allow guest to use phone</string>
+    <string name="enable_guest_calling">Allow guest to make phone calls</string>
     <!-- Summary of preference to enable guest calling [CHAR LIMIT=NONE] -->
     <string name="enable_guest_calling_summary">Call history will be shared with guest user</string>
 
@@ -7182,6 +7180,18 @@
     <!-- Sound: Title for the option managing notification volume. [CHAR LIMIT=30] -->
     <string name="notification_volume_option_title">Notification volume</string>
 
+    <!-- Sound: Content description of ring volume title in silent mode. [CHAR LIMIT=NONE BACKUP_MESSAGE_ID=8994620163934249882] -->
+    <string name="ringer_content_description_silent_mode">Ringer silent</string>
+
+    <!-- Sound: Content description of ring volume title in vibrate mode. [CHAR LIMIT=NONE BACKUP_MESSAGE_ID=6261841170896561364] -->
+    <string name="ringer_content_description_vibrate_mode">Ringer vibrate</string>
+
+    <!-- Sound: Content description of notification volume title in vibrate mode. [CHAR LIMIT=NONE] -->
+    <string name="notification_volume_content_description_vibrate_mode">Notification volume muted, notifications will vibrate</string>
+
+    <!-- Sound: Content description of volume title in silent mode [CHAR LIMIT=NONE] -->
+    <string name="volume_content_description_silent_mode"> <xliff:g id="volume type" example="notification volume">%1$s</xliff:g> muted</string>
+
     <!-- Sound: Summary for when notification volume is disabled. [CHAR LIMIT=100] -->
     <string name="notification_volume_disabled_summary">Unavailable because ring is muted</string>
 
@@ -11994,7 +12004,7 @@
     <!-- Developer settings: Title for force enabling Notes role. [CHAR LIMIT=50]-->
     <string name="enable_notes_role_title">Force enable Notes role</string>
     <!-- Developer settings: Summary for disabling phantom process monitoring. [CHAR LIMIT=NONE]-->
-    <string name="enable_notes_role_summary">Enable note-taking system integrations via the Notes role. If the Notes role is already enabled, does nothing.</string>
+    <string name="enable_notes_role_summary">Enable note-taking system integrations via the Notes role. If the Notes role is already enabled, does nothing. Requires reboot.</string>
 
 
     <!-- BT LE Audio Device: Media Broadcast -->
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index a2195df..370b17a 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -63,6 +63,7 @@
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.Environment;
 import android.os.IBinder;
 import android.os.INetworkManagementService;
 import android.os.RemoteException;
@@ -97,7 +98,6 @@
 import androidx.annotation.ColorInt;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.StringRes;
 import androidx.annotation.VisibleForTesting;
 import androidx.core.graphics.drawable.IconCompat;
 import androidx.core.graphics.drawable.RoundedBitmapDrawable;
@@ -1309,4 +1309,15 @@
                 com.android.internal.R.bool.config_dreamsOnlyEnabledForDockUser);
         return dreamsSupported && (!dreamsOnlyEnabledForDockUser || canCurrentUserDream(context));
     }
+
+    /**
+     * Get private total size directly.
+     * Referred from StorageManager
+     */
+    public static long getPrimaryStorageSize() {
+        // TODO(b/288103116): remove this method once support by StorageManager.
+        return Environment.getDataDirectory().getTotalSpace()
+                + Environment.getRootDirectory().getTotalSpace();
+    }
+
 }
diff --git a/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java b/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java
index 0767e65..6bee62c 100644
--- a/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java
+++ b/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java
@@ -81,6 +81,8 @@
         final RestrictedSwitchPreference preference =
                 (RestrictedSwitchPreference) pref;
         final CharSequence label = mPkgInfo.applicationInfo.loadLabel(mPm);
+        final boolean isAllowedCn = mCn.flattenToShortString().length()
+                <= NotificationManager.MAX_SERVICE_COMPONENT_NAME_LENGTH;
         final boolean isEnabled = isServiceEnabled(mCn);
         preference.setChecked(isEnabled);
         preference.setOnPreferenceChangeListener((p, newValue) -> {
@@ -105,7 +107,8 @@
                 return false;
             }
         });
-        preference.updateState(mCn.getPackageName(), mPkgInfo.applicationInfo.uid, isEnabled);
+        preference.updateState(
+                mCn.getPackageName(), mPkgInfo.applicationInfo.uid, isAllowedCn, isEnabled);
     }
 
     public void disable(final ComponentName cn) {
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
index 701967b..00f18e8 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
@@ -116,10 +116,6 @@
         pref.setTitle(profile.getNameResource(mCachedDevice.getDevice()));
         pref.setOnPreferenceClickListener(this);
         pref.setOrder(profile.getOrdinal());
-
-        if (profile instanceof LeAudioProfile) {
-            pref.setSummary(R.string.device_details_leaudio_toggle_summary);
-        }
         return pref;
     }
 
diff --git a/src/com/android/settings/deviceinfo/StorageCategoryFragment.java b/src/com/android/settings/deviceinfo/StorageCategoryFragment.java
index 52f453d..d1d4cbe 100644
--- a/src/com/android/settings/deviceinfo/StorageCategoryFragment.java
+++ b/src/com/android/settings/deviceinfo/StorageCategoryFragment.java
@@ -211,7 +211,9 @@
 
         setLoading(false /* loading */, false /* animate */);
 
-        final long privateUsedBytes = mStorageInfo.totalBytes - mStorageInfo.freeBytes;
+        // TODO(b/288103116): replace with  new API to get TotalBytes before rounding
+        //  once support by StorageManager.
+        final long privateUsedBytes = Utils.getPrimaryStorageSize() - mStorageInfo.freeBytes;
         mPreferenceController.setVolume(mSelectedStorageEntry.getVolumeInfo());
         mPreferenceController.setUsedSize(privateUsedBytes);
         mPreferenceController.setTotalSize(mStorageInfo.totalBytes);
diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
index f31f2be..4138057 100644
--- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
+++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
@@ -387,7 +387,9 @@
 
         setLoading(false /* loading */, false /* animate */);
 
-        final long privateUsedBytes = mStorageInfo.totalBytes - mStorageInfo.freeBytes;
+        // TODO(b/288103116): replace with  new API to get TotalBytes before rounding
+        //  once support by StorageManager.
+        final long privateUsedBytes = Utils.getPrimaryStorageSize() - mStorageInfo.freeBytes;
         mPreferenceController.setVolume(mSelectedStorageEntry.getVolumeInfo());
         mPreferenceController.setUsedSize(privateUsedBytes);
         mPreferenceController.setTotalSize(mStorageInfo.totalBytes);
diff --git a/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceController.java b/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceController.java
index e682783..43dc9dd 100644
--- a/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceController.java
+++ b/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceController.java
@@ -74,10 +74,14 @@
         return ThreadUtils.postOnBackgroundThread(() -> {
             final PrivateStorageInfo info = PrivateStorageInfo.getPrivateStorageInfo(
                     getStorageManagerVolumeProvider());
-            storageCacheHelper.cacheUsedSize(info.totalBytes - info.freeBytes);
+
+            // TODO(b/288103116): replace with  new API to get TotalBytes before rounding
+            //  once support by StorageManager.
+            long usedBytes = Utils.getPrimaryStorageSize() - info.freeBytes;
+            storageCacheHelper.cacheUsedSize(usedBytes);
             ThreadUtils.postOnMainThread(() -> {
                 preference.setSummary(
-                        getSummary(info.totalBytes - info.freeBytes, info.totalBytes));
+                        getSummary(usedBytes, info.totalBytes));
             });
         });
     }
diff --git a/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java
index be2a64a..23559d4 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java
@@ -26,6 +26,7 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
+import com.android.settings.Utils;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settingslib.utils.ThreadUtils;
 import com.android.settingslib.widget.UsageProgressBarPreference;
@@ -92,7 +93,9 @@
                 if (mStorageEntry.isPrivate()) {
                     // StorageStatsManager can only query private storages.
                     mTotalBytes = mStorageStatsManager.getTotalBytes(mStorageEntry.getFsUuid());
-                    mUsedBytes = mTotalBytes
+                    // TODO(b/288103116): replace with  new API to get TotalBytes before rounding
+                    //  once support by StorageManager.
+                    mUsedBytes = Utils.getPrimaryStorageSize()
                             - mStorageStatsManager.getFreeBytes(mStorageEntry.getFsUuid());
                 } else {
                     final File rootFile = mStorageEntry.getPath();
diff --git a/src/com/android/settings/localepicker/LocaleDialogFragment.java b/src/com/android/settings/localepicker/LocaleDialogFragment.java
index ad9e10f..f54446a 100644
--- a/src/com/android/settings/localepicker/LocaleDialogFragment.java
+++ b/src/com/android/settings/localepicker/LocaleDialogFragment.java
@@ -164,15 +164,18 @@
         public void onClick(DialogInterface dialog, int which) {
             if (mDialogType == DIALOG_CONFIRM_SYSTEM_DEFAULT) {
                 int result = Activity.RESULT_CANCELED;
+                boolean changed = false;
                 if (which == DialogInterface.BUTTON_POSITIVE) {
                     result = Activity.RESULT_OK;
+                    changed = true;
                 }
                 Intent intent = new Intent();
                 Bundle bundle = new Bundle();
                 bundle.putInt(ARG_DIALOG_TYPE, DIALOG_CONFIRM_SYSTEM_DEFAULT);
                 intent.putExtras(bundle);
                 mParent.onActivityResult(DIALOG_CONFIRM_SYSTEM_DEFAULT, result, intent);
-                mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_CHANGE_LANGUAGE);
+                mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_CHANGE_LANGUAGE,
+                        changed);
             }
             mShouldKeepDialog = false;
         }
diff --git a/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java b/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java
index edd3026..3d7976a 100644
--- a/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java
+++ b/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.localepicker;
 
+import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.os.Bundle;
@@ -37,6 +38,7 @@
 import com.android.internal.app.LocalePicker;
 import com.android.internal.app.LocaleStore;
 import com.android.settings.R;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.shortcut.ShortcutsUpdateTask;
 
 import java.text.NumberFormat;
@@ -210,6 +212,13 @@
             Log.e(TAG, String.format(Locale.US,
                     "Negative position in onItemMove %d -> %d", fromPosition, toPosition));
         }
+
+        if (fromPosition != toPosition) {
+            FeatureFactory.getFactory(mContext).getMetricsFeatureProvider()
+                    .action(mContext, SettingsEnums.ACTION_REORDER_LANGUAGE,
+                            mDragLocale.getLocale().toLanguageTag() + " move to " + toPosition);
+        }
+
         notifyItemChanged(fromPosition); // to update the numbers
         notifyItemChanged(toPosition);
         notifyItemMoved(fromPosition, toPosition);
@@ -244,8 +253,13 @@
 
     void removeChecked() {
         int itemCount = mFeedItemList.size();
+        LocaleStore.LocaleInfo localeInfo;
         for (int i = itemCount - 1; i >= 0; i--) {
-            if (mFeedItemList.get(i).getChecked()) {
+            localeInfo = mFeedItemList.get(i);
+            if (localeInfo.getChecked()) {
+                FeatureFactory.getFactory(mContext).getMetricsFeatureProvider()
+                        .action(mContext, SettingsEnums.ACTION_REMOVE_LANGUAGE,
+                                localeInfo.getLocale().toLanguageTag());
                 mFeedItemList.remove(i);
             }
         }
diff --git a/src/com/android/settings/localepicker/LocaleListEditor.java b/src/com/android/settings/localepicker/LocaleListEditor.java
index 55cff3b..dfdb942 100644
--- a/src/com/android/settings/localepicker/LocaleListEditor.java
+++ b/src/com/android/settings/localepicker/LocaleListEditor.java
@@ -199,9 +199,11 @@
             localeInfo = (LocaleStore.LocaleInfo) data.getSerializableExtra(INTENT_LOCALE_KEY);
             String preferencesTags = Settings.System.getString(
                     getContext().getContentResolver(), Settings.System.LOCALE_PREFERENCES);
-
-            mAdapter.addLocale(mayAppendUnicodeTags(localeInfo, preferencesTags));
+            localeInfo = mayAppendUnicodeTags(localeInfo, preferencesTags);
+            mAdapter.addLocale(localeInfo);
             updateVisibilityOfRemoveMenu();
+            mMetricsFeatureProvider.action(getContext(), SettingsEnums.ACTION_ADD_LANGUAGE,
+                    localeInfo.getLocale().toLanguageTag());
         } else if (requestCode == DIALOG_CONFIRM_SYSTEM_DEFAULT) {
             localeInfo = mAdapter.getFeedItemList().get(0);
             if (resultCode == Activity.RESULT_OK) {
@@ -214,6 +216,9 @@
                     LocaleDialogFragment localeDialogFragment = LocaleDialogFragment.newInstance();
                     localeDialogFragment.setArguments(args);
                     localeDialogFragment.show(mFragmentManager, TAG_DIALOG_NOT_AVAILABLE);
+                    mMetricsFeatureProvider.action(getContext(),
+                            SettingsEnums.ACTION_NOT_SUPPORTED_SYSTEM_LANGUAGE,
+                            localeInfo.getLocale().toLanguageTag());
                 }
             } else {
                 mAdapter.notifyListChanged(localeInfo);
diff --git a/src/com/android/settings/network/SubscriptionUtil.java b/src/com/android/settings/network/SubscriptionUtil.java
index 9d953bf..0cd12fe 100644
--- a/src/com/android/settings/network/SubscriptionUtil.java
+++ b/src/com/android/settings/network/SubscriptionUtil.java
@@ -23,6 +23,7 @@
 
 import android.annotation.Nullable;
 import android.content.Context;
+import android.content.SharedPreferences;
 import android.os.ParcelUuid;
 import android.provider.Settings;
 import android.telephony.PhoneNumberUtils;
@@ -61,6 +62,10 @@
 public class SubscriptionUtil {
     private static final String TAG = "SubscriptionUtil";
     private static final String PROFILE_GENERIC_DISPLAY_NAME = "CARD";
+    @VisibleForTesting
+    static final String SUB_ID = "sub_id";
+    @VisibleForTesting
+    static final String KEY_UNIQUE_SUBSCRIPTION_DISPLAYNAME = "unique_subscription_displayName";
     private static List<SubscriptionInfo> sAvailableResultsForTesting;
     private static List<SubscriptionInfo> sActiveResultsForTesting;
 
@@ -265,20 +270,21 @@
         // Map of SubscriptionId to DisplayName
         final Supplier<Stream<DisplayInfo>> originalInfos =
                 () -> getAvailableSubscriptions(context)
-                .stream()
-                .filter(i -> {
-                    // Filter out null values.
-                    return (i != null && i.getDisplayName() != null);
-                })
-                .map(i -> {
-                    DisplayInfo info = new DisplayInfo();
-                    info.subscriptionInfo = i;
-                    String displayName = i.getDisplayName().toString();
-                    info.originalName = TextUtils.equals(displayName, PROFILE_GENERIC_DISPLAY_NAME)
-                            ? context.getResources().getString(R.string.sim_card)
-                            : displayName.trim();
-                    return info;
-                });
+                        .stream()
+                        .filter(i -> {
+                            // Filter out null values.
+                            return (i != null && i.getDisplayName() != null);
+                        })
+                        .map(i -> {
+                            DisplayInfo info = new DisplayInfo();
+                            info.subscriptionInfo = i;
+                            String displayName = i.getDisplayName().toString();
+                            info.originalName =
+                                    TextUtils.equals(displayName, PROFILE_GENERIC_DISPLAY_NAME)
+                                    ? context.getResources().getString(R.string.sim_card)
+                                    : displayName.trim();
+                            return info;
+                        });
 
         // TODO(goldmanj) consider using a map of DisplayName to SubscriptionInfos.
         // A Unique set of display names
@@ -292,6 +298,14 @@
         // If a display name is duplicate, append the final 4 digits of the phone number.
         // Creates a mapping of Subscription id to original display name + phone number display name
         final Supplier<Stream<DisplayInfo>> uniqueInfos = () -> originalInfos.get().map(info -> {
+            String cachedDisplayName = getDisplayNameFromSharedPreference(
+                    context, info.subscriptionInfo.getSubscriptionId());
+            if (!TextUtils.isEmpty(cachedDisplayName)) {
+                Log.d(TAG, "use cached display name : " + cachedDisplayName);
+                info.uniqueName = cachedDisplayName;
+                return info;
+            }
+
             if (duplicateOriginalNames.contains(info.originalName)) {
                 // This may return null, if the user cannot view the phone number itself.
                 final String phoneNumber = getBidiFormattedPhoneNumber(context,
@@ -299,15 +313,17 @@
                 String lastFourDigits = "";
                 if (phoneNumber != null) {
                     lastFourDigits = (phoneNumber.length() > 4)
-                        ? phoneNumber.substring(phoneNumber.length() - 4) : phoneNumber;
+                            ? phoneNumber.substring(phoneNumber.length() - 4) : phoneNumber;
                 }
-
                 if (TextUtils.isEmpty(lastFourDigits)) {
                     info.uniqueName = info.originalName;
                 } else {
                     info.uniqueName = info.originalName + " " + lastFourDigits;
+                    Log.d(TAG, "Cache display name [" + info.uniqueName + "] for sub id "
+                            + info.subscriptionInfo.getSubscriptionId());
+                    saveDisplayNameToSharedPreference(
+                            context, info.subscriptionInfo.getSubscriptionId(), info.uniqueName);
                 }
-
             } else {
                 info.uniqueName = info.originalName;
             }
@@ -371,6 +387,27 @@
         return getUniqueSubscriptionDisplayName(info.getSubscriptionId(), context);
     }
 
+
+    private static SharedPreferences getDisplayNameSharedPreferences(Context context) {
+        return context.getSharedPreferences(
+                KEY_UNIQUE_SUBSCRIPTION_DISPLAYNAME, Context.MODE_PRIVATE);
+    }
+
+    private static SharedPreferences.Editor getDisplayNameSharedPreferenceEditor(Context context) {
+        return getDisplayNameSharedPreferences(context).edit();
+    }
+
+    private static void saveDisplayNameToSharedPreference(
+            Context context, int subId, CharSequence displayName) {
+        getDisplayNameSharedPreferenceEditor(context)
+                .putString(SUB_ID + subId, String.valueOf(displayName))
+                .apply();
+    }
+
+    private static String getDisplayNameFromSharedPreference(Context context, int subid) {
+        return getDisplayNameSharedPreferences(context).getString(SUB_ID + subid, "");
+    }
+
     public static String getDisplayName(SubscriptionInfo info) {
         final CharSequence name = info.getDisplayName();
         if (name != null) {
diff --git a/src/com/android/settings/network/telephony/AbstractMobileNetworkSettings.java b/src/com/android/settings/network/telephony/AbstractMobileNetworkSettings.java
index 245ac83..7addb59 100644
--- a/src/com/android/settings/network/telephony/AbstractMobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/AbstractMobileNetworkSettings.java
@@ -18,7 +18,6 @@
 
 import android.os.SystemClock;
 import android.text.TextUtils;
-import android.util.Log;
 
 import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
@@ -66,8 +65,7 @@
 
     TelephonyStatusControlSession setTelephonyAvailabilityStatus(
             Collection<AbstractPreferenceController> listOfPrefControllers) {
-        return (new TelephonyStatusControlSession.Builder(listOfPrefControllers))
-                .build();
+        return new TelephonyStatusControlSession(listOfPrefControllers, getLifecycle());
     }
 
     @Override
diff --git a/src/com/android/settings/network/telephony/TelephonyStatusControlSession.java b/src/com/android/settings/network/telephony/TelephonyStatusControlSession.java
deleted file mode 100644
index 3716f1f..0000000
--- a/src/com/android/settings/network/telephony/TelephonyStatusControlSession.java
+++ /dev/null
@@ -1,117 +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.network.telephony;
-
-import android.util.Log;
-
-import com.android.settings.core.BasePreferenceController;
-import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.utils.ThreadUtils;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-
-/**
- * Session for controlling the status of TelephonyPreferenceController(s).
- *
- * Within this session, result of {@link BasePreferenceController#availabilityStatus()}
- * would be under control.
- */
-public class TelephonyStatusControlSession implements AutoCloseable {
-
-    private static final String LOG_TAG = "TelephonyStatusControlSS";
-
-    private Collection<AbstractPreferenceController> mControllers;
-    private Collection<Future<Boolean>> mResult = new ArrayList<>();
-
-    /**
-     * Buider of session
-     */
-    public static class Builder {
-        private Collection<AbstractPreferenceController> mControllers;
-
-        /**
-         * Constructor
-         *
-         * @param controllers is a collection of {@link AbstractPreferenceController}
-         *        which would have {@link BasePreferenceController#availabilityStatus()}
-         *        under control within this session.
-         */
-        public Builder(Collection<AbstractPreferenceController> controllers) {
-            mControllers = controllers;
-        }
-
-        /**
-         * Method to build this session.
-         * @return {@link TelephonyStatusControlSession} session been setup.
-         */
-        public TelephonyStatusControlSession build() {
-            return new TelephonyStatusControlSession(mControllers);
-        }
-    }
-
-    private TelephonyStatusControlSession(Collection<AbstractPreferenceController> controllers) {
-        mControllers = controllers;
-        controllers.forEach(prefCtrl -> mResult
-                .add(ThreadUtils.postOnBackgroundThread(() -> setupAvailabilityStatus(prefCtrl))));
-
-    }
-
-    /**
-     * Close the session.
-     *
-     * No longer control the status.
-     */
-    public void close() {
-        //check the background thread is finished then unset the status of availability.
-
-        for (Future<Boolean> result : mResult) {
-            try {
-                result.get();
-            } catch (ExecutionException | InterruptedException exception) {
-                Log.e(LOG_TAG, "setup availability status failed!", exception);
-            }
-        }
-        unsetAvailabilityStatus(mControllers);
-    }
-
-    private Boolean setupAvailabilityStatus(AbstractPreferenceController controller) {
-        try {
-            if (controller instanceof TelephonyAvailabilityHandler) {
-                int status = ((BasePreferenceController) controller)
-                        .getAvailabilityStatus();
-                ((TelephonyAvailabilityHandler) controller).setAvailabilityStatus(status);
-            }
-            return true;
-        } catch (Exception exception) {
-            Log.e(LOG_TAG, "Setup availability status failed!", exception);
-            return false;
-        }
-    }
-
-    private void unsetAvailabilityStatus(
-            Collection<AbstractPreferenceController> controllerLists) {
-        controllerLists.stream()
-                .filter(controller -> controller instanceof TelephonyAvailabilityHandler)
-                .map(TelephonyAvailabilityHandler.class::cast)
-                .forEach(controller -> {
-                    controller.unsetAvailabilityStatus();
-                });
-    }
-}
diff --git a/src/com/android/settings/network/telephony/TelephonyStatusControlSession.kt b/src/com/android/settings/network/telephony/TelephonyStatusControlSession.kt
new file mode 100644
index 0000000..0e63c8c
--- /dev/null
+++ b/src/com/android/settings/network/telephony/TelephonyStatusControlSession.kt
@@ -0,0 +1,86 @@
+/*
+ * 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.network.telephony
+
+import android.util.Log
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.coroutineScope
+import com.android.settings.core.BasePreferenceController
+import com.android.settingslib.core.AbstractPreferenceController
+import com.google.common.collect.Sets
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.yield
+
+/**
+ * Session for controlling the status of TelephonyPreferenceController(s).
+ *
+ * Within this session, result of [BasePreferenceController.getAvailabilityStatus]
+ * would be under control.
+ */
+class TelephonyStatusControlSession(
+    private val controllers: Collection<AbstractPreferenceController>,
+    lifecycle: Lifecycle,
+) : AutoCloseable {
+    private var job: Job? = null
+    private val controllerSet = Sets.newConcurrentHashSet<TelephonyAvailabilityHandler>()
+
+    init {
+        job = lifecycle.coroutineScope.launch(Dispatchers.Default) {
+            for (controller in controllers) {
+                launch {
+                    setupAvailabilityStatus(controller)
+                }
+            }
+        }
+    }
+
+    /**
+     * Close the session.
+     *
+     * No longer control the status.
+     */
+    override fun close() {
+        job?.cancel()
+        unsetAvailabilityStatus()
+    }
+
+    private suspend fun setupAvailabilityStatus(controller: AbstractPreferenceController): Boolean =
+        try {
+            if (controller is TelephonyAvailabilityHandler) {
+                val status = (controller as BasePreferenceController).availabilityStatus
+                yield() // prompt cancellation guarantee
+                if (controllerSet.add(controller)) {
+                    controller.setAvailabilityStatus(status)
+                }
+            }
+            true
+        } catch (exception: Exception) {
+            Log.e(LOG_TAG, "Setup availability status failed!", exception)
+            false
+        }
+
+    private fun unsetAvailabilityStatus() {
+        for (controller in controllerSet) {
+            controller.unsetAvailabilityStatus()
+        }
+    }
+
+    companion object {
+        private const val LOG_TAG = "TelephonyStatusControlSS"
+    }
+}
diff --git a/src/com/android/settings/notification/MediaVolumePreferenceController.java b/src/com/android/settings/notification/MediaVolumePreferenceController.java
index e40a2b4..79df55a 100644
--- a/src/com/android/settings/notification/MediaVolumePreferenceController.java
+++ b/src/com/android/settings/notification/MediaVolumePreferenceController.java
@@ -52,6 +52,7 @@
 
     public MediaVolumePreferenceController(Context context) {
         super(context, KEY_MEDIA_VOLUME);
+        mVolumePreferenceListener = this::updateContentDescription;
     }
 
     @Override
@@ -109,6 +110,18 @@
         return false;
     }
 
+    private void updateContentDescription() {
+        if (mPreference != null) {
+            if (mPreference.isMuted()) {
+                mPreference.updateContentDescription(
+                        mContext.getString(R.string.volume_content_description_silent_mode,
+                        mPreference.getTitle()));
+            } else {
+                mPreference.updateContentDescription(mPreference.getTitle());
+            }
+        }
+    }
+
     @Override
     public SliceAction getSliceEndItem(Context context) {
         if (!isSupportEndItem()) {
diff --git a/src/com/android/settings/notification/NotificationAccessConfirmationActivity.java b/src/com/android/settings/notification/NotificationAccessConfirmationActivity.java
index dfe6df2..a6b565a 100644
--- a/src/com/android/settings/notification/NotificationAccessConfirmationActivity.java
+++ b/src/com/android/settings/notification/NotificationAccessConfirmationActivity.java
@@ -67,7 +67,9 @@
         mUserId = getIntent().getIntExtra(EXTRA_USER_ID, UserHandle.USER_NULL);
         CharSequence mAppLabel;
 
-        if (mComponentName == null || mComponentName.getPackageName() == null) {
+        if (mComponentName == null || mComponentName.getPackageName() == null
+                || mComponentName.flattenToString().length()
+                > NotificationManager.MAX_SERVICE_COMPONENT_NAME_LENGTH) {
             finish();
             return;
         }
diff --git a/src/com/android/settings/notification/NotificationAccessSettings.java b/src/com/android/settings/notification/NotificationAccessSettings.java
index 369c4f6..e2ef0dd 100644
--- a/src/com/android/settings/notification/NotificationAccessSettings.java
+++ b/src/com/android/settings/notification/NotificationAccessSettings.java
@@ -66,7 +66,6 @@
     private static final String TAG = "NotifAccessSettings";
     static final String ALLOWED_KEY = "allowed";
     static final String NOT_ALLOWED_KEY = "not_allowed";
-    private static final int MAX_CN_LENGTH = 500;
 
     private static final ManagedServiceSettings.Config CONFIG =
             new ManagedServiceSettings.Config.Builder()
@@ -150,7 +149,8 @@
         for (ServiceInfo service : services) {
             final ComponentName cn = new ComponentName(service.packageName, service.name);
             boolean isAllowed = mNm.isNotificationListenerAccessGranted(cn);
-            if (!isAllowed && cn.flattenToString().length() > MAX_CN_LENGTH) {
+            if (!isAllowed && cn.flattenToString().length()
+                    > NotificationManager.MAX_SERVICE_COMPONENT_NAME_LENGTH) {
                 continue;
             }
 
diff --git a/src/com/android/settings/notification/NotificationVolumePreferenceController.java b/src/com/android/settings/notification/NotificationVolumePreferenceController.java
index cf8a33f..fe7b70b 100644
--- a/src/com/android/settings/notification/NotificationVolumePreferenceController.java
+++ b/src/com/android/settings/notification/NotificationVolumePreferenceController.java
@@ -26,6 +26,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.service.notification.NotificationListenerService;
+import android.view.View;
 
 import androidx.lifecycle.OnLifecycleEvent;
 import androidx.preference.PreferenceScreen;
@@ -75,6 +76,7 @@
 
         updateEffectsSuppressor();
         selectPreferenceIconState();
+        updateContentDescription();
         updateEnabledState();
     }
 
@@ -120,23 +122,37 @@
     }
 
     @Override
-    protected void selectPreferenceIconState() {
+    protected int getEffectiveRingerMode() {
+        if (mVibrator == null && mRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
+            return AudioManager.RINGER_MODE_SILENT;
+        } else if (mRingerMode == AudioManager.RINGER_MODE_NORMAL) {
+            if (mHelper.getStreamVolume(AudioManager.STREAM_NOTIFICATION) == 0) {
+                // Ring is in normal, but notification is in silent.
+                return AudioManager.RINGER_MODE_SILENT;
+            }
+        }
+        return mRingerMode;
+    }
+
+    @Override
+    protected void updateContentDescription() {
         if (mPreference != null) {
-            if (mVibrator != null && mRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
-                mMuteIcon = mVibrateIconId;
-                mPreference.showIcon(mVibrateIconId);
-            } else if (mRingerMode == AudioManager.RINGER_MODE_SILENT
-                    || mVibrator == null && mRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
-                mMuteIcon = mSilentIconId;
-                mPreference.showIcon(mSilentIconId);
-            } else { // ringmode normal: could be that we are still silent
-                if (mHelper.getStreamVolume(AudioManager.STREAM_NOTIFICATION) == 0) {
-                    // ring is in normal, but notification is in silent
-                    mMuteIcon = mSilentIconId;
-                    mPreference.showIcon(mSilentIconId);
-                } else {
-                    mPreference.showIcon(mNormalIconId);
-                }
+            int ringerMode = getEffectiveRingerMode();
+            if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
+                mPreference.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
+                mPreference.updateContentDescription(
+                        mContext.getString(
+                                R.string.notification_volume_content_description_vibrate_mode));
+            } else if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
+                mPreference.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
+                mPreference.updateContentDescription(
+                        mContext.getString(R.string.volume_content_description_silent_mode,
+                                mPreference.getTitle()));
+            } else {
+                // Set a11y mode to none in order not to trigger talkback while changing
+                // notification volume in normal mode.
+                mPreference.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_NONE);
+                mPreference.updateContentDescription(mPreference.getTitle());
             }
         }
     }
@@ -169,6 +185,7 @@
                     break;
                 case NOTIFICATION_VOLUME_CHANGED:
                     selectPreferenceIconState();
+                    updateContentDescription();
                     updateEnabledState();
                     break;
             }
diff --git a/src/com/android/settings/notification/RingerModeAffectedVolumePreferenceController.java b/src/com/android/settings/notification/RingerModeAffectedVolumePreferenceController.java
index 3687770..ab65f8f 100644
--- a/src/com/android/settings/notification/RingerModeAffectedVolumePreferenceController.java
+++ b/src/com/android/settings/notification/RingerModeAffectedVolumePreferenceController.java
@@ -26,6 +26,7 @@
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.R;
 
 import java.util.Objects;
 
@@ -54,6 +55,7 @@
         if (mVibrator != null && !mVibrator.hasVibrator()) {
             mVibrator = null;
         }
+        mVolumePreferenceListener = this::updateContentDescription;
     }
 
     protected void updateEffectsSuppressor() {
@@ -123,6 +125,7 @@
         }
         mRingerMode = ringerMode;
         selectPreferenceIconState();
+        updateContentDescription();
         return true;
     }
 
@@ -131,10 +134,11 @@
      */
     protected void selectPreferenceIconState() {
         if (mPreference != null) {
-            if (mRingerMode == AudioManager.RINGER_MODE_NORMAL) {
+            int ringerMode = getEffectiveRingerMode();
+            if (ringerMode == AudioManager.RINGER_MODE_NORMAL) {
                 mPreference.showIcon(mNormalIconId);
             } else {
-                if (mRingerMode == AudioManager.RINGER_MODE_VIBRATE && mVibrator != null) {
+                if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
                     mMuteIcon = mVibrateIconId;
                 } else {
                     mMuteIcon = mSilentIconId;
@@ -144,6 +148,28 @@
         }
     }
 
+    protected int getEffectiveRingerMode() {
+        if (mVibrator == null && mRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
+            return AudioManager.RINGER_MODE_SILENT;
+        }
+        return mRingerMode;
+    }
+
+    protected void updateContentDescription() {
+        if (mPreference != null) {
+            int ringerMode = getEffectiveRingerMode();
+            if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
+                mPreference.updateContentDescription(
+                        mContext.getString(R.string.ringer_content_description_vibrate_mode));
+            } else if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
+                mPreference.updateContentDescription(
+                        mContext.getString(R.string.ringer_content_description_silent_mode));
+            } else {
+                mPreference.updateContentDescription(mPreference.getTitle());
+            }
+        }
+    }
+
     protected abstract boolean hintsMatch(int hints);
 
 }
diff --git a/src/com/android/settings/notification/SeparateRingVolumePreferenceController.java b/src/com/android/settings/notification/SeparateRingVolumePreferenceController.java
index b8a9908..91926e3 100644
--- a/src/com/android/settings/notification/SeparateRingVolumePreferenceController.java
+++ b/src/com/android/settings/notification/SeparateRingVolumePreferenceController.java
@@ -65,6 +65,7 @@
         mReceiver.register(true);
         updateEffectsSuppressor();
         selectPreferenceIconState();
+        updateContentDescription();
 
         if (mPreference != null) {
             mPreference.setVisible(getAvailabilityStatus() == AVAILABLE);
diff --git a/src/com/android/settings/notification/VolumeSeekBarPreference.java b/src/com/android/settings/notification/VolumeSeekBarPreference.java
index 14955c4..0000eba 100644
--- a/src/com/android/settings/notification/VolumeSeekBarPreference.java
+++ b/src/com/android/settings/notification/VolumeSeekBarPreference.java
@@ -47,10 +47,13 @@
 
     protected SeekBar mSeekBar;
     private int mStream;
-    private SeekBarVolumizer mVolumizer;
+    @VisibleForTesting
+    SeekBarVolumizer mVolumizer;
     private Callback mCallback;
+    private Listener mListener;
     private ImageView mIconView;
     private TextView mSuppressionTextView;
+    private TextView mTitle;
     private String mSuppressionText;
     private boolean mMuted;
     private boolean mZenMuted;
@@ -98,6 +101,10 @@
         mCallback = callback;
     }
 
+    public void setListener(Listener listener) {
+        mListener = listener;
+    }
+
     public void onActivityResume() {
         if (mStopped) {
             init();
@@ -118,6 +125,7 @@
         mSeekBar = (SeekBar) view.findViewById(com.android.internal.R.id.seekbar);
         mIconView = (ImageView) view.findViewById(com.android.internal.R.id.icon);
         mSuppressionTextView = (TextView) view.findViewById(R.id.suppression_text);
+        mTitle = (TextView) view.findViewById(com.android.internal.R.id.title);
         init();
     }
 
@@ -142,6 +150,9 @@
                 mMuted = muted;
                 mZenMuted = zenMuted;
                 updateIconView();
+                if (mListener != null) {
+                    mListener.onUpdateMuteState();
+                }
             }
             @Override
             public void onStartTrackingTouch(SeekBarVolumizer sbv) {
@@ -165,6 +176,9 @@
         mVolumizer.setSeekBar(mSeekBar);
         updateIconView();
         updateSuppressionText();
+        if (mListener != null) {
+            mListener.onUpdateMuteState();
+        }
         if (!isEnabled()) {
             mSeekBar.setEnabled(false);
             mVolumizer.stop();
@@ -175,7 +189,7 @@
         if (mIconView == null) return;
         if (mIconResId != 0) {
             mIconView.setImageResource(mIconResId);
-        } else if (mMuteIconResId != 0 && mMuted && !mZenMuted) {
+        } else if (mMuteIconResId != 0 && isMuted()) {
             mIconView.setImageResource(mMuteIconResId);
         } else {
             mIconView.setImageDrawable(getIcon());
@@ -208,6 +222,10 @@
         updateSuppressionText();
     }
 
+    protected boolean isMuted() {
+        return mMuted && !mZenMuted;
+    }
+
     protected void updateSuppressionText() {
         if (mSuppressionTextView != null && mSeekBar != null) {
             mSuppressionTextView.setText(mSuppressionText);
@@ -216,6 +234,19 @@
         }
     }
 
+    /**
+     * Update content description of title to improve talkback announcements.
+     */
+    protected void updateContentDescription(CharSequence contentDescription) {
+        if (mTitle == null) return;
+        mTitle.setContentDescription(contentDescription);
+    }
+
+    protected void setAccessibilityLiveRegion(int mode) {
+        if (mTitle == null) return;
+        mTitle.setAccessibilityLiveRegion(mode);
+    }
+
     public interface Callback {
         void onSampleStarting(SeekBarVolumizer sbv);
         void onStreamValueChanged(int stream, int progress);
@@ -225,4 +256,15 @@
          */
         void onStartTrackingTouch(SeekBarVolumizer sbv);
     }
+
+    /**
+     * Listener to view updates in volumeSeekbarPreference.
+     */
+    public interface Listener {
+
+        /**
+         * Listener to mute state updates.
+         */
+        void onUpdateMuteState();
+    }
 }
diff --git a/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java b/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java
index 0414565..285e8dd 100644
--- a/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java
+++ b/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java
@@ -36,6 +36,7 @@
     protected VolumeSeekBarPreference mPreference;
     protected VolumeSeekBarPreference.Callback mVolumePreferenceCallback;
     protected AudioHelper mHelper;
+    protected VolumeSeekBarPreference.Listener mVolumePreferenceListener;
 
     public VolumeSeekBarPreferenceController(Context context, String key) {
         super(context, key);
@@ -62,6 +63,7 @@
     protected void setupVolPreference(PreferenceScreen screen) {
         mPreference = screen.findPreference(getPreferenceKey());
         mPreference.setCallback(mVolumePreferenceCallback);
+        mPreference.setListener(mVolumePreferenceListener);
         mPreference.setStream(getAudioStream());
         mPreference.setMuteIcon(getMuteIcon());
     }
diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
index 314ce05..f2f6520 100644
--- a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
+++ b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
@@ -23,6 +23,7 @@
 import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_CONFIRM_PASSWORD;
 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 android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
 
 import android.app.Activity;
 import android.app.KeyguardManager;
@@ -32,6 +33,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.Configuration;
 import android.graphics.Color;
 import android.hardware.biometrics.BiometricConstants;
 import android.hardware.biometrics.BiometricPrompt;
@@ -379,6 +381,12 @@
         // Translucent activity that is "visible", so it doesn't complain about finish()
         // not being called before onResume().
         setVisible(true);
+
+        if ((getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK)
+                != Configuration.UI_MODE_NIGHT_YES) {
+            getWindow().getInsetsController().setSystemBarsAppearance(
+                    APPEARANCE_LIGHT_STATUS_BARS, APPEARANCE_LIGHT_STATUS_BARS);
+        }
     }
 
     @Override
diff --git a/src/com/android/settings/password/SetupChooseLockPattern.java b/src/com/android/settings/password/SetupChooseLockPattern.java
index 2cad181..4424b4f 100644
--- a/src/com/android/settings/password/SetupChooseLockPattern.java
+++ b/src/com/android/settings/password/SetupChooseLockPattern.java
@@ -90,6 +90,12 @@
             }
             // Show the skip button during SUW but not during Settings > Biometric Enrollment
             mSkipOrClearButton.setOnClickListener(this::onSkipOrClearButtonClick);
+
+            final View headerView = view.findViewById(R.id.sud_layout_header);
+            final ViewGroup.MarginLayoutParams lp =
+                    (ViewGroup.MarginLayoutParams) headerView.getLayoutParams();
+            lp.bottomMargin = 0;
+            view.setLayoutParams(lp);
             return view;
         }
 
diff --git a/src/com/android/settings/regionalpreferences/NumberingSystemItemController.java b/src/com/android/settings/regionalpreferences/NumberingSystemItemController.java
index e3a8d23..2a99e99 100644
--- a/src/com/android/settings/regionalpreferences/NumberingSystemItemController.java
+++ b/src/com/android/settings/regionalpreferences/NumberingSystemItemController.java
@@ -153,7 +153,7 @@
     private void handleLanguageSelect(Preference preference) {
         String selectedLanguage = preference.getKey();
         mMetricsFeatureProvider.action(mContext,
-                SettingsEnums.ACTION_CHOOSE_LANGUAGE_FOR_NUMBERS_PREFERENCES);
+                SettingsEnums.ACTION_CHOOSE_LANGUAGE_FOR_NUMBERS_PREFERENCES, selectedLanguage);
         final Bundle extra = new Bundle();
         extra.putString(RegionalPreferencesEntriesFragment.ARG_KEY_REGIONAL_PREFERENCE,
                 ARG_VALUE_NUMBERING_SYSTEM_SELECT);
@@ -177,7 +177,8 @@
                         saveNumberingSystemToLocale(Locale.forLanguageTag(mSelectedLanguage),
                                 numberingSystem);
                 mMetricsFeatureProvider.action(mContext,
-                        SettingsEnums.ACTION_SET_NUMBERS_PREFERENCES);
+                        SettingsEnums.ACTION_SET_NUMBERS_PREFERENCES,
+                        updatedLocale.getDisplayName() + ": " + numberingSystem);
                 // After updated locale to framework, this fragment will recreate,
                 // so it needs to update the argument of selected language.
                 Bundle bundle = new Bundle();
diff --git a/src/com/android/settings/regionalpreferences/RegionalPreferenceListBasePreferenceController.java b/src/com/android/settings/regionalpreferences/RegionalPreferenceListBasePreferenceController.java
index 1e39fff..432ce0e 100644
--- a/src/com/android/settings/regionalpreferences/RegionalPreferenceListBasePreferenceController.java
+++ b/src/com/android/settings/regionalpreferences/RegionalPreferenceListBasePreferenceController.java
@@ -59,6 +59,8 @@
             TickButtonPreference pref = new TickButtonPreference(mContext);
             mPreferenceCategory.addPreference(pref);
             final String item = unitValues[i];
+            final String value = RegionalPreferencesDataUtils.getDefaultUnicodeExtensionData(
+                    mContext, getExtensionTypes());
             pref.setTitle(getPreferenceTitle(item));
             pref.setKey(item);
             pref.setOnPreferenceClickListener(clickedPref -> {
@@ -66,11 +68,10 @@
                 RegionalPreferencesDataUtils.savePreference(mContext, getExtensionTypes(),
                         item.equals(RegionalPreferencesDataUtils.DEFAULT_VALUE)
                                 ? null : item);
-                mMetricsFeatureProvider.action(mContext, getMetricsActionKey());
+                mMetricsFeatureProvider.action(mContext, getMetricsActionKey(),
+                        getPreferenceTitle(value) + " > " +  getPreferenceTitle(item));
                 return true;
             });
-            String value = RegionalPreferencesDataUtils.getDefaultUnicodeExtensionData(mContext,
-                    getExtensionTypes());
             pref.setSelected(!value.isEmpty() && item.equals(value));
         }
     }
diff --git a/src/com/android/settings/users/GuestTelephonyPreferenceController.java b/src/com/android/settings/users/GuestTelephonyPreferenceController.java
index a935b8a..2aa808f 100644
--- a/src/com/android/settings/users/GuestTelephonyPreferenceController.java
+++ b/src/com/android/settings/users/GuestTelephonyPreferenceController.java
@@ -17,6 +17,7 @@
 package com.android.settings.users;
 
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.os.UserManager;
 
@@ -73,6 +74,7 @@
     public void updateState(Preference preference) {
         super.updateState(preference);
         mUserCaps.updateAddUserCapabilities(mContext);
-        preference.setVisible(isAvailable() && mUserCaps.mUserSwitcherEnabled);
+        preference.setVisible(isAvailable() && mUserCaps.mUserSwitcherEnabled && mContext
+                .getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY));
     }
 }
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index d9fbc42..93b7c78 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -977,10 +977,10 @@
             return;
         }
         try {
-            getContext().getSystemService(UserManager.class)
-                    .removeUserWhenPossible(UserHandle.of(UserHandle.myUserId()),
-                            /* overrideDevicePolicy= */ false);
-            ActivityManager.getService().switchUser(UserHandle.USER_SYSTEM);
+            mUserManager.removeUserWhenPossible(
+                    UserHandle.of(UserHandle.myUserId()), /* overrideDevicePolicy= */ false);
+            ActivityManager.getService().switchUser(
+                    mUserManager.getPreviousForegroundUser().getIdentifier());
         } catch (RemoteException re) {
             Log.e(TAG, "Unable to remove self user");
         }
@@ -1099,7 +1099,7 @@
         }
         mMetricsFeatureProvider.action(getActivity(),
                 SettingsEnums.ACTION_USER_GUEST_EXIT_CONFIRMED);
-        switchToUserId(UserHandle.USER_SYSTEM);
+        switchToUserId(mUserManager.getPreviousForegroundUser().getIdentifier());
     }
 
     private int createGuest() {
@@ -1139,8 +1139,8 @@
             // Create a new guest in the foreground, and then immediately switch to it
             int newGuestUserId = createGuest();
             if (newGuestUserId == UserHandle.USER_NULL) {
-                Log.e(TAG, "Could not create new guest, switching back to system user");
-                switchToUserId(UserHandle.USER_SYSTEM);
+                Log.e(TAG, "Could not create new guest, switching back to previous user");
+                switchToUserId(mUserManager.getPreviousForegroundUser().getIdentifier());
                 mUserManager.removeUser(oldGuestUserId);
                 WindowManagerGlobal.getWindowManagerService().lockNow(/* options= */ null);
                 return;
diff --git a/tests/robotests/src/com/android/settings/notification/NotificationAccessConfirmationActivityTest.java b/tests/robotests/src/com/android/settings/notification/NotificationAccessConfirmationActivityTest.java
new file mode 100644
index 0000000..86631ff
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/NotificationAccessConfirmationActivityTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.notification;
+
+import static com.android.internal.notification.NotificationAccessConfirmationActivityContract.EXTRA_COMPONENT_NAME;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.robolectric.Shadows.shadowOf;
+
+import android.annotation.Nullable;
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.widget.TextView;
+
+import com.android.settings.R;
+
+import com.google.common.base.Strings;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class NotificationAccessConfirmationActivityTest {
+
+    @Test
+    public void start_showsDialog() {
+        ComponentName cn = new ComponentName("com.example", "com.example.SomeService");
+        installPackage(cn.getPackageName(), "X");
+
+        NotificationAccessConfirmationActivity activity = startActivityWithIntent(cn);
+
+        assertThat(activity.isFinishing()).isFalse();
+        assertThat(getDialogText(activity)).isEqualTo(
+                activity.getString(R.string.notification_listener_security_warning_summary, "X"));
+    }
+
+    @Test
+    public void start_withMissingPackage_finishes() {
+        ComponentName cn = new ComponentName("com.example", "com.example.SomeService");
+
+        NotificationAccessConfirmationActivity activity = startActivityWithIntent(cn);
+
+        assertThat(getDialogText(activity)).isNull();
+        assertThat(activity.isFinishing()).isTrue();
+    }
+
+    @Test
+    public void start_componentNameTooLong_finishes() {
+        ComponentName longCn = new ComponentName("com.example", Strings.repeat("Blah", 150));
+        installPackage(longCn.getPackageName(), "<Unused>");
+
+        NotificationAccessConfirmationActivity activity = startActivityWithIntent(longCn);
+
+        assertThat(getDialogText(activity)).isNull();
+        assertThat(activity.isFinishing()).isTrue();
+    }
+
+    private static NotificationAccessConfirmationActivity startActivityWithIntent(
+            ComponentName cn) {
+        return Robolectric.buildActivity(
+                        NotificationAccessConfirmationActivity.class,
+                        new Intent().putExtra(EXTRA_COMPONENT_NAME, cn))
+                .setup()
+                .get();
+    }
+
+    private static void installPackage(String packageName, String appName) {
+        PackageInfo pi = new PackageInfo();
+        pi.packageName = packageName;
+        pi.applicationInfo = new ApplicationInfo();
+        pi.applicationInfo.packageName = packageName;
+        pi.applicationInfo.name = appName;
+        shadowOf(RuntimeEnvironment.application.getPackageManager()).installPackage(pi);
+    }
+
+    @Nullable
+    private static String getDialogText(Activity activity) {
+        TextView tv = activity.getWindow().findViewById(android.R.id.message);
+        CharSequence text = (tv != null ? tv.getText() : null);
+        return text != null ? text.toString() : null;
+    }
+
+}
diff --git a/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java
index 2d54c38..f7e32a2 100644
--- a/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java
@@ -49,6 +49,8 @@
     @Mock
     private VolumeSeekBarPreference.Callback mCallback;
     @Mock
+    private VolumeSeekBarPreference.Listener mListener;
+    @Mock
     private AudioHelper mHelper;
 
     private VolumeSeekBarPreferenceControllerTestable mController;
@@ -59,7 +61,7 @@
         when(mScreen.findPreference(nullable(String.class))).thenReturn(mPreference);
         when(mPreference.getKey()).thenReturn("key");
         mController = new VolumeSeekBarPreferenceControllerTestable(mContext, mCallback, true,
-                mPreference.getKey());
+                mPreference.getKey(), mListener);
         mController.setAudioHelper(mHelper);
     }
 
@@ -70,18 +72,20 @@
         verify(mPreference).setCallback(mCallback);
         verify(mPreference).setStream(VolumeSeekBarPreferenceControllerTestable.AUDIO_STREAM);
         verify(mPreference).setMuteIcon(VolumeSeekBarPreferenceControllerTestable.MUTE_ICON);
+        verify(mPreference).setListener(mListener);
     }
 
     @Test
     public void displayPreference_notAvailable_shouldNotUpdatePreference() {
         mController = new VolumeSeekBarPreferenceControllerTestable(mContext, mCallback, false,
-                mPreference.getKey());
+                mPreference.getKey(), mListener);
 
         mController.displayPreference(mScreen);
 
         verify(mPreference, never()).setCallback(any(VolumeSeekBarPreference.Callback.class));
         verify(mPreference, never()).setStream(anyInt());
         verify(mPreference, never()).setMuteIcon(anyInt());
+        verify(mPreference, never()).setListener(mListener);
     }
 
     @Test
@@ -157,10 +161,12 @@
         private boolean mAvailable;
 
         VolumeSeekBarPreferenceControllerTestable(Context context,
-            VolumeSeekBarPreference.Callback callback, boolean available, String key) {
+                VolumeSeekBarPreference.Callback callback, boolean available, String key,
+                VolumeSeekBarPreference.Listener listener) {
             super(context, key);
             setCallback(callback);
             mAvailable = available;
+            mVolumePreferenceListener = listener;
         }
 
         @Override
diff --git a/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceTest.java b/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceTest.java
index d74f76a..59f0bcb 100644
--- a/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceTest.java
@@ -18,11 +18,14 @@
 
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.media.AudioManager;
+import android.preference.SeekBarVolumizer;
+import android.widget.SeekBar;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -34,18 +37,28 @@
 @RunWith(RobolectricTestRunner.class)
 public class VolumeSeekBarPreferenceTest {
 
+    private static final CharSequence CONTENT_DESCRIPTION = "TEST";
     @Mock
     private AudioManager mAudioManager;
     @Mock
     private VolumeSeekBarPreference mPreference;
     @Mock
     private Context mContext;
+    @Mock
+    private SeekBar mSeekBar;
+    @Mock
+    private SeekBarVolumizer mVolumizer;
+    private VolumeSeekBarPreference.Listener mListener;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         when(mContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager);
+        doCallRealMethod().when(mPreference).updateContentDescription(CONTENT_DESCRIPTION);
+        mPreference.mSeekBar = mSeekBar;
         mPreference.mAudioManager = mAudioManager;
+        mPreference.mVolumizer = mVolumizer;
+        mListener = () -> mPreference.updateContentDescription(CONTENT_DESCRIPTION);
     }
 
     @Test
@@ -65,4 +78,24 @@
         verify(mPreference).setMin(min);
         verify(mPreference).setProgress(progress);
     }
+
+    @Test
+    public void init_listenerIsCalled() {
+        doCallRealMethod().when(mPreference).setListener(mListener);
+        doCallRealMethod().when(mPreference).init();
+
+        mPreference.setListener(mListener);
+        mPreference.init();
+
+        verify(mPreference).updateContentDescription(CONTENT_DESCRIPTION);
+    }
+
+    @Test
+    public void init_listenerNotSet_noException() {
+        doCallRealMethod().when(mPreference).init();
+
+        mPreference.init();
+
+        verify(mPreference, never()).updateContentDescription(CONTENT_DESCRIPTION);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/password/SetupChooseLockPatternTest.java b/tests/robotests/src/com/android/settings/password/SetupChooseLockPatternTest.java
index c5e0813..2f46986 100644
--- a/tests/robotests/src/com/android/settings/password/SetupChooseLockPatternTest.java
+++ b/tests/robotests/src/com/android/settings/password/SetupChooseLockPatternTest.java
@@ -28,6 +28,7 @@
 import android.os.UserHandle;
 import android.util.TypedValue;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.Button;
 import android.widget.TextView;
 
@@ -114,6 +115,14 @@
         assertThat(button.getVisibility()).isEqualTo(View.VISIBLE);
     }
 
+    @Test
+    public void headerView_noBottomMargin() {
+        final View header = mActivity.findViewById(R.id.sud_layout_header);
+        final ViewGroup.MarginLayoutParams lp =
+                (ViewGroup.MarginLayoutParams) header.getLayoutParams();
+        assertThat(lp.bottomMargin).isEqualTo(0);
+    }
+
     private void verifyScreenLockOptionsShown() {
         final Button button = mActivity.findViewById(R.id.screen_lock_options);
         assertThat(button).isNotNull();
diff --git a/tests/spa_unit/src/com/android/settings/network/telephony/TelephonyStatusControlSessionTest.kt b/tests/spa_unit/src/com/android/settings/network/telephony/TelephonyStatusControlSessionTest.kt
new file mode 100644
index 0000000..7e6a91b
--- /dev/null
+++ b/tests/spa_unit/src/com/android/settings/network/telephony/TelephonyStatusControlSessionTest.kt
@@ -0,0 +1,81 @@
+/*
+ * 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.network.telephony
+
+import android.content.Context
+import androidx.lifecycle.testing.TestLifecycleOwner
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settings.core.BasePreferenceController
+import com.android.settingslib.spa.testutils.waitUntil
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidJUnit4::class)
+class TelephonyStatusControlSessionTest {
+    private val context: Context = ApplicationProvider.getApplicationContext()
+
+    @Test
+    fun init() = runTest {
+        val controller = TestController(context)
+
+        val session = TelephonyStatusControlSession(
+            controllers = listOf(controller),
+            lifecycle = TestLifecycleOwner().lifecycle,
+        )
+
+        waitUntil { controller.availabilityStatus == STATUS }
+        session.close()
+    }
+
+    @Test
+    fun close() = runTest {
+        val controller = TestController(context)
+
+        val session = TelephonyStatusControlSession(
+            controllers = listOf(controller),
+            lifecycle = TestLifecycleOwner().lifecycle,
+        )
+        session.close()
+
+        assertThat(controller.availabilityStatus).isNull()
+    }
+
+    private companion object {
+        const val KEY = "key"
+        const val STATUS = BasePreferenceController.AVAILABLE
+    }
+
+    private class TestController(context: Context) : BasePreferenceController(context, KEY),
+        TelephonyAvailabilityHandler {
+
+        var availabilityStatus: Int? = null
+        override fun getAvailabilityStatus(): Int = STATUS
+
+        override fun setAvailabilityStatus(status: Int) {
+            availabilityStatus = status
+        }
+
+        override fun unsetAvailabilityStatus() {
+            availabilityStatus = null
+        }
+    }
+}
diff --git a/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java
index 249b713..4601a1c 100644
--- a/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java
@@ -84,6 +84,36 @@
     }
 
     @Test
+    public void updateState_enabled() {
+        when(mAppOpsManager.noteOpNoThrow(anyInt(), anyInt(), anyString())).thenReturn(
+                AppOpsManager.MODE_ALLOWED);
+        when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
+        RestrictedSwitchPreference pref = new RestrictedSwitchPreference(
+                mContext);
+        pref.setAppOps(mAppOpsManager);
+
+        mController.updateState(pref);
+
+        assertThat(pref.isEnabled()).isTrue();
+    }
+
+    @Test
+    public void updateState_invalidCn_disabled() {
+        ComponentName longCn = new ComponentName("com.example.package",
+                com.google.common.base.Strings.repeat("Blah", 150));
+        mController.setCn(longCn);
+        when(mAppOpsManager.noteOpNoThrow(anyInt(), anyInt(), anyString())).thenReturn(
+                AppOpsManager.MODE_ALLOWED);
+        RestrictedSwitchPreference pref = new RestrictedSwitchPreference(
+                mContext);
+        pref.setAppOps(mAppOpsManager);
+
+        mController.updateState(pref);
+
+        assertThat(pref.isEnabled()).isFalse();
+    }
+
+    @Test
     public void updateState_checked() {
         when(mAppOpsManager.noteOpNoThrow(anyInt(), anyInt(), anyString())).thenReturn(
                 AppOpsManager.MODE_ALLOWED);
diff --git a/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java b/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java
index 63dca7e..f063042 100644
--- a/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java
+++ b/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java
@@ -16,26 +16,32 @@
 
 package com.android.settings.network;
 
+import static com.android.settings.network.SubscriptionUtil.KEY_UNIQUE_SUBSCRIPTION_DISPLAYNAME;
+import static com.android.settings.network.SubscriptionUtil.SUB_ID;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.content.SharedPreferences;
 import android.content.res.Resources;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 
-import com.android.settings.R;
-
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
+import com.android.settings.R;
+
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -445,6 +451,35 @@
     }
 
     @Test
+    public void getUniqueDisplayName_hasRecord_useRecordBeTheResult() {
+        final SubscriptionInfo info1 = mock(SubscriptionInfo.class);
+        final SubscriptionInfo info2 = mock(SubscriptionInfo.class);
+        when(info1.getSubscriptionId()).thenReturn(SUBID_1);
+        when(info2.getSubscriptionId()).thenReturn(SUBID_2);
+        when(info1.getDisplayName()).thenReturn(CARRIER_1);
+        when(info2.getDisplayName()).thenReturn(CARRIER_1);
+        when(mSubMgr.getAvailableSubscriptionInfoList()).thenReturn(
+                Arrays.asList(info1, info2));
+
+        SharedPreferences sp = mock(SharedPreferences.class);
+        when(mContext.getSharedPreferences(
+                KEY_UNIQUE_SUBSCRIPTION_DISPLAYNAME, Context.MODE_PRIVATE)).thenReturn(sp);
+        when(sp.getString(eq(SUB_ID + SUBID_1), anyString())).thenReturn(CARRIER_1 + "6789");
+        when(sp.getString(eq(SUB_ID + SUBID_2), anyString())).thenReturn(CARRIER_1 + "4321");
+
+
+        final CharSequence nameOfSub1 =
+                SubscriptionUtil.getUniqueSubscriptionDisplayName(info1, mContext);
+        final CharSequence nameOfSub2 =
+                SubscriptionUtil.getUniqueSubscriptionDisplayName(info2, mContext);
+
+        assertThat(nameOfSub1).isNotNull();
+        assertThat(nameOfSub2).isNotNull();
+        assertEquals(CARRIER_1 + "6789", nameOfSub1.toString());
+        assertEquals(CARRIER_1 + "4321", nameOfSub2.toString());
+    }
+
+    @Test
     public void isInactiveInsertedPSim_nullSubInfo_doesNotCrash() {
         assertThat(SubscriptionUtil.isInactiveInsertedPSim(null)).isFalse();
     }