Merge "Return mapping of subscription id to unique display name."
This commit is contained in:
committed by
Android (Google) Code Review
commit
3c3ce5ea66
@@ -28,19 +28,25 @@ import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.telephony.UiccSlotInfo;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.network.telephony.DeleteEuiccSubscriptionDialogActivity;
|
||||
import com.android.settings.network.telephony.ToggleSubscriptionDialogActivity;
|
||||
import com.android.settingslib.DeviceInfoUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class SubscriptionUtil {
|
||||
private static final String TAG = "SubscriptionUtil";
|
||||
@@ -214,6 +220,92 @@ public class SubscriptionUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a mapping of active subscription ids to diaplay names. Each display name is
|
||||
* guaranteed to be unique in the following manner:
|
||||
* 1) If the original display name is not unique, the last four digits of the phone number
|
||||
* will be appended.
|
||||
* 2) If the phone number is not visible or the last four digits are shared with another
|
||||
* subscription, the subscription id will be appended to the original display name.
|
||||
* More details can be found at go/unique-sub-display-names.
|
||||
*
|
||||
* @return map of active subscription ids to diaplay names.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public static Map<Integer, CharSequence> getUniqueSubscriptionDisplayNames(Context context) {
|
||||
class DisplayInfo {
|
||||
public SubscriptionInfo subscriptionInfo;
|
||||
public CharSequence originalName;
|
||||
public CharSequence uniqueName;
|
||||
}
|
||||
|
||||
final SubscriptionManager subscriptionManager =
|
||||
context.getSystemService(SubscriptionManager.class);
|
||||
// Map of SubscriptionId to DisplayName
|
||||
final Supplier<Stream<DisplayInfo>> originalInfos =
|
||||
() -> getActiveSubscriptions(subscriptionManager)
|
||||
.stream()
|
||||
.map(i -> {
|
||||
DisplayInfo info = new DisplayInfo();
|
||||
info.subscriptionInfo = i;
|
||||
info.originalName = i.getDisplayName();
|
||||
return info;
|
||||
});
|
||||
|
||||
// TODO(goldmanj) consider using a map of DisplayName to SubscriptionInfos.
|
||||
// A Unique set of display names
|
||||
Set<CharSequence> uniqueNames = new HashSet<>();
|
||||
// Return the set of duplicate names
|
||||
final Set<CharSequence> duplicateOriginalNames = originalInfos.get()
|
||||
.filter(info -> !uniqueNames.add(info.originalName))
|
||||
.map(info -> info.originalName)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 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 -> {
|
||||
if (duplicateOriginalNames.contains(info.originalName)) {
|
||||
// This may return null, if the user cannot view the phone number itself.
|
||||
final String phoneNumber = DeviceInfoUtils.getBidiFormattedPhoneNumber(context,
|
||||
info.subscriptionInfo);
|
||||
String lastFourDigits = "";
|
||||
if (phoneNumber != null) {
|
||||
lastFourDigits = (phoneNumber.length() > 4)
|
||||
? phoneNumber.substring(phoneNumber.length() - 4) : phoneNumber;
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(lastFourDigits)) {
|
||||
info.uniqueName = info.originalName;
|
||||
} else {
|
||||
info.uniqueName = info.originalName + " " + lastFourDigits;
|
||||
}
|
||||
|
||||
} else {
|
||||
info.uniqueName = info.originalName;
|
||||
}
|
||||
return info;
|
||||
});
|
||||
|
||||
// Check uniqueness a second time.
|
||||
// We might not have had permission to view the phone numbers.
|
||||
// There might also be multiple phone numbers whose last 4 digits the same.
|
||||
uniqueNames.clear();
|
||||
final Set<CharSequence> duplicatePhoneNames = uniqueInfos.get()
|
||||
.filter(info -> !uniqueNames.add(info.uniqueName))
|
||||
.map(info -> info.uniqueName)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
return uniqueInfos.get().map(info -> {
|
||||
if (duplicatePhoneNames.contains(info.uniqueName)) {
|
||||
info.uniqueName = info.originalName + " "
|
||||
+ info.subscriptionInfo.getSubscriptionId();
|
||||
}
|
||||
return info;
|
||||
}).collect(Collectors.toMap(
|
||||
info -> info.subscriptionInfo.getSubscriptionId(),
|
||||
info -> info.uniqueName));
|
||||
}
|
||||
|
||||
public static String getDisplayName(SubscriptionInfo info) {
|
||||
final CharSequence name = info.getDisplayName();
|
||||
if (name != null) {
|
||||
|
@@ -18,6 +18,7 @@ package com.android.settings.network;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -38,9 +39,15 @@ import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class SubscriptionUtilTest {
|
||||
private static final int SUBID_1 = 1;
|
||||
private static final int SUBID_2 = 2;
|
||||
private static final int SUBID_3 = 3;
|
||||
private static final CharSequence CARRIER_1 = "carrier1";
|
||||
private static final CharSequence CARRIER_2 = "carrier2";
|
||||
|
||||
private Context mContext;
|
||||
@Mock
|
||||
@@ -125,6 +132,131 @@ public class SubscriptionUtilTest {
|
||||
assertThat(subs).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getUniqueDisplayNames_uniqueCarriers_originalUsed() {
|
||||
// Each subscription's default display name is unique.
|
||||
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_2);
|
||||
when(mSubMgr.getActiveSubscriptionInfoList()).thenReturn(
|
||||
Arrays.asList(info1, info2));
|
||||
|
||||
// Each subscription has a unique last 4 digits of the phone number.
|
||||
TelephonyManager sub1Telmgr = mock(TelephonyManager.class);
|
||||
TelephonyManager sub2Telmgr = mock(TelephonyManager.class);
|
||||
when(sub1Telmgr.getLine1Number()).thenReturn("1112223333");
|
||||
when(sub2Telmgr.getLine1Number()).thenReturn("2223334444");
|
||||
when(mTelMgr.createForSubscriptionId(SUBID_1)).thenReturn(sub1Telmgr);
|
||||
when(mTelMgr.createForSubscriptionId(SUBID_2)).thenReturn(sub2Telmgr);
|
||||
|
||||
final Map<Integer, CharSequence> idNames =
|
||||
SubscriptionUtil.getUniqueSubscriptionDisplayNames(mContext);
|
||||
|
||||
assertThat(idNames).isNotNull();
|
||||
assertThat(idNames).hasSize(2);
|
||||
assertEquals(CARRIER_1, idNames.get(SUBID_1));
|
||||
assertEquals(CARRIER_2, idNames.get(SUBID_2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getUniqueDisplayNames_identicalCarriers_fourDigitsUsed() {
|
||||
// Both subscriptoins have the same display name.
|
||||
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.getActiveSubscriptionInfoList()).thenReturn(
|
||||
Arrays.asList(info1, info2));
|
||||
|
||||
// Each subscription has a unique last 4 digits of the phone number.
|
||||
TelephonyManager sub1Telmgr = mock(TelephonyManager.class);
|
||||
TelephonyManager sub2Telmgr = mock(TelephonyManager.class);
|
||||
when(sub1Telmgr.getLine1Number()).thenReturn("1112223333");
|
||||
when(sub2Telmgr.getLine1Number()).thenReturn("2223334444");
|
||||
when(mTelMgr.createForSubscriptionId(SUBID_1)).thenReturn(sub1Telmgr);
|
||||
when(mTelMgr.createForSubscriptionId(SUBID_2)).thenReturn(sub2Telmgr);
|
||||
|
||||
final Map<Integer, CharSequence> idNames =
|
||||
SubscriptionUtil.getUniqueSubscriptionDisplayNames(mContext);
|
||||
|
||||
assertThat(idNames).isNotNull();
|
||||
assertThat(idNames).hasSize(2);
|
||||
assertEquals(CARRIER_1 + " 3333", idNames.get(SUBID_1));
|
||||
assertEquals(CARRIER_1 + " 4444", idNames.get(SUBID_2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getUniqueDisplayNames_phoneNumberBlocked_subscriptoinIdFallback() {
|
||||
// Both subscriptoins have the same display name.
|
||||
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.getActiveSubscriptionInfoList()).thenReturn(
|
||||
Arrays.asList(info1, info2));
|
||||
|
||||
// The subscriptions' phone numbers cannot be revealed to the user.
|
||||
TelephonyManager sub1Telmgr = mock(TelephonyManager.class);
|
||||
TelephonyManager sub2Telmgr = mock(TelephonyManager.class);
|
||||
when(sub1Telmgr.getLine1Number()).thenReturn("");
|
||||
when(sub2Telmgr.getLine1Number()).thenReturn("");
|
||||
when(mTelMgr.createForSubscriptionId(SUBID_1)).thenReturn(sub1Telmgr);
|
||||
when(mTelMgr.createForSubscriptionId(SUBID_2)).thenReturn(sub2Telmgr);
|
||||
|
||||
final Map<Integer, CharSequence> idNames =
|
||||
SubscriptionUtil.getUniqueSubscriptionDisplayNames(mContext);
|
||||
|
||||
assertThat(idNames).isNotNull();
|
||||
assertThat(idNames).hasSize(2);
|
||||
assertEquals(CARRIER_1 + " 1", idNames.get(SUBID_1));
|
||||
assertEquals(CARRIER_1 + " 2", idNames.get(SUBID_2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getUniqueDisplayNames_phoneNumberIdentical_subscriptoinIdFallback() {
|
||||
// TODO have three here from the same carrier
|
||||
// Both subscriptoins have the same display name.
|
||||
final SubscriptionInfo info1 = mock(SubscriptionInfo.class);
|
||||
final SubscriptionInfo info2 = mock(SubscriptionInfo.class);
|
||||
final SubscriptionInfo info3 = mock(SubscriptionInfo.class);
|
||||
when(info1.getSubscriptionId()).thenReturn(SUBID_1);
|
||||
when(info2.getSubscriptionId()).thenReturn(SUBID_2);
|
||||
when(info3.getSubscriptionId()).thenReturn(SUBID_3);
|
||||
when(info1.getDisplayName()).thenReturn(CARRIER_1);
|
||||
when(info2.getDisplayName()).thenReturn(CARRIER_1);
|
||||
when(info3.getDisplayName()).thenReturn(CARRIER_1);
|
||||
when(mSubMgr.getActiveSubscriptionInfoList()).thenReturn(
|
||||
Arrays.asList(info1, info2, info3));
|
||||
|
||||
// Subscription 1 has a unique phone number, but subscriptions 2 and 3 share the same
|
||||
// last four digits.
|
||||
TelephonyManager sub1Telmgr = mock(TelephonyManager.class);
|
||||
TelephonyManager sub2Telmgr = mock(TelephonyManager.class);
|
||||
TelephonyManager sub3Telmgr = mock(TelephonyManager.class);
|
||||
when(sub1Telmgr.getLine1Number()).thenReturn("1112223333");
|
||||
when(sub2Telmgr.getLine1Number()).thenReturn("2223334444");
|
||||
when(sub3Telmgr.getLine1Number()).thenReturn("5556664444");
|
||||
when(mTelMgr.createForSubscriptionId(SUBID_1)).thenReturn(sub1Telmgr);
|
||||
when(mTelMgr.createForSubscriptionId(SUBID_2)).thenReturn(sub2Telmgr);
|
||||
when(mTelMgr.createForSubscriptionId(SUBID_3)).thenReturn(sub3Telmgr);
|
||||
|
||||
final Map<Integer, CharSequence> idNames =
|
||||
SubscriptionUtil.getUniqueSubscriptionDisplayNames(mContext);
|
||||
|
||||
assertThat(idNames).isNotNull();
|
||||
assertThat(idNames).hasSize(3);
|
||||
assertEquals(CARRIER_1 + " 3333", idNames.get(SUBID_1));
|
||||
assertEquals(CARRIER_1 + " 2", idNames.get(SUBID_2));
|
||||
assertEquals(CARRIER_1 + " 3", idNames.get(SUBID_3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isInactiveInsertedPSim_nullSubInfo_doesNotCrash() {
|
||||
assertThat(SubscriptionUtil.isInactiveInsertedPSim(null)).isFalse();
|
||||
|
Reference in New Issue
Block a user