From 2716dd18bb621fa334f3c000fa98ed4d3ad2e638 Mon Sep 17 00:00:00 2001 From: Bonian Chen Date: Wed, 18 Dec 2019 00:02:13 +0800 Subject: [PATCH] [Settings] Unable to display disabled SIM Disabled p(e)SIM should be allowed to display to the user. Bug: 144172733 Test: Manual Change-Id: I6825fde8ffb22bc95d6c50a60bdeb8027a2f93b8 --- .../settings/network/SubscriptionUtil.java | 172 +++++++++++++++++- .../telephony/MobileNetworkActivity.java | 5 +- 2 files changed, 165 insertions(+), 12 deletions(-) diff --git a/src/com/android/settings/network/SubscriptionUtil.java b/src/com/android/settings/network/SubscriptionUtil.java index 7e355c41e5a..6220d455e61 100644 --- a/src/com/android/settings/network/SubscriptionUtil.java +++ b/src/com/android/settings/network/SubscriptionUtil.java @@ -22,10 +22,12 @@ import static android.telephony.UiccSlotInfo.CARD_STATE_INFO_PRESENT; import static com.android.internal.util.CollectionUtils.emptyIfNull; import android.content.Context; +import android.os.ParcelUuid; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.UiccSlotInfo; +import android.text.TextUtils; import androidx.annotation.VisibleForTesting; @@ -67,6 +69,12 @@ public class SubscriptionUtil { slotInfo.getCardStateInfo() == CARD_STATE_INFO_PRESENT; } + /** + * Get all of the subscriptions which is available to display to the user. + * + * @param context {@code Context} + * @return list of {@code SubscriptionInfo} + */ public static List getAvailableSubscriptions(Context context) { if (sAvailableResultsForTesting != null) { return sAvailableResultsForTesting; @@ -74,12 +82,12 @@ public class SubscriptionUtil { final SubscriptionManager subMgr = context.getSystemService(SubscriptionManager.class); final TelephonyManager telMgr = context.getSystemService(TelephonyManager.class); - List subscriptions = + final List subscriptions = new ArrayList<>(emptyIfNull(subMgr.getSelectableSubscriptionInfoList())); // Look for inactive but present physical SIMs that are missing from the selectable list. final List missing = new ArrayList<>(); - UiccSlotInfo[] slotsInfo = telMgr.getUiccSlotsInfo(); + final UiccSlotInfo[] slotsInfo = telMgr.getUiccSlotsInfo(); for (int i = 0; slotsInfo != null && i < slotsInfo.length; i++) { final UiccSlotInfo slotInfo = slotsInfo[i]; if (isInactiveInsertedPSim(slotInfo)) { @@ -93,20 +101,164 @@ public class SubscriptionUtil { } } } - if (!missing.isEmpty()) { - for (SubscriptionInfo info : subMgr.getAllSubscriptionInfoList()) { - for (UiccSlotInfo slotInfo : missing) { - if (info.getSimSlotIndex() == slotInfo.getLogicalSlotIdx() && - info.getCardString().equals(slotInfo.getCardId())) { - subscriptions.add(info); - break; - } + if (missing.isEmpty()) { + return subscriptions; + } + for (SubscriptionInfo info : subMgr.getAllSubscriptionInfoList()) { + for (UiccSlotInfo slotInfo : missing) { + if (info.getSimSlotIndex() == slotInfo.getLogicalSlotIdx() + && info.getCardString().equals(slotInfo.getCardId())) { + subscriptions.add(info); + break; } } } return subscriptions; } + /** + * Get subscription which is available to be displayed to the user + * per subscription id. + * + * @param context {@code Context} + * @param subscriptionManager The ProxySubscriptionManager for accessing subcription + * information + * @param subId The id of subscription to be retrieved + * @return {@code SubscriptionInfo} based on the given subscription id. Null of subscription + * is invalid or not allowed to be displayed to the user. + */ + public static SubscriptionInfo getAvailableSubscription(Context context, + ProxySubscriptionManager subscriptionManager, int subId) { + final SubscriptionInfo subInfo = subscriptionManager.getAccessibleSubscriptionInfo(subId); + if (subInfo == null) { + return null; + } + + final ParcelUuid groupUuid = subInfo.getGroupUuid(); + + if (groupUuid != null) { + if (isPrimarySubscriptionWithinSameUuid(getUiccSlotsInfo(context), groupUuid, + subscriptionManager.getAccessibleSubscriptionsInfo(), subId)) { + return subInfo; + } + return null; + } + + if (subInfo.isEmbedded()) { + return subInfo; + } + + // Look for physical SIM which presented in slots no mater active or not. + final UiccSlotInfo[] slotsInfo = getUiccSlotsInfo(context); + if (slotsInfo == null) { + return null; + } + for (UiccSlotInfo slotInfo : slotsInfo) { + if ((!slotInfo.getIsEuicc()) + && (slotInfo.getCardStateInfo() == CARD_STATE_INFO_PRESENT) + && (slotInfo.getLogicalSlotIdx() == subInfo.getSimSlotIndex()) + && TextUtils.equals(slotInfo.getCardId(), subInfo.getCardString())) { + return subInfo; + } + } + return null; + } + + private static UiccSlotInfo [] getUiccSlotsInfo(Context context) { + final TelephonyManager telMgr = context.getSystemService(TelephonyManager.class); + return telMgr.getUiccSlotsInfo(); + } + + private static boolean isPrimarySubscriptionWithinSameUuid(UiccSlotInfo[] slotsInfo, + ParcelUuid groupUuid, List subscriptions, int subId) { + // only interested in subscriptions with this group UUID + final ArrayList physicalSubInfoList = + new ArrayList(); + final ArrayList nonOpportunisticSubInfoList = + new ArrayList(); + final ArrayList activeSlotSubInfoList = + new ArrayList(); + final ArrayList inactiveSlotSubInfoList = + new ArrayList(); + for (SubscriptionInfo subInfo : subscriptions) { + if (groupUuid.equals(subInfo.getGroupUuid())) { + if (!subInfo.isEmbedded()) { + physicalSubInfoList.add(subInfo); + } else { + if (!subInfo.isOpportunistic()) { + nonOpportunisticSubInfoList.add(subInfo); + } + if (subInfo.getSimSlotIndex() + != SubscriptionManager.INVALID_SIM_SLOT_INDEX) { + activeSlotSubInfoList.add(subInfo); + } else { + inactiveSlotSubInfoList.add(subInfo); + } + } + } + } + + // find any physical SIM which is currently inserted within logical slot + // and which is our target subscription + if ((slotsInfo != null) && (physicalSubInfoList.size() > 0)) { + final SubscriptionInfo subInfo = searchForSubscriptionId(physicalSubInfoList, subId); + if (subInfo == null) { + return false; + } + // verify if subscription is inserted within slot + for (UiccSlotInfo slotInfo : slotsInfo) { + if ((slotInfo != null) && (!slotInfo.getIsEuicc()) + && (slotInfo.getCardStateInfo() == CARD_STATE_INFO_PRESENT) + && (slotInfo.getLogicalSlotIdx() == subInfo.getSimSlotIndex()) + && TextUtils.equals(slotInfo.getCardId(), subInfo.getCardString())) { + return true; + } + } + return false; + } + + // When all of the eSIM profiles are opprtunistic and no physical SIM, + // first opportunistic subscriptions with same group UUID can be primary. + if (nonOpportunisticSubInfoList.size() <= 0) { + if (physicalSubInfoList.size() > 0) { + return false; + } + if (activeSlotSubInfoList.size() > 0) { + return (activeSlotSubInfoList.get(0).getSubscriptionId() == subId); + } + return (inactiveSlotSubInfoList.get(0).getSubscriptionId() == subId); + } + + // Allow non-opportunistic + active eSIM subscription as primary + int numberOfActiveNonOpportunisticSubs = 0; + boolean isTargetNonOpportunistic = false; + for (SubscriptionInfo subInfo : nonOpportunisticSubInfoList) { + final boolean isTargetSubInfo = (subInfo.getSubscriptionId() == subId); + if (subInfo.getSimSlotIndex() != SubscriptionManager.INVALID_SIM_SLOT_INDEX) { + if (isTargetSubInfo) { + return true; + } + numberOfActiveNonOpportunisticSubs++; + } else { + isTargetNonOpportunistic |= isTargetSubInfo; + } + } + if (numberOfActiveNonOpportunisticSubs > 0) { + return false; + } + return isTargetNonOpportunistic; + } + + private static SubscriptionInfo searchForSubscriptionId(List subInfoList, + int subscriptionId) { + for (SubscriptionInfo subInfo : subInfoList) { + if (subInfo.getSubscriptionId() == subscriptionId) { + return subInfo; + } + } + return null; + } + public static String getDisplayName(SubscriptionInfo info) { final CharSequence name = info.getDisplayName(); if (name != null) { diff --git a/src/com/android/settings/network/telephony/MobileNetworkActivity.java b/src/com/android/settings/network/telephony/MobileNetworkActivity.java index 9eb9e7127e3..9dd6ddde15e 100644 --- a/src/com/android/settings/network/telephony/MobileNetworkActivity.java +++ b/src/com/android/settings/network/telephony/MobileNetworkActivity.java @@ -35,6 +35,7 @@ import com.android.internal.util.CollectionUtils; import com.android.settings.R; import com.android.settings.core.SettingsBaseActivity; import com.android.settings.network.ProxySubscriptionManager; +import com.android.settings.network.SubscriptionUtil; import java.util.List; @@ -161,8 +162,8 @@ public class MobileNetworkActivity extends SettingsBaseActivity @VisibleForTesting SubscriptionInfo getSubscription() { if (mCurSubscriptionId != SUB_ID_NULL) { - final SubscriptionInfo subInfo = - mProxySubscriptionMgr.getActiveSubscriptionInfo(mCurSubscriptionId); + final SubscriptionInfo subInfo = SubscriptionUtil.getAvailableSubscription( + this, mProxySubscriptionMgr, mCurSubscriptionId); if (subInfo != null) { return subInfo; }