diff --git a/src/com/android/settings/network/SubscriptionUtil.java b/src/com/android/settings/network/SubscriptionUtil.java index 9d953bf3139..0cd12fe6354 100644 --- a/src/com/android/settings/network/SubscriptionUtil.java +++ b/src/com/android/settings/network/SubscriptionUtil.java @@ -23,6 +23,7 @@ import static com.android.internal.util.CollectionUtils.emptyIfNull; 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 @@ import java.util.stream.Stream; 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 sAvailableResultsForTesting; private static List sActiveResultsForTesting; @@ -265,20 +270,21 @@ public class SubscriptionUtil { // Map of SubscriptionId to DisplayName final Supplier> 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 @@ public class SubscriptionUtil { // 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> 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 @@ public class SubscriptionUtil { 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 @@ public class SubscriptionUtil { 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/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java b/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java index 63dca7e88eb..f0630423953 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; @@ -444,6 +450,35 @@ public class SubscriptionUtilTest { assertTrue(TextUtils.isEmpty(name)); } + @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();