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

Commit 8ad00f7a authored by Jordan Liu's avatar Jordan Liu
Browse files

EuiccController/Connector support multiple eUICCs

This is done using cardId, which is then converted into the slotId. The
reason for the conversion is that the EuiccService API was already
defined using the slot index, and we can't change the existing API
without deprectating all the functions.

Bug: 80097562
Test: manual
Change-Id: I6087f26b90960fd26bc989fb71b534d3d92f48e0
Merged-In: I6087f26b90960fd26bc989fb71b534d3d92f48e0
parent 1f2e8825
Loading
Loading
Loading
Loading
+49 −28
Original line number Diff line number Diff line
@@ -55,6 +55,8 @@ import android.service.euicc.IRetainSubscriptionsForFactoryResetCallback;
import android.service.euicc.ISwitchToSubscriptionCallback;
import android.service.euicc.IUpdateSubscriptionNicknameCallback;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.UiccCardInfo;
import android.telephony.euicc.DownloadableSubscription;
import android.telephony.euicc.EuiccInfo;
import android.telephony.euicc.EuiccManager;
@@ -219,7 +221,7 @@ public class EuiccConnector extends StateMachine implements ServiceConnection {
    @VisibleForTesting(visibility = PACKAGE)
    public interface GetMetadataCommandCallback extends BaseEuiccCommandCallback {
        /** Called when the metadata lookup has completed (though it may have failed). */
        void onGetMetadataComplete(GetDownloadableSubscriptionMetadataResult result);
        void onGetMetadataComplete(int cardId, GetDownloadableSubscriptionMetadataResult result);
    }

    static class DownloadRequest {
@@ -394,37 +396,38 @@ public class EuiccConnector extends StateMachine implements ServiceConnection {

    /** Asynchronously fetch the EID. */
    @VisibleForTesting(visibility = PACKAGE)
    public void getEid(GetEidCommandCallback callback) {
        sendMessage(CMD_GET_EID, callback);
    public void getEid(int cardId, GetEidCommandCallback callback) {
        sendMessage(CMD_GET_EID, cardId, 0 /* arg2 */, callback);
    }

    /** Asynchronously get OTA status. */
    @VisibleForTesting(visibility = PACKAGE)
    public void getOtaStatus(GetOtaStatusCommandCallback callback) {
        sendMessage(CMD_GET_OTA_STATUS, callback);
    public void getOtaStatus(int cardId, GetOtaStatusCommandCallback callback) {
        sendMessage(CMD_GET_OTA_STATUS, cardId, 0 /* arg2 */, callback);
    }

    /** Asynchronously perform OTA update. */
    @VisibleForTesting(visibility = PACKAGE)
    public void startOtaIfNecessary(OtaStatusChangedCallback callback) {
        sendMessage(CMD_START_OTA_IF_NECESSARY, callback);
    public void startOtaIfNecessary(int cardId, OtaStatusChangedCallback callback) {
        sendMessage(CMD_START_OTA_IF_NECESSARY, cardId, 0 /* arg2 */, callback);
    }

    /** Asynchronously fetch metadata for the given downloadable subscription. */
    @VisibleForTesting(visibility = PACKAGE)
    public void getDownloadableSubscriptionMetadata(DownloadableSubscription subscription,
    public void getDownloadableSubscriptionMetadata(int cardId,
            DownloadableSubscription subscription,
            boolean forceDeactivateSim, GetMetadataCommandCallback callback) {
        GetMetadataRequest request =
                new GetMetadataRequest();
        request.mSubscription = subscription;
        request.mForceDeactivateSim = forceDeactivateSim;
        request.mCallback = callback;
        sendMessage(CMD_GET_DOWNLOADABLE_SUBSCRIPTION_METADATA, request);
        sendMessage(CMD_GET_DOWNLOADABLE_SUBSCRIPTION_METADATA, cardId, 0 /* arg2 */, request);
    }

    /** Asynchronously download the given subscription. */
    @VisibleForTesting(visibility = PACKAGE)
    public void downloadSubscription(DownloadableSubscription subscription,
    public void downloadSubscription(int cardId, DownloadableSubscription subscription,
            boolean switchAfterDownload, boolean forceDeactivateSim,
            Bundle resolvedBundle, DownloadCommandCallback callback) {
        DownloadRequest request = new DownloadRequest();
@@ -433,7 +436,7 @@ public class EuiccConnector extends StateMachine implements ServiceConnection {
        request.mForceDeactivateSim = forceDeactivateSim;
        request.mResolvedBundle = resolvedBundle;
        request.mCallback = callback;
        sendMessage(CMD_DOWNLOAD_SUBSCRIPTION, request);
        sendMessage(CMD_DOWNLOAD_SUBSCRIPTION, cardId, 0 /* arg2 */, request);
    }

    void getEuiccProfileInfoList(int cardId, GetEuiccProfileInfoListCommandCallback callback) {
@@ -442,61 +445,61 @@ public class EuiccConnector extends StateMachine implements ServiceConnection {

    /** Asynchronously fetch the default downloadable subscription list. */
    @VisibleForTesting(visibility = PACKAGE)
    public void getDefaultDownloadableSubscriptionList(
    public void getDefaultDownloadableSubscriptionList(int cardId,
            boolean forceDeactivateSim, GetDefaultListCommandCallback callback) {
        GetDefaultListRequest request = new GetDefaultListRequest();
        request.mForceDeactivateSim = forceDeactivateSim;
        request.mCallback = callback;
        sendMessage(CMD_GET_DEFAULT_DOWNLOADABLE_SUBSCRIPTION_LIST, request);
        sendMessage(CMD_GET_DEFAULT_DOWNLOADABLE_SUBSCRIPTION_LIST, cardId, 0 /* arg2 */, request);
    }

    /** Asynchronously fetch the {@link EuiccInfo}. */
    @VisibleForTesting(visibility = PACKAGE)
    public void getEuiccInfo(GetEuiccInfoCommandCallback callback) {
        sendMessage(CMD_GET_EUICC_INFO, callback);
    public void getEuiccInfo(int cardId, GetEuiccInfoCommandCallback callback) {
        sendMessage(CMD_GET_EUICC_INFO, cardId, 0 /* arg2 */, callback);
    }

    /** Asynchronously delete the given subscription. */
    @VisibleForTesting(visibility = PACKAGE)
    public void deleteSubscription(String iccid, DeleteCommandCallback callback) {
    public void deleteSubscription(int cardId, String iccid, DeleteCommandCallback callback) {
        DeleteRequest request = new DeleteRequest();
        request.mIccid = iccid;
        request.mCallback = callback;
        sendMessage(CMD_DELETE_SUBSCRIPTION, request);
        sendMessage(CMD_DELETE_SUBSCRIPTION, cardId, 0 /* arg2 */, request);
    }

    /** Asynchronously switch to the given subscription. */
    @VisibleForTesting(visibility = PACKAGE)
    public void switchToSubscription(@Nullable String iccid, boolean forceDeactivateSim,
    public void switchToSubscription(int cardId, @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, request);
        sendMessage(CMD_SWITCH_TO_SUBSCRIPTION, cardId, 0 /* arg2 */, request);
    }

    /** Asynchronously update the nickname of the given subscription. */
    @VisibleForTesting(visibility = PACKAGE)
    public void updateSubscriptionNickname(
    public void updateSubscriptionNickname(int cardId,
            String iccid, String nickname, UpdateNicknameCommandCallback callback) {
        UpdateNicknameRequest request = new UpdateNicknameRequest();
        request.mIccid = iccid;
        request.mNickname = nickname;
        request.mCallback = callback;
        sendMessage(CMD_UPDATE_SUBSCRIPTION_NICKNAME, request);
        sendMessage(CMD_UPDATE_SUBSCRIPTION_NICKNAME, cardId, 0 /* arg2 */, request);
    }

    /** Asynchronously erase all profiles on the eUICC. */
    @VisibleForTesting(visibility = PACKAGE)
    public void eraseSubscriptions(EraseCommandCallback callback) {
        sendMessage(CMD_ERASE_SUBSCRIPTIONS, callback);
    public void eraseSubscriptions(int cardId, EraseCommandCallback callback) {
        sendMessage(CMD_ERASE_SUBSCRIPTIONS, cardId, 0 /* arg2 */, callback);
    }

    /** Asynchronously ensure that all profiles will be retained on the next factory reset. */
    @VisibleForTesting(visibility = PACKAGE)
    public void retainSubscriptions(RetainSubscriptionsCommandCallback callback) {
        sendMessage(CMD_RETAIN_SUBSCRIPTIONS, callback);
    public void retainSubscriptions(int cardId, RetainSubscriptionsCommandCallback callback) {
        sendMessage(CMD_RETAIN_SUBSCRIPTIONS, cardId, 0 /* arg2 */, callback);
    }

    /**
@@ -671,8 +674,7 @@ public class EuiccConnector extends StateMachine implements ServiceConnection {
            } else if (isEuiccCommand(message.what)) {
                final BaseEuiccCommandCallback callback = getCallback(message);
                onCommandStart(callback);
                // TODO(b/36260308): Plumb through an actual SIM slot ID.
                int slotId = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
                final int slotId = getSlotIdFromCardId(message.arg1);
                try {
                    switch (message.what) {
                        case CMD_GET_EID: {
@@ -700,7 +702,7 @@ public class EuiccConnector extends StateMachine implements ServiceConnection {
                                                GetDownloadableSubscriptionMetadataResult result) {
                                            sendMessage(CMD_COMMAND_COMPLETE, (Runnable) () -> {
                                                ((GetMetadataCommandCallback) callback)
                                                        .onGetMetadataComplete(result);
                                                        .onGetMetadataComplete(slotId, result);
                                                onCommandEnd(callback);
                                            });
                                        }
@@ -946,6 +948,25 @@ public class EuiccConnector extends StateMachine implements ServiceConnection {
        }
    }

    /**
     * Gets the slot ID from the card ID.
     */
    private int getSlotIdFromCardId(int cardId) {
        TelephonyManager tm = (TelephonyManager)
                mContext.getSystemService(Context.TELEPHONY_SERVICE);
        UiccCardInfo[] infos = tm.getUiccCardsInfo();
        if (infos == null) {
            return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
        }
        int slotId = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
        for (UiccCardInfo info : infos) {
            if (info.getCardId() == cardId) {
                slotId = info.getSlotIndex();
            }
        }
        return slotId;
    }

    /** Call this at the beginning of the execution of any command. */
    private void onCommandStart(BaseEuiccCommandCallback callback) {
        mActiveCommandCallbacks.add(callback);
+74 −56

File changed.

Preview size limit exceeded, changes collapsed.

+35 −22
Original line number Diff line number Diff line
@@ -245,7 +245,8 @@ public class EuiccOperation implements Parcelable {
     *     {@link EuiccManager#continueOperation}.
     * @param callbackIntent The callback intent to trigger after the operation completes.
     */
    public void continueOperation(Bundle resolutionExtras, PendingIntent callbackIntent) {
    public void continueOperation(int cardId, Bundle resolutionExtras,
            PendingIntent callbackIntent) {
        // Restore the identity of the caller. We should err on the side of caution and redo any
        // permission checks before continuing with the operation in case the caller state has
        // changed. Resolution flows can re-clear the identity if required.
@@ -253,40 +254,40 @@ public class EuiccOperation implements Parcelable {

        switch (mAction) {
            case ACTION_GET_METADATA_DEACTIVATE_SIM:
                resolvedGetMetadataDeactivateSim(
                resolvedGetMetadataDeactivateSim(cardId,
                        resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT),
                        callbackIntent);
                break;
            case ACTION_DOWNLOAD_DEACTIVATE_SIM:
                resolvedDownloadDeactivateSim(
                resolvedDownloadDeactivateSim(cardId,
                        resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT),
                        callbackIntent);
                break;
            case ACTION_DOWNLOAD_NO_PRIVILEGES:
                resolvedDownloadNoPrivileges(
                resolvedDownloadNoPrivileges(cardId,
                        resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT),
                        callbackIntent);
                break;
            case ACTION_DOWNLOAD_CONFIRMATION_CODE: // Deprecated case
                resolvedDownloadConfirmationCode(
                resolvedDownloadConfirmationCode(cardId,
                        resolutionExtras.getString(EuiccService.EXTRA_RESOLUTION_CONFIRMATION_CODE),
                        callbackIntent);
                break;
            case ACTION_DOWNLOAD_RESOLVABLE_ERRORS:
                resolvedDownloadResolvableErrors(resolutionExtras, callbackIntent);
                resolvedDownloadResolvableErrors(cardId, resolutionExtras, callbackIntent);
                break;
            case ACTION_GET_DEFAULT_LIST_DEACTIVATE_SIM:
                resolvedGetDefaultListDeactivateSim(
                resolvedGetDefaultListDeactivateSim(cardId,
                        resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT),
                        callbackIntent);
                break;
            case ACTION_SWITCH_DEACTIVATE_SIM:
                resolvedSwitchDeactivateSim(
                resolvedSwitchDeactivateSim(cardId,
                        resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT),
                        callbackIntent);
                break;
            case ACTION_SWITCH_NO_PRIVILEGES:
                resolvedSwitchNoPrivileges(
                resolvedSwitchNoPrivileges(cardId,
                        resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT),
                        callbackIntent);
                break;
@@ -296,12 +297,13 @@ public class EuiccOperation implements Parcelable {
        }
    }

    private void resolvedGetMetadataDeactivateSim(
            boolean consent, PendingIntent callbackIntent) {
    private void resolvedGetMetadataDeactivateSim(int cardId, boolean consent,
            PendingIntent callbackIntent) {
        if (consent) {
            // User has consented; perform the lookup, but this time, tell the LPA to deactivate any
            // required active SIMs.
            EuiccController.get().getDownloadableSubscriptionMetadata(
                    cardId,
                    mDownloadableSubscription,
                    true /* forceDeactivateSim */,
                    mCallingPackage,
@@ -312,12 +314,13 @@ public class EuiccOperation implements Parcelable {
        }
    }

    private void resolvedDownloadDeactivateSim(
            boolean consent, PendingIntent callbackIntent) {
    private void resolvedDownloadDeactivateSim(int cardId, boolean consent,
            PendingIntent callbackIntent) {
        if (consent) {
            // User has consented; perform the download, but this time, tell the LPA to deactivate
            // any required active SIMs.
            EuiccController.get().downloadSubscription(
                    cardId,
                    mDownloadableSubscription,
                    mSwitchAfterDownload,
                    mCallingPackage,
@@ -330,7 +333,8 @@ public class EuiccOperation implements Parcelable {
        }
    }

    private void resolvedDownloadNoPrivileges(boolean consent, PendingIntent callbackIntent) {
    private void resolvedDownloadNoPrivileges(int cardId, boolean consent,
            PendingIntent callbackIntent) {
        if (consent) {
            // User has consented; perform the download with full privileges.
            long token = Binder.clearCallingIdentity();
@@ -340,6 +344,7 @@ public class EuiccOperation implements Parcelable {
                // the privilege prompt makes it clear that we're switching from the current
                // carrier.
                EuiccController.get().downloadSubscriptionPrivileged(
                        cardId,
                        token,
                        mDownloadableSubscription,
                        mSwitchAfterDownload,
@@ -361,13 +366,14 @@ public class EuiccOperation implements Parcelable {
     * {@link #resolvedDownloadResolvableErrors(Bundle, PendingIntent)} from Q.
     */
    @Deprecated
    private void resolvedDownloadConfirmationCode(String confirmationCode,
    private void resolvedDownloadConfirmationCode(int cardId, String confirmationCode,
            PendingIntent callbackIntent) {
        if (TextUtils.isEmpty(confirmationCode)) {
            fail(callbackIntent);
        } else {
            mDownloadableSubscription.setConfirmationCode(confirmationCode);
            EuiccController.get().downloadSubscription(
                    cardId,
                    mDownloadableSubscription,
                    mSwitchAfterDownload,
                    mCallingPackage,
@@ -377,7 +383,7 @@ public class EuiccOperation implements Parcelable {
        }
    }

    private void resolvedDownloadResolvableErrors(Bundle resolvedBundle,
    private void resolvedDownloadResolvableErrors(int cardId, Bundle resolvedBundle,
            PendingIntent callbackIntent) {
        boolean pass = true;
        String confirmationCode = null;
@@ -401,6 +407,7 @@ public class EuiccOperation implements Parcelable {
        } else {
            mDownloadableSubscription.setConfirmationCode(confirmationCode);
            EuiccController.get().downloadSubscription(
                    cardId,
                    mDownloadableSubscription,
                    mSwitchAfterDownload,
                    mCallingPackage,
@@ -410,25 +417,29 @@ public class EuiccOperation implements Parcelable {
        }
    }

    private void resolvedGetDefaultListDeactivateSim(
            boolean consent, PendingIntent callbackIntent) {
    private void resolvedGetDefaultListDeactivateSim(int cardId, boolean consent,
            PendingIntent callbackIntent) {
        if (consent) {
            // User has consented; perform the lookup, but this time, tell the LPA to deactivate any
            // required active SIMs.
            EuiccController.get().getDefaultDownloadableSubscriptionList(
                    true /* forceDeactivateSim */, mCallingPackage, callbackIntent);
                    cardId,
                    true /* forceDeactivateSim */,
                    mCallingPackage,
                    callbackIntent);
        } else {
            // User has not consented; fail the operation.
            fail(callbackIntent);
        }
    }

    private void resolvedSwitchDeactivateSim(
            boolean consent, PendingIntent callbackIntent) {
    private void resolvedSwitchDeactivateSim(int cardId, 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(
                    cardId,
                    mSubscriptionId,
                    true /* forceDeactivateSim */,
                    mCallingPackage,
@@ -439,7 +450,8 @@ public class EuiccOperation implements Parcelable {
        }
    }

    private void resolvedSwitchNoPrivileges(boolean consent, PendingIntent callbackIntent) {
    private void resolvedSwitchNoPrivileges(int cardId, boolean consent,
            PendingIntent callbackIntent) {
        if (consent) {
            // User has consented; perform the switch with full privileges.
            long token = Binder.clearCallingIdentity();
@@ -451,6 +463,7 @@ public class EuiccOperation implements Parcelable {
                // even reach this point, because we cannot fetch the metadata needed to check the
                // privileges without doing so.
                EuiccController.get().switchToSubscriptionPrivileged(
                        cardId,
                        token,
                        mSubscriptionId,
                        true /* forceDeactivateSim */,
+2 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.when;

@@ -82,7 +83,7 @@ public class EuiccCardControllerTest extends TelephonyTest {
        mOtaStarted = false;
        mOtaLatch = new CountDownLatch(1);

        when(mEuiccController.getOtaStatus()).thenReturn(EuiccManager.EUICC_OTA_SUCCEEDED);
        when(mEuiccController.getOtaStatus(anyInt())).thenReturn(EuiccManager.EUICC_OTA_SUCCEEDED);
        doAnswer(new Answer<Void>() {
                @Override
                public Void answer(InvocationOnMock invocation) throws Throwable {
+11 −8
Original line number Diff line number Diff line
@@ -67,6 +67,8 @@ public class EuiccConnectorTest extends TelephonyTest {
    private EuiccConnector mConnector;
    @Mock private IEuiccService.Stub mEuiccService;

    private static final int CARD_ID = 15;

    @Before
    public void setUp() throws Exception {
        super.setUp("EuiccConnectorTest");
@@ -114,7 +116,7 @@ public class EuiccConnectorTest extends TelephonyTest {
                false /* hasPriority */);
        mConnector = new EuiccConnector(mContext, mLooper.getLooper());
        final AtomicBoolean called = new AtomicBoolean(false);
        mConnector.getEid(new EuiccConnector.GetEidCommandCallback() {
        mConnector.getEid(CARD_ID, new EuiccConnector.GetEidCommandCallback() {
            @Override
            public void onGetEidComplete(String eid) {
                fail("Command should have failed");
@@ -135,7 +137,8 @@ public class EuiccConnectorTest extends TelephonyTest {
                false /* hasPriority */);
        mConnector = new EuiccConnector(mContext, mLooper.getLooper());
        final AtomicBoolean called = new AtomicBoolean(false);
        mConnector.switchToSubscription("12345", true, new EuiccConnector.SwitchCommandCallback() {
        mConnector.switchToSubscription(CARD_ID, "12345", true, new
                EuiccConnector.SwitchCommandCallback() {
            @Override
            public void onSwitchComplete(int result) {
                fail("Command should have failed");
@@ -210,7 +213,7 @@ public class EuiccConnectorTest extends TelephonyTest {
            }
        }).when(mEuiccService).getEid(anyInt(), Mockito.<IGetEidCallback>any());
        final AtomicReference<String> eidRef = new AtomicReference<>();
        mConnector.getEid(new EuiccConnector.GetEidCommandCallback() {
        mConnector.getEid(CARD_ID, new EuiccConnector.GetEidCommandCallback() {
            @Override
            public void onGetEidComplete(String eid) {
                if (eidRef.get() != null) {
@@ -236,7 +239,7 @@ public class EuiccConnectorTest extends TelephonyTest {
        doThrow(new RemoteException("failure"))
                .when(mEuiccService).getEid(anyInt(), Mockito.<IGetEidCallback>any());
        final AtomicBoolean called = new AtomicBoolean(false);
        mConnector.getEid(new EuiccConnector.GetEidCommandCallback() {
        mConnector.getEid(CARD_ID, new EuiccConnector.GetEidCommandCallback() {
            @Override
            public void onGetEidComplete(String eid) {
                fail("Command should have failed");
@@ -258,7 +261,7 @@ public class EuiccConnectorTest extends TelephonyTest {
                true /* hasPriority */);
        mConnector = new EuiccConnector(mContext, mLooper.getLooper());
        final AtomicBoolean called = new AtomicBoolean(false);
        mConnector.getEid(new EuiccConnector.GetEidCommandCallback() {
        mConnector.getEid(CARD_ID, new EuiccConnector.GetEidCommandCallback() {
            @Override
            public void onGetEidComplete(String eid) {
                fail("Unexpected command success callback");
@@ -288,7 +291,7 @@ public class EuiccConnectorTest extends TelephonyTest {
        ArgumentCaptor<IGetEidCallback> callbackCaptor =
                ArgumentCaptor.forClass(IGetEidCallback.class);
        doNothing().when(mEuiccService).getEid(anyInt(), callbackCaptor.capture());
        mConnector.getEid(new EuiccConnector.GetEidCommandCallback() {
        mConnector.getEid(CARD_ID, new EuiccConnector.GetEidCommandCallback() {
            @Override public void onGetEidComplete(String eid) {}
            @Override public void onEuiccServiceUnavailable() {}
        });
@@ -316,11 +319,11 @@ public class EuiccConnectorTest extends TelephonyTest {
        ArgumentCaptor<IGetEidCallback> callbackCaptor =
                ArgumentCaptor.forClass(IGetEidCallback.class);
        doNothing().when(mEuiccService).getEid(anyInt(), callbackCaptor.capture());
        mConnector.getEid(new EuiccConnector.GetEidCommandCallback() {
        mConnector.getEid(CARD_ID, new EuiccConnector.GetEidCommandCallback() {
            @Override public void onGetEidComplete(String eid) {}
            @Override public void onEuiccServiceUnavailable() {}
        });
        mConnector.getEid(new EuiccConnector.GetEidCommandCallback() {
        mConnector.getEid(CARD_ID, new EuiccConnector.GetEidCommandCallback() {
            @Override public void onGetEidComplete(String eid) {}
            @Override public void onEuiccServiceUnavailable() {}
        });
Loading