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

Commit 0e25db6d authored by Jack Yu's avatar Jack Yu
Browse files

Migrated PhoneSwitcher to use SubscriptionManagerService

Test: atest FrameworksTelephonyTests
Bug: 239607619
Merged-In: I42ad1ec0aaddb1111f9b820e8029af7c23a13cda
Change-Id: I42ad1ec0aaddb1111f9b820e8029af7c23a13cda
parent 0f1f740c
Loading
Loading
Loading
Loading
+155 −84
Original line number Diff line number Diff line
@@ -94,6 +94,8 @@ import com.android.internal.telephony.metrics.TelephonyMetrics;
import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent;
import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.DataSwitch;
import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.OnDemandDataSwitch;
import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.internal.telephony.util.NotificationChannelController;
import com.android.internal.util.IndentingPrintWriter;
import com.android.telephony.Rlog;
@@ -204,6 +206,7 @@ public class PhoneSwitcher extends Handler {
    private final @NonNull NetworkRequestList mNetworkRequestList = new NetworkRequestList();
    protected final RegistrantList mActivePhoneRegistrants;
    protected final SubscriptionController mSubscriptionController;
    private final SubscriptionManagerService mSubscriptionManagerService;
    protected final Context mContext;
    private final LocalLog mLocalLog;
    protected PhoneState[] mPhoneStates;
@@ -550,6 +553,7 @@ public class PhoneSwitcher extends Handler {
        mLocalLog = new LocalLog(MAX_LOCAL_LOG_LINES);

        mSubscriptionController = SubscriptionController.getInstance();
        mSubscriptionManagerService = SubscriptionManagerService.getInstance();
        mRadioConfig = RadioConfig.getInstance();
        mValidator = CellularNetworkValidator.getInstance();

@@ -675,9 +679,16 @@ public class PhoneSwitcher extends Handler {
            return false;
        }

        SubscriptionInfo info = mSubscriptionController
        SubscriptionInfo info;
        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
            info = mSubscriptionManagerService
                    .getActiveSubscriptionInfoForSimSlotIndex(slotIndex,
                            mContext.getOpPackageName(), mContext.getAttributionTag());
        } else {
            info = mSubscriptionController
                    .getActiveSubscriptionInfoForSimSlotIndex(slotIndex,
                            mContext.getOpPackageName(), null);
        }
        boolean uiccAppsEnabled = info != null && info.areUiccApplicationsEnabled();

        IccCard iccCard = PhoneFactory.getPhone(slotIndex).getIccCard();
@@ -927,7 +938,7 @@ public class PhoneSwitcher extends Handler {
     * Register for device config change on the primary data phone.
     */
    private void registerConfigChange() {
        Phone phone = findPhoneById(mSubscriptionController.getPhoneId(mPrimaryDataSubId));
        Phone phone = getPhoneBySubId(mPrimaryDataSubId);
        if (phone != null) {
            DataConfigManager dataConfig = phone.getDataNetworkController().getDataConfigManager();
            dataConfig.registerCallback(mDataConfigManagerCallback);
@@ -940,7 +951,7 @@ public class PhoneSwitcher extends Handler {
     * Update data config.
     */
    private void updateConfig() {
        Phone phone = findPhoneById(mSubscriptionController.getPhoneId(mPrimaryDataSubId));
        Phone phone = getPhoneBySubId(mPrimaryDataSubId);
        if (phone != null) {
            DataConfigManager dataConfig = phone.getDataNetworkController().getDataConfigManager();
            mAutoDataSwitchAvailabilityStabilityTimeThreshold =
@@ -1114,17 +1125,29 @@ public class PhoneSwitcher extends Handler {
        // auto data switch feature is disabled from server
        if (mAutoDataSwitchAvailabilityStabilityTimeThreshold < 0) return;
        // check is valid DSDS
        if (!mSubscriptionController.isActiveSubId(mPrimaryDataSubId)
        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
            if (!isActiveSubId(mPrimaryDataSubId) || mSubscriptionManagerService
                    .getActiveSubIdList(true).length <= 1) {
                return;
            }
        } else {
            if (!isActiveSubId(mPrimaryDataSubId)
                    || mSubscriptionController.getActiveSubIdList(true).length <= 1) {
                return;
            }
        int primaryPhoneId = mSubscriptionController.getPhoneId(mPrimaryDataSubId);
        }

        Phone primaryDataPhone = getPhoneBySubId(mPrimaryDataSubId);
        if (primaryDataPhone == null) {
            loge("evaluateIfAutoSwitchIsNeeded: cannot find primary data phone. subId="
                    + mPrimaryDataSubId);
            return;
        }

        int primaryPhoneId = primaryDataPhone.getPhoneId();
        log("evaluateIfAutoSwitchIsNeeded: primaryPhoneId: " + primaryPhoneId
                + " preferredPhoneId: " + mPreferredDataPhoneId);
        Phone primaryDataPhone = findPhoneById(primaryPhoneId);
        Phone secondaryDataPhone;
        if (primaryDataPhone != null) {

        if (mPreferredDataPhoneId == primaryPhoneId) {
            // on primary data sub
@@ -1181,8 +1204,6 @@ public class PhoneSwitcher extends Handler {
            // cancel any previous attempts of switching back to primary
            cancelPendingAutoDataSwitch();
        }

        }
    }

    /**
@@ -1234,14 +1255,14 @@ public class PhoneSwitcher extends Handler {
     * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}
     */
    private int getAutoSwitchTargetSubIdIfExists() {
        int primaryPhoneId = mSubscriptionController.getPhoneId(mPrimaryDataSubId);
        Phone primaryDataPhone = findPhoneById(primaryPhoneId);

        Phone primaryDataPhone = getPhoneBySubId(mPrimaryDataSubId);
        if (primaryDataPhone == null) {
            log("getAutoSwitchTargetSubId: no sim loaded");
            return INVALID_SUBSCRIPTION_ID;
        }

        int primaryPhoneId = primaryDataPhone.getPhoneId();

        if (!primaryDataPhone.isUserDataEnabled()) {
            log("getAutoSwitchTargetSubId: user disabled data");
            return INVALID_SUBSCRIPTION_ID;
@@ -1300,7 +1321,12 @@ public class PhoneSwitcher extends Handler {
        boolean diffDetected = mHalCommandToUse != HAL_COMMAND_PREFERRED_DATA && requestsChanged;

        // Check if user setting of default non-opportunistic data sub is changed.
        final int primaryDataSubId = mSubscriptionController.getDefaultDataSubId();
        int primaryDataSubId;
        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
            primaryDataSubId = mSubscriptionManagerService.getDefaultDataSubId();
        } else {
            primaryDataSubId = mSubscriptionController.getDefaultDataSubId();
        }
        if (primaryDataSubId != mPrimaryDataSubId) {
            sb.append(" mPrimaryDataSubId ").append(mPrimaryDataSubId).append("->")
                .append(primaryDataSubId);
@@ -1313,7 +1339,12 @@ public class PhoneSwitcher extends Handler {

        // Check if phoneId to subId mapping is changed.
        for (int i = 0; i < mActiveModemCount; i++) {
            int sub = mSubscriptionController.getSubId(i);
            int sub;
            if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
                sub = mSubscriptionManagerService.getSubId(i);
            } else {
                sub = mSubscriptionController.getSubId(i);
            }

            if (SubscriptionManager.isValidSubscriptionId(sub)) hasAnyActiveSubscription = true;

@@ -1574,8 +1605,18 @@ public class PhoneSwitcher extends Handler {
        return INVALID_SUBSCRIPTION_ID;
    }

    private boolean isActiveSubId(int subId) {
        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
            SubscriptionInfoInternal subInfo = mSubscriptionManagerService
                    .getSubscriptionInfoInternal(subId);
            return subInfo != null && subInfo.isActive();
        } else {
            return mSubscriptionController.isActiveSubId(subId);
        }
    }

    private int getSubIdForDefaultNetworkRequests() {
        if (mSubscriptionController.isActiveSubId(mAutoSelectedDataSubId)) {
        if (isActiveSubId(mAutoSelectedDataSubId)) {
            return mAutoSelectedDataSubId;
        } else {
            return mPrimaryDataSubId;
@@ -1587,8 +1628,7 @@ public class PhoneSwitcher extends Handler {
    protected void updatePreferredDataPhoneId() {
        Phone voicePhone = findPhoneById(mPhoneIdInVoiceCall);
        // check user enabled data on the default phone
        int defaultDataPhoneId = mSubscriptionController.getPhoneId(mPrimaryDataSubId);
        Phone defaultDataPhone = findPhoneById(defaultDataPhoneId);
        Phone defaultDataPhone = getPhoneBySubId(mPrimaryDataSubId);
        boolean isDataEnabled = false;
        if (voicePhone != null && defaultDataPhone != null
                && defaultDataPhone.isUserDataEnabled()) {
@@ -1627,8 +1667,11 @@ public class PhoneSwitcher extends Handler {
            mPreferredDataPhoneId = phoneId;
        }

        mPreferredDataSubId.set(
                mSubscriptionController.getSubId(mPreferredDataPhoneId));
        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
            mPreferredDataSubId.set(mSubscriptionManagerService.getSubId(mPreferredDataPhoneId));
        } else {
            mPreferredDataSubId.set(mSubscriptionController.getSubId(mPreferredDataPhoneId));
        }
    }

    protected void transitionToEmergencyPhone() {
@@ -1648,6 +1691,14 @@ public class PhoneSwitcher extends Handler {
        }
    }

    private Phone getPhoneBySubId(int subId) {
        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
            return findPhoneById(mSubscriptionManagerService.getPhoneId(subId));
        } else {
            return findPhoneById(mSubscriptionController.getPhoneId(subId));
        }
    }

    private Phone findPhoneById(final int phoneId) {
        if (!SubscriptionManager.isValidPhoneId(phoneId)) {
            return null;
@@ -1659,15 +1710,21 @@ public class PhoneSwitcher extends Handler {
            TelephonyNetworkRequest networkRequest, int phoneId) {
        if (!SubscriptionManager.isValidPhoneId(phoneId)) return false;

        int subId;
        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
            subId = mSubscriptionManagerService.getSubId(phoneId);
        } else {
            subId = mSubscriptionController.getSubId(phoneId);
        }

        // In any case, if phone state is inactive, don't apply the network request.
        if (!isPhoneActive(phoneId) || (
                mSubscriptionController.getSubId(phoneId) == INVALID_SUBSCRIPTION_ID
        if (!isPhoneActive(phoneId) || (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID
                && !isEmergencyNetworkRequest(networkRequest))) {
            return false;
        }

        NetworkRequest netRequest = networkRequest.getNativeNetworkRequest();
        int subId = getSubIdFromNetworkSpecifier(netRequest.getNetworkSpecifier());
        subId = getSubIdFromNetworkSpecifier(netRequest.getNetworkSpecifier());

        //if this phone is an emergency networkRequest
        //and subId is not specified that is invalid or default
@@ -1742,7 +1799,7 @@ public class PhoneSwitcher extends Handler {
                + " needValidation=" + needValidation);
        int subIdToValidate = (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)
                ? mPrimaryDataSubId : subId;
        if (!mSubscriptionController.isActiveSubId(subIdToValidate)) {
        if (!isActiveSubId(subIdToValidate)) {
            logl("Can't switch data to inactive subId " + subIdToValidate);
            if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
                // the default data sub is not selected yet, store the intent of switching to
@@ -1838,7 +1895,7 @@ public class PhoneSwitcher extends Handler {
    private void confirmSwitch(int subId, boolean confirm) {
        logl("confirmSwitch: subId " + subId + (confirm ? " confirmed." : " cancelled."));
        int resultForCallBack;
        if (!mSubscriptionController.isActiveSubId(subId)) {
        if (!isActiveSubId(subId)) {
            logl("confirmSwitch: subId " + subId + " is no longer active");
            resultForCallBack = SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION;
            mAutoSwitchRetryFailedCount = 0;
@@ -2075,9 +2132,15 @@ public class PhoneSwitcher extends Handler {
        }
        pw.println("mPreferredDataPhoneId=" + mPreferredDataPhoneId);
        pw.println("mPreferredDataSubId=" + mPreferredDataSubId.get());
        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
            pw.println("DefaultDataSubId=" + mSubscriptionManagerService.getDefaultDataSubId());
            pw.println("DefaultDataPhoneId=" + mSubscriptionManagerService.getPhoneId(
                    mSubscriptionManagerService.getDefaultDataSubId()));
        } else {
            pw.println("DefaultDataSubId=" + mSubscriptionController.getDefaultDataSubId());
            pw.println("DefaultDataPhoneId=" + mSubscriptionController.getPhoneId(
                    mSubscriptionController.getDefaultDataSubId()));
        }
        pw.println("mPrimaryDataSubId=" + mPrimaryDataSubId);
        pw.println("mAutoSelectedDataSubId=" + mAutoSelectedDataSubId);
        pw.println("mIsRegisteredForImsRadioTechChange=" + mIsRegisteredForImsRadioTechChange);
@@ -2163,8 +2226,12 @@ public class PhoneSwitcher extends Handler {
                    + switchReasonToString(mLastSwitchPreferredDataReason));
            return;
        }
        SubscriptionInfo subInfo = mSubscriptionController.getSubscriptionInfo(
                mAutoSelectedDataSubId);
        SubscriptionInfo subInfo;
        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
            subInfo = mSubscriptionManagerService.getSubscriptionInfo(mAutoSelectedDataSubId);
        } else {
            subInfo = mSubscriptionController.getSubscriptionInfo(mAutoSelectedDataSubId);
        }
        if (subInfo == null || subInfo.isOpportunistic()) {
            loge("displayAutoDataSwitchNotification:mAutoSelectedDataSubId="
                    + mAutoSelectedDataSubId + " unexpected subInfo " + subInfo);
@@ -2203,16 +2270,20 @@ public class PhoneSwitcher extends Handler {
    }

    private boolean isPhoneIdValidForRetry(int phoneId) {
        int phoneIdForRequest = INVALID_PHONE_INDEX;
        int ddsPhoneId = mSubscriptionController.getPhoneId(
        int ddsPhoneId;
        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
            ddsPhoneId = mSubscriptionManagerService.getPhoneId(
                    mSubscriptionManagerService.getDefaultDataSubId());
        } else {
            ddsPhoneId = mSubscriptionController.getPhoneId(
                    mSubscriptionController.getDefaultDataSubId());
        }
        if (ddsPhoneId != INVALID_PHONE_INDEX && ddsPhoneId == phoneId) {
            return true;
        } else {
            if (mNetworkRequestList.isEmpty()) return false;
            for (TelephonyNetworkRequest networkRequest : mNetworkRequestList) {
                phoneIdForRequest = phoneIdForRequest(networkRequest);
                if (phoneIdForRequest == phoneId) {
                if (phoneIdForRequest(networkRequest) == phoneId) {
                    return true;
                }
            }
+15 −9
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.metrics.NetworkRequestsStats;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.internal.util.IndentingPrintWriter;
import com.android.telephony.Rlog;

@@ -63,7 +64,6 @@ public class TelephonyNetworkFactory extends NetworkFactory {
    private static final int EVENT_NETWORK_RELEASE                  = 4;

    private final PhoneSwitcher mPhoneSwitcher;
    private final SubscriptionController mSubscriptionController;
    private final LocalLog mLocalLog = new LocalLog(REQUEST_LOG_SIZE);

    // Key: network request. Value: the transport of the network request applies to,
@@ -86,10 +86,9 @@ public class TelephonyNetworkFactory extends NetworkFactory {
        mPhone = phone;
        mInternalHandler = new InternalHandler(looper);

        mSubscriptionController = SubscriptionController.getInstance();
        mAccessNetworksManager = mPhone.getAccessNetworksManager();

        setCapabilityFilter(makeNetworkFilter(mSubscriptionController, mPhone.getPhoneId()));
        setCapabilityFilter(makeNetworkFilterByPhoneId(mPhone.getPhoneId()));
        setScoreFilter(TELEPHONY_NETWORK_SCORE);

        mPhoneSwitcher = PhoneSwitcher.getInstance();
@@ -113,10 +112,12 @@ public class TelephonyNetworkFactory extends NetworkFactory {
                }
            };

    private NetworkCapabilities makeNetworkFilter(SubscriptionController subscriptionController,
            int phoneId) {
        final int subscriptionId = subscriptionController.getSubId(phoneId);
        return makeNetworkFilter(subscriptionId);
    private NetworkCapabilities makeNetworkFilterByPhoneId(int phoneId) {
        if (mPhone.isSubscriptionManagerServiceEnabled()) {
            return makeNetworkFilter(SubscriptionManagerService.getInstance().getSubId(phoneId));
        } else {
            return makeNetworkFilter(SubscriptionController.getInstance().getSubId(phoneId));
        }
    }

    /**
@@ -238,8 +239,13 @@ public class TelephonyNetworkFactory extends NetworkFactory {
    // watch for phone->subId changes, reapply new filter and let
    // that flow through to apply/revoke of requests
    private void onSubIdChange() {
        final int newSubscriptionId = mSubscriptionController.getSubId(
        int newSubscriptionId;
        if (mPhone.isSubscriptionManagerServiceEnabled()) {
            newSubscriptionId = SubscriptionManagerService.getInstance().getSubId(
                    mPhone.getPhoneId());
        } else {
            newSubscriptionId = SubscriptionController.getInstance().getSubId(mPhone.getPhoneId());
        }
        if (mSubscriptionId != newSubscriptionId) {
            if (DBG) logl("onSubIdChange " + mSubscriptionId + "->" + newSubscriptionId);
            mSubscriptionId = newSubscriptionId;
+7 −1
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.metrics.TelephonyMetrics;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.internal.util.IndentingPrintWriter;
import com.android.phone.ecc.nano.ProtobufEccData;
import com.android.phone.ecc.nano.ProtobufEccData.EccInfo;
@@ -269,7 +270,12 @@ public class EmergencyNumberTracker extends Handler {
    @VisibleForTesting
    public boolean isSimAbsent() {
        for (Phone phone: PhoneFactory.getPhones()) {
            int slotId = SubscriptionController.getInstance().getSlotIndex(phone.getSubId());
            int slotId;
            if (phone.isSubscriptionManagerServiceEnabled()) {
                slotId = SubscriptionManagerService.getInstance().getSlotIndex(phone.getSubId());
            } else {
                slotId = SubscriptionController.getInstance().getSlotIndex(phone.getSubId());
            }
            // If slot id is invalid, it means that there is no sim card.
            if (slotId != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
                // If there is at least one sim active, sim is not absent; it returns false
+36 −5
Original line number Diff line number Diff line
@@ -766,15 +766,41 @@ public class SubscriptionManagerService extends ISub.Stub {
    /**
     * Get the active {@link SubscriptionInfo} associated with the logical SIM slot index.
     *
     * @param slotIndex the logical SIM slot index which the subscription is inserted
     * @param callingPackage The package making the call
     * @param callingFeatureId The feature in the package
     * @param slotIndex the logical SIM slot index which the subscription is inserted.
     * @param callingPackage The package making the call.
     * @param callingFeatureId The feature in the package.
     *
     * @return SubscriptionInfo, null for Remote-SIMs or non-active logical SIM slot index.
     * @return {@link SubscriptionInfo}, null for Remote-SIMs or non-active logical SIM slot index.
     */
    @Override
    @Nullable
    @RequiresPermission(anyOf = {
            Manifest.permission.READ_PHONE_STATE,
            Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
            "carrier privileges",
    })
    public SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex,
            @NonNull String callingPackage, @Nullable String callingFeatureId) {
        int subId = mSlotIndexToSubId.getOrDefault(slotIndex,
                SubscriptionManager.INVALID_SUBSCRIPTION_ID);

        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId,
                callingPackage, callingFeatureId,
                "getActiveSubscriptionInfoForSimSlotIndex")) {
            throw new SecurityException("Requires READ_PHONE_STATE permission.");
        }

        if (!SubscriptionManager.isValidSlotIndex(slotIndex)) {
            throw new IllegalArgumentException("Invalid slot index " + slotIndex);
        }

        SubscriptionInfoInternal subInfo = mSubscriptionDatabaseManager
                .getSubscriptionInfoInternal(subId);
        if (subInfo != null && subInfo.isActive()) {
            return conditionallyRemoveIdentifiers(subInfo.toSubscriptionInfo(), callingPackage,
                    callingFeatureId, "getActiveSubscriptionInfoForSimSlotIndex");
        }

        return null;
    }

@@ -939,7 +965,11 @@ public class SubscriptionManagerService extends ISub.Stub {
            // Check if the record exists or not.
            if (subInfo == null) {
                // Record does not exist.
                mSubscriptionDatabaseManager.insertSubscriptionInfo(
                if (mSlotIndexToSubId.containsKey(slotIndex)) {
                    loge("Already a subscription on slot " + slotIndex);
                    return -1;
                }
                int subId = mSubscriptionDatabaseManager.insertSubscriptionInfo(
                        new SubscriptionInfoInternal.Builder()
                                .setIccId(iccId)
                                .setSimSlotIndex(slotIndex)
@@ -947,6 +977,7 @@ public class SubscriptionManagerService extends ISub.Stub {
                                .setType(subscriptionType)
                                .build()
                );
                mSlotIndexToSubId.put(slotIndex, subId);
            } else {
                // Record already exists.
                loge("Subscription record already existed.");
+45 −1
Original line number Diff line number Diff line
@@ -174,7 +174,21 @@ public class SubscriptionManagerServiceTest extends TelephonyTest {
            Method method = SubscriptionDatabaseManager.class.getDeclaredMethod(
                    "insertSubscriptionInfo", cArgs);
            method.setAccessible(true);
            return (int) method.invoke(sdbm, subInfo);
            int subId = (int) method.invoke(sdbm, subInfo);

            Class<?> WatchedMapClass = Class.forName("com.android.internal.telephony.subscription"
                    + ".SubscriptionManagerService$WatchedMap");
            field = SubscriptionManagerService.class.getDeclaredField("mSlotIndexToSubId");
            field.setAccessible(true);
            Object map = field.get(mSubscriptionManagerServiceUT);
            cArgs = new Class[2];
            cArgs[0] = Object.class;
            cArgs[1] = Object.class;

            method = WatchedMapClass.getDeclaredMethod("put", cArgs);
            method.setAccessible(true);
            method.invoke(map, subInfo.getSimSlotIndex(), subId);
            return subId;
        } catch (Exception e) {
            fail("Failed to insert subscription. e=" + e);
        }
@@ -637,4 +651,34 @@ public class SubscriptionManagerServiceTest extends TelephonyTest {
        assertThat(subInfos).hasSize(1);
        assertThat(subInfos.get(0)).isEqualTo(FAKE_SUBSCRIPTION_INFO1.toSubscriptionInfo());
    }

    @Test
    public void testGetActiveSubscriptionInfoForSimSlotIndex() {
        // Grant MODIFY_PHONE_STATE permission for insertion.
        mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
        insertSubscription(FAKE_SUBSCRIPTION_INFO1);
        insertSubscription(FAKE_SUBSCRIPTION_INFO2);
        // Remove MODIFY_PHONE_STATE
        mContextFixture.removeCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);

        // Should fail without READ_PHONE_STATE
        assertThrows(SecurityException.class, () -> mSubscriptionManagerServiceUT
                .getActiveSubscriptionInfoForSimSlotIndex(0, CALLING_PACKAGE, CALLING_FEATURE));

        // Grant READ_PHONE_STATE permission for insertion.
        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
        SubscriptionInfo subInfo = mSubscriptionManagerServiceUT
                .getActiveSubscriptionInfoForSimSlotIndex(0, CALLING_PACKAGE,
                        CALLING_FEATURE);
        assertThat(subInfo).isNotNull();
        assertThat(subInfo.getSubscriptionId()).isEqualTo(1);
        assertThat(subInfo.getIccId()).isEmpty();
        assertThat(subInfo.getNumber()).isEmpty();

        // Grant carrier privilege for sub 1
        setCarrierPrivilegesForSubId(true, 1);
        subInfo = mSubscriptionManagerServiceUT.getActiveSubscriptionInfoForSimSlotIndex(
                0, CALLING_PACKAGE, CALLING_FEATURE);
        assertThat(subInfo).isEqualTo(FAKE_SUBSCRIPTION_INFO1.toSubscriptionInfo());
    }
}