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

Commit 9195feb3 authored by Chen Xu's avatar Chen Xu Committed by Gerrit Code Review
Browse files

Merge "Use portIndex when switching subscription"

parents 8d8f7ee8 e0cf8a77
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -493,13 +493,13 @@ public class EuiccConnector extends StateMachine implements ServiceConnection {

    /** Asynchronously switch to the given subscription. */
    @VisibleForTesting(visibility = PACKAGE)
    public void switchToSubscription(int cardId, @Nullable String iccid, boolean forceDeactivateSim,
            SwitchCommandCallback callback) {
    public void switchToSubscription(int cardId, int portIndex, @Nullable String iccid,
            boolean forceDeactivateSim, SwitchCommandCallback callback) {
        SwitchRequest request = new SwitchRequest();
        request.mIccid = iccid;
        request.mForceDeactivateSim = forceDeactivateSim;
        request.mCallback = callback;
        sendMessage(CMD_SWITCH_TO_SUBSCRIPTION, cardId, 0 /* arg2 */, request);
        sendMessage(CMD_SWITCH_TO_SUBSCRIPTION, cardId, portIndex, request);
    }

    /** Asynchronously update the nickname of the given subscription. */
@@ -838,7 +838,8 @@ public class EuiccConnector extends StateMachine implements ServiceConnection {
                        }
                        case CMD_SWITCH_TO_SUBSCRIPTION: {
                            SwitchRequest request = (SwitchRequest) message.obj;
                            mEuiccService.switchToSubscription(slotId, request.mIccid,
                            final int portIndex = message.arg2;
                            mEuiccService.switchToSubscription(slotId, portIndex, request.mIccid,
                                    request.mForceDeactivateSim,
                                    new ISwitchToSubscriptionCallback.Stub() {
                                        @Override
+87 −31
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.RemoteException;
import android.provider.Settings;
import android.service.euicc.DownloadSubscriptionResult;
import android.service.euicc.EuiccService;
@@ -180,6 +181,9 @@ public class EuiccController extends IEuiccController.Stub {
            PendingIntent callbackIntent =
                    resolutionIntent.getParcelableExtra(
                            EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT);
            int portIndex = resolutionIntent.getIntExtra(
                    EuiccService.EXTRA_RESOLUTION_PORT_INDEX, 0);
            resolutionExtras.putInt(EuiccService.EXTRA_RESOLUTION_PORT_INDEX, portIndex);
            op.continueOperation(cardId, resolutionExtras, callbackIntent);
        } finally {
            Binder.restoreCallingIdentity(token);
@@ -417,7 +421,7 @@ public class EuiccController extends IEuiccController.Stub {
                    break;
                case EuiccService.RESULT_MUST_DEACTIVATE_SIM:
                    resultCode = RESOLVABLE_ERROR;
                    addResolutionIntent(extrasIntent,
                    addResolutionIntentForDefaultPort(extrasIntent,
                            EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM,
                            mCallingPackage,
                            0 /* resolvableErrors */,
@@ -568,7 +572,8 @@ public class EuiccController extends IEuiccController.Stub {
                Log.i(TAG, "Caller can't manage subscription on target SIM. "
                        + "Ask user's consent first");
                Intent extrasIntent = new Intent();
                addResolutionIntent(extrasIntent, EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
                addResolutionIntentForDefaultPort(extrasIntent,
                        EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
                        callingPackage,
                        0 /* resolvableErrors */,
                        false /* confirmationCodeRetried */,
@@ -624,7 +629,8 @@ public class EuiccController extends IEuiccController.Stub {
                    // The caller can manage the target SIM. Ask the user's consent to deactivate
                    // the current SIM.
                    Intent extrasIntent = new Intent();
                    addResolutionIntent(extrasIntent, EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM,
                    addResolutionIntentForDefaultPort(extrasIntent,
                            EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM,
                            mCallingPackage,
                            0 /* resolvableErrors */,
                            false /* confirmationCodeRetried */,
@@ -706,7 +712,7 @@ public class EuiccController extends IEuiccController.Stub {
                                break;
                            case EuiccService.RESULT_MUST_DEACTIVATE_SIM:
                                resultCode = RESOLVABLE_ERROR;
                                addResolutionIntent(extrasIntent,
                                addResolutionIntentForDefaultPort(extrasIntent,
                                        EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM,
                                        callingPackage,
                                        0 /* resolvableErrors */,
@@ -727,7 +733,7 @@ public class EuiccController extends IEuiccController.Stub {
                                    retried = true;
                                }
                                if (result.getResolvableErrors() != 0) {
                                    addResolutionIntent(extrasIntent,
                                    addResolutionIntentForDefaultPort(extrasIntent,
                                            EuiccService.ACTION_RESOLVE_RESOLVABLE_ERRORS,
                                            callingPackage,
                                            result.getResolvableErrors(),
@@ -737,7 +743,7 @@ public class EuiccController extends IEuiccController.Stub {
                                                callingPackage, result.getResolvableErrors()),
                                            cardId);
                                }  else { // Deprecated case
                                    addResolutionIntent(extrasIntent,
                                    addResolutionIntentForDefaultPort(extrasIntent,
                                            EuiccService.ACTION_RESOLVE_CONFIRMATION_CODE,
                                            callingPackage,
                                            0 /* resolvableErrors */,
@@ -851,7 +857,7 @@ public class EuiccController extends IEuiccController.Stub {
                    break;
                case EuiccService.RESULT_MUST_DEACTIVATE_SIM:
                    resultCode = RESOLVABLE_ERROR;
                    addResolutionIntent(extrasIntent,
                    addResolutionIntentForDefaultPort(extrasIntent,
                            EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM,
                            mCallingPackage,
                            0 /* resolvableErrors */,
@@ -959,12 +965,21 @@ public class EuiccController extends IEuiccController.Stub {
    @Override
    public void switchToSubscription(int cardId, int subscriptionId, String callingPackage,
            PendingIntent callbackIntent) {
        switchToSubscription(cardId,
                subscriptionId, false /* forceDeactivateSim */, callingPackage, callbackIntent);
        // convert PendingIntent to callback if no callback provided
        IResultCallback callback = getCallbackFromPendingIntent(callbackIntent);
        switchToSubscription(cardId, 0,
                subscriptionId, false /* forceDeactivateSim */, callingPackage, callback);
    }

    void switchToSubscription(int cardId, int subscriptionId, boolean forceDeactivateSim,
            String callingPackage, PendingIntent callbackIntent) {
    @Override
    public void switchToSubscriptionWithPort(int cardId, int portIndex, int subscriptionId,
            String callingPackage, IResultCallback callback) {
        switchToSubscription(cardId, portIndex,
                subscriptionId, false /* forceDeactivateSim */, callingPackage, callback);
    }

    void switchToSubscription(int cardId, int portIndex, int subscriptionId,
            boolean forceDeactivateSim, String callingPackage, IResultCallback callback) {
        boolean callerCanWriteEmbeddedSubscriptions = callerCanWriteEmbeddedSubscriptions();
        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);

@@ -985,7 +1000,7 @@ public class EuiccController extends IEuiccController.Stub {
                    passConsent = true;
                } else {
                    Log.e(TAG, "Not permitted to switch to empty subscription");
                    sendResult(callbackIntent, ERROR, null /* extrasIntent */);
                    callback.onComplete(ERROR, null);
                    return;
                }
                iccid = null;
@@ -993,7 +1008,7 @@ public class EuiccController extends IEuiccController.Stub {
                SubscriptionInfo sub = getSubscriptionForSubscriptionId(subscriptionId);
                if (sub == null) {
                    Log.e(TAG, "Cannot switch to nonexistent sub: " + subscriptionId);
                    sendResult(callbackIntent, ERROR, null /* extrasIntent */);
                    callback.onComplete(ERROR, null);
                    return;
                }
                if (callerCanWriteEmbeddedSubscriptions) {
@@ -1001,7 +1016,7 @@ public class EuiccController extends IEuiccController.Stub {
                } else {
                    if (!mSubscriptionManager.canManageSubscription(sub, callingPackage)) {
                        Log.e(TAG, "Not permitted to switch to sub: " + subscriptionId);
                        sendResult(callbackIntent, ERROR, null /* extrasIntent */);
                        callback.onComplete(ERROR, null);
                        return;
                    }

@@ -1022,35 +1037,55 @@ public class EuiccController extends IEuiccController.Stub {
                        false /* confirmationCodeRetried */,
                        EuiccOperation.forSwitchNoPrivileges(
                                token, subscriptionId, callingPackage),
                        cardId);
                sendResult(callbackIntent, RESOLVABLE_ERROR, extrasIntent);
                        cardId, portIndex);
                callback.onComplete(RESOLVABLE_ERROR, extrasIntent);
                return;
            }

            switchToSubscriptionPrivileged(cardId, token, subscriptionId, iccid, forceDeactivateSim,
                    callingPackage, callbackIntent);
            switchToSubscriptionPrivileged(cardId, portIndex, token, subscriptionId, iccid,
                    forceDeactivateSim, callingPackage, callback);
        } catch (RemoteException e) {
            Log.e(TAG, "Cannot run callback.onComplete due to RemoteException e=" + e);
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    void switchToSubscriptionPrivileged(int cardId, final long callingToken, int subscriptionId,
            boolean forceDeactivateSim, final String callingPackage,
            final PendingIntent callbackIntent) {
    /**
     *
     * Create callback object which sends a given PendingIntent in the onComplete method.
     * This is used for compatibility between the old API which uses PendingIntents, and the new
     * API which uses Executors and Callbacks.
     * @param pi the PendingIntent to send
     * @return the callback
     */
    public IResultCallback getCallbackFromPendingIntent(PendingIntent pi) {
        return new IResultCallback.Stub() {
            @Override
            public void onComplete(int result, Intent resultIntent) {
                sendResult(pi, result, resultIntent);
            }
        };
    }

    void switchToSubscriptionPrivileged(int cardId, int portIndex, final long callingToken,
            int subscriptionId, boolean forceDeactivateSim, final String callingPackage,
            final IResultCallback callback) {
        String iccid = null;
        SubscriptionInfo sub = getSubscriptionForSubscriptionId(subscriptionId);
        if (sub != null) {
            iccid = sub.getIccId();
        }
        switchToSubscriptionPrivileged(cardId, callingToken, subscriptionId, iccid,
                forceDeactivateSim, callingPackage, callbackIntent);
        switchToSubscriptionPrivileged(cardId, portIndex, callingToken, subscriptionId, iccid,
                forceDeactivateSim, callingPackage, callback);
    }

    void switchToSubscriptionPrivileged(int cardId, final long callingToken, int subscriptionId,
            @Nullable String iccid, boolean forceDeactivateSim, final String callingPackage,
            final PendingIntent callbackIntent) {
    void switchToSubscriptionPrivileged(int cardId, int portIndex, final long callingToken,
            int subscriptionId, @Nullable String iccid, boolean forceDeactivateSim,
            final String callingPackage, final IResultCallback callback) {
        mConnector.switchToSubscription(
                cardId,
                portIndex,
                iccid,
                forceDeactivateSim,
                new EuiccConnector.SwitchCommandCallback() {
@@ -1071,20 +1106,31 @@ public class EuiccController extends IEuiccController.Stub {
                                        false /* confirmationCodeRetried */,
                                        EuiccOperation.forSwitchDeactivateSim(
                                                callingToken, subscriptionId, callingPackage),
                                        cardId);
                                        cardId, portIndex);
                                break;
                            default:
                                resultCode = ERROR;
                                addExtrasToResultIntent(extrasIntent, result);
                                break;
                        }

                        sendResult(callbackIntent, resultCode, extrasIntent);
                        try {
                            callback.onComplete(resultCode, extrasIntent);
                        } catch (RemoteException e) {
                            Log.e(TAG, "onSwitchComplete: "
                                    + "Cannot run callback.onComplete due to RemoteException e="
                                    + e);
                        }
                    }

                    @Override
                    public void onEuiccServiceUnavailable() {
                        sendResult(callbackIntent, ERROR, null /* extrasIntent */);
                        try {
                            callback.onComplete(ERROR, null);
                        } catch (RemoteException e) {
                            Log.e(TAG, "EuiccService is unavailable. "
                                    + "Cannot run callback.onComplete due to RemoteException e="
                                    + e);
                        }
                    }
                });
    }
@@ -1279,11 +1325,20 @@ public class EuiccController extends IEuiccController.Stub {
        }
    }

    /** Add a resolution intent to the given extras intent with the default port index 0 */
    public void addResolutionIntentForDefaultPort(Intent extrasIntent, String resolutionAction,
            String callingPackage, int resolvableErrors, boolean confirmationCodeRetried,
            EuiccOperation op, int cardId) {
        // use the default port 0 when not specified
        addResolutionIntent(extrasIntent, resolutionAction, callingPackage, resolvableErrors,
                confirmationCodeRetried, op, cardId, TelephonyManager.DEFAULT_PORT_INDEX);
    }

    /** Add a resolution intent to the given extras intent. */
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    public void addResolutionIntent(Intent extrasIntent, String resolutionAction,
            String callingPackage, int resolvableErrors, boolean confirmationCodeRetried,
            EuiccOperation op, int cardId) {
            EuiccOperation op, int cardId, int portIndex) {
        Intent intent = new Intent(EuiccManager.ACTION_RESOLVE_ERROR);
        intent.setPackage(RESOLUTION_ACTIVITY_PACKAGE_NAME);
        intent.setComponent(new ComponentName(
@@ -1293,6 +1348,7 @@ public class EuiccController extends IEuiccController.Stub {
        intent.putExtra(EuiccService.EXTRA_RESOLUTION_CALLING_PACKAGE, callingPackage);
        intent.putExtra(EuiccService.EXTRA_RESOLVABLE_ERRORS, resolvableErrors);
        intent.putExtra(EuiccService.EXTRA_RESOLUTION_CARD_ID, cardId);
        intent.putExtra(EuiccService.EXTRA_RESOLUTION_PORT_INDEX, portIndex);
        intent.putExtra(EuiccService.EXTRA_RESOLUTION_CONFIRMATION_CODE_RETRIED,
                confirmationCodeRetried);
        intent.putExtra(EXTRA_OPERATION, op);
+24 −10
Original line number Diff line number Diff line
@@ -302,16 +302,26 @@ public class EuiccOperation implements Parcelable {
                        resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT),
                        callbackIntent);
                break;
            case ACTION_SWITCH_DEACTIVATE_SIM:
                resolvedSwitchDeactivateSim(cardId,
            case ACTION_SWITCH_DEACTIVATE_SIM: {
                // get portIndex from original operation
                final int portIndex = resolutionExtras.getInt(
                        EuiccService.EXTRA_RESOLUTION_PORT_INDEX,
                        0);
                resolvedSwitchDeactivateSim(cardId, portIndex,
                        resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT),
                        callbackIntent);
                break;
            case ACTION_SWITCH_NO_PRIVILEGES:
                resolvedSwitchNoPrivileges(cardId,
            }
            case ACTION_SWITCH_NO_PRIVILEGES: {
                // get portIndex from original operation
                final int portIndex = resolutionExtras.getInt(
                        EuiccService.EXTRA_RESOLUTION_PORT_INDEX,
                        0);
                resolvedSwitchNoPrivileges(cardId, portIndex,
                        resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT),
                        callbackIntent);
                break;
            }
            default:
                Log.wtf(TAG, "Unknown action: " + mAction);
                break;
@@ -482,24 +492,26 @@ public class EuiccOperation implements Parcelable {
        }
    }

    private void resolvedSwitchDeactivateSim(int cardId, boolean consent,
    private void resolvedSwitchDeactivateSim(int cardId, int portIndex, boolean consent,
            PendingIntent callbackIntent) {
        if (consent) {
            // User has consented; perform the switch, but this time, tell the LPA to deactivate any
            // required active SIMs.
            EuiccController.get().switchToSubscription(
            EuiccController euiccController = EuiccController.get();
            euiccController.switchToSubscription(
                    cardId,
                    portIndex,
                    mSubscriptionId,
                    true /* forceDeactivateSim */,
                    mCallingPackage,
                    callbackIntent);
                    euiccController.getCallbackFromPendingIntent(callbackIntent));
        } else {
            // User has not consented; fail the operation.
            fail(callbackIntent);
        }
    }

    private void resolvedSwitchNoPrivileges(int cardId, boolean consent,
    private void resolvedSwitchNoPrivileges(int cardId, int portIndex, boolean consent,
            PendingIntent callbackIntent) {
        if (consent) {
            // User has consented; perform the switch with full privileges.
@@ -511,13 +523,15 @@ public class EuiccOperation implements Parcelable {
                // carrier. Also note that in practice, we'd need to deactivate the active SIM to
                // even reach this point, because we cannot fetch the metadata needed to check the
                // privileges without doing so.
                EuiccController.get().switchToSubscriptionPrivileged(
                EuiccController euiccController = EuiccController.get();
                euiccController.switchToSubscriptionPrivileged(
                        cardId,
                        portIndex,
                        token,
                        mSubscriptionId,
                        true /* forceDeactivateSim */,
                        mCallingPackage,
                        callbackIntent);
                        euiccController.getCallbackFromPendingIntent(callbackIntent));
            } finally {
                Binder.restoreCallingIdentity(token);
            }
+2 −1
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ public class EuiccConnectorTest extends TelephonyTest {
    @Mock private IEuiccService.Stub mEuiccService;

    private static final int CARD_ID = 15;
    private static final int PORT_INDEX = 0;

    @Before
    public void setUp() throws Exception {
@@ -137,7 +138,7 @@ public class EuiccConnectorTest extends TelephonyTest {
                false /* hasPriority */);
        mConnector = new EuiccConnector(mContext, mLooper.getLooper());
        final AtomicBoolean called = new AtomicBoolean(false);
        mConnector.switchToSubscription(CARD_ID, "12345", true, new
        mConnector.switchToSubscription(CARD_ID, PORT_INDEX, "12345", true, new
                EuiccConnector.SwitchCommandCallback() {
            @Override
            public void onSwitchComplete(int result) {
+21 −17
Original line number Diff line number Diff line
@@ -118,6 +118,7 @@ public class EuiccControllerTest extends TelephonyTest {
    private static final int SUBSCRIPTION_ID = 12345;
    private static final String ICC_ID = "54321";
    private static final int CARD_ID = 25;
    private static final int PORT_INDEX = 0;

    @Mock private EuiccConnector mMockConnector;
    private TestEuiccController mController;
@@ -148,7 +149,7 @@ public class EuiccControllerTest extends TelephonyTest {
        public void addResolutionIntent(
                Intent extrasIntent, String resolutionAction, String callingPackage,
                int resolvableErrors, boolean confirmationCodeRetried, EuiccOperation op,
                int cardId) {
                int cardId, int portIndex) {
            mResolutionAction = resolutionAction;
            mOp = op;
        }
@@ -765,8 +766,8 @@ public class EuiccControllerTest extends TelephonyTest {
                "whatever" /* callingPackage */);
        verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
                0 /* detailedCode */);
        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyString(), anyBoolean(),
                any());
        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyInt(), anyString(),
                anyBoolean(), any());
    }

    @Test
@@ -777,8 +778,8 @@ public class EuiccControllerTest extends TelephonyTest {
                0 /* result */, "whatever" /* callingPackage */);
        verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
                0 /* detailedCode */);
        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyString(), anyBoolean(),
                any());
        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyInt(), anyString(),
                anyBoolean(), any());
    }

    @Test
@@ -790,7 +791,8 @@ public class EuiccControllerTest extends TelephonyTest {
                "whatever" /* callingPackage */);
        verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
                0 /* detailedCode */);
        verify(mMockConnector).switchToSubscription(anyInt(), anyString(), anyBoolean(), any());
        verify(mMockConnector).switchToSubscription(anyInt(), anyInt(), anyString(), anyBoolean(),
                any());
    }

    @Test
@@ -832,8 +834,8 @@ public class EuiccControllerTest extends TelephonyTest {
                "whatever" /* callingPackage */);
        verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
                0 /* detailedCode */);
        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyString(), anyBoolean(),
                any());
        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyInt(), anyString(),
                anyBoolean(), any());
    }

    @Test
@@ -868,8 +870,8 @@ public class EuiccControllerTest extends TelephonyTest {
                SUBSCRIPTION_ID, ICC_ID, false /* complete */, 0 /* result */, PACKAGE_NAME);
        verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR,
                0 /* detailedCode */);
        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyString(), anyBoolean(),
                any());
        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyInt(), anyString(),
                anyBoolean(), any());
        verifyResolutionIntent(EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
                EuiccOperation.ACTION_SWITCH_NO_PRIVILEGES);
    }
@@ -885,8 +887,8 @@ public class EuiccControllerTest extends TelephonyTest {
                SUBSCRIPTION_ID, ICC_ID, false /* complete */, 0 /* result */, PACKAGE_NAME);
        verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR,
                0 /* detailedCode */);
        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyString(), anyBoolean(),
                any());
        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyInt(), anyString(),
                anyBoolean(), any());
        verifyResolutionIntent(EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
                EuiccOperation.ACTION_SWITCH_NO_PRIVILEGES);
    }
@@ -902,8 +904,8 @@ public class EuiccControllerTest extends TelephonyTest {
                SUBSCRIPTION_ID, ICC_ID, false /* complete */, 0 /* result */, PACKAGE_NAME);
        verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR,
                0 /* detailedCode */);
        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyString(), anyBoolean(),
                any());
        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyInt(), anyString(),
                anyBoolean(), any());
        verifyResolutionIntent(EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
                EuiccOperation.ACTION_SWITCH_NO_PRIVILEGES);
    }
@@ -1383,7 +1385,7 @@ public class EuiccControllerTest extends TelephonyTest {
            @Override
            public Void answer(InvocationOnMock invocation) throws Exception {
                EuiccConnector.SwitchCommandCallback cb = invocation
                        .getArgument(3 /* resultCallback */);
                        .getArgument(4 /* resultCallback */);
                if (complete) {
                    cb.onSwitchComplete(result);
                } else {
@@ -1391,8 +1393,10 @@ public class EuiccControllerTest extends TelephonyTest {
                }
                return null;
            }
        }).when(mMockConnector).switchToSubscription(anyInt(), eq(iccid), anyBoolean(), any());
        mController.switchToSubscription(CARD_ID, subscriptionId, callingPackage, resultCallback);
        }).when(mMockConnector).switchToSubscription(anyInt(), anyInt(), eq(iccid), anyBoolean(),
                any());
        mController.switchToSubscription(CARD_ID, subscriptionId, callingPackage,
                resultCallback);
    }

    private void callUpdateSubscriptionNickname(int subscriptionId, String iccid, String nickname,