Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b212076d authored by Bonian Chen's avatar Bonian Chen Committed by Android (Google) Code Review
Browse files

Merge "[Settings] Unable to display disabled SIM"

parents 0a12e517 2716dd18
Loading
Loading
Loading
Loading
+162 −10
Original line number Diff line number Diff line
@@ -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<SubscriptionInfo> 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<SubscriptionInfo> subscriptions =
        final List<SubscriptionInfo> subscriptions =
                new ArrayList<>(emptyIfNull(subMgr.getSelectableSubscriptionInfoList()));

        // Look for inactive but present physical SIMs that are missing from the selectable list.
        final List<UiccSlotInfo> 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()) {
        if (missing.isEmpty()) {
            return subscriptions;
        }
        for (SubscriptionInfo info : subMgr.getAllSubscriptionInfoList()) {
            for (UiccSlotInfo slotInfo : missing) {
                    if (info.getSimSlotIndex() == slotInfo.getLogicalSlotIdx() &&
                    info.getCardString().equals(slotInfo.getCardId())) {
                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<SubscriptionInfo> subscriptions, int subId) {
        // only interested in subscriptions with this group UUID
        final ArrayList<SubscriptionInfo> physicalSubInfoList =
                new ArrayList<SubscriptionInfo>();
        final ArrayList<SubscriptionInfo> nonOpportunisticSubInfoList =
                new ArrayList<SubscriptionInfo>();
        final ArrayList<SubscriptionInfo> activeSlotSubInfoList =
                new ArrayList<SubscriptionInfo>();
        final ArrayList<SubscriptionInfo> inactiveSlotSubInfoList =
                new ArrayList<SubscriptionInfo>();
        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<SubscriptionInfo> 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) {
+3 −2
Original line number Diff line number Diff line
@@ -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;
            }