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

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

Merge "Add portIndex for switch subscription API"

parents e72e4ca8 abedec16
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -42283,7 +42283,8 @@ package android.telephony.euicc {
    method public boolean isEnabled();
    method public boolean isSimPortAvailable(int);
    method public void startResolutionActivity(android.app.Activity, int, android.content.Intent, android.app.PendingIntent) throws android.content.IntentSender.SendIntentException;
    method @RequiresPermission("android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS") public void switchToSubscription(int, android.app.PendingIntent);
    method @Deprecated @RequiresPermission("android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS") public void switchToSubscription(int, android.app.PendingIntent);
    method @RequiresPermission("android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS") public void switchToSubscription(int, int, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.euicc.EuiccManager.ResultListener);
    method @RequiresPermission("android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS") public void updateSubscriptionNickname(int, @Nullable String, @NonNull android.app.PendingIntent);
    field public static final String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS = "android.telephony.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS";
    field public static final String ACTION_NOTIFY_CARRIER_SETUP_INCOMPLETE = "android.telephony.euicc.action.NOTIFY_CARRIER_SETUP_INCOMPLETE";
@@ -42329,6 +42330,10 @@ package android.telephony.euicc {
    field public static final int OPERATION_SYSTEM = 1; // 0x1
  }
  public static interface EuiccManager.ResultListener {
    method public void onComplete(int, @Nullable android.content.Intent);
  }
}
package android.telephony.gsm {
+3 −1
Original line number Diff line number Diff line
@@ -9641,7 +9641,8 @@ package android.service.euicc {
    method @android.telephony.euicc.EuiccManager.OtaStatus public abstract int onGetOtaStatus(int);
    method public abstract int onRetainSubscriptionsForFactoryReset(int);
    method public abstract void onStartOtaIfNecessary(int, android.service.euicc.EuiccService.OtaStatusChangedCallback);
    method public abstract int onSwitchToSubscription(int, @Nullable String, boolean);
    method @Deprecated public abstract int onSwitchToSubscription(int, @Nullable String, boolean);
    method public int onSwitchToSubscriptionWithPort(int, int, @Nullable String, boolean);
    method public abstract int onUpdateSubscriptionNickname(int, String, String);
    field public static final String ACTION_BIND_CARRIER_PROVISIONING_SERVICE = "android.service.euicc.action.BIND_CARRIER_PROVISIONING_SERVICE";
    field public static final String ACTION_DELETE_SUBSCRIPTION_PRIVILEGED = "android.service.euicc.action.DELETE_SUBSCRIPTION_PRIVILEGED";
@@ -9663,6 +9664,7 @@ package android.service.euicc {
    field public static final String EXTRA_RESOLUTION_CONFIRMATION_CODE = "android.service.euicc.extra.RESOLUTION_CONFIRMATION_CODE";
    field public static final String EXTRA_RESOLUTION_CONFIRMATION_CODE_RETRIED = "android.service.euicc.extra.RESOLUTION_CONFIRMATION_CODE_RETRIED";
    field public static final String EXTRA_RESOLUTION_CONSENT = "android.service.euicc.extra.RESOLUTION_CONSENT";
    field public static final String EXTRA_RESOLUTION_PORT_INDEX = "android.service.euicc.extra.RESOLUTION_PORT_INDEX";
    field public static final String EXTRA_RESOLVABLE_ERRORS = "android.service.euicc.extra.RESOLVABLE_ERRORS";
    field public static final int RESOLVABLE_ERROR_CONFIRMATION_CODE = 1; // 0x1
    field public static final int RESOLVABLE_ERROR_POLICY_RULES = 2; // 0x2
+35 −7
Original line number Diff line number Diff line
@@ -255,6 +255,12 @@ public abstract class EuiccService extends Service {
    public static final String EXTRA_RESOLUTION_CARD_ID =
            "android.service.euicc.extra.RESOLUTION_CARD_ID";

    /**
     * Intent extra set for resolution requests containing an int indicating the current port index.
     */
    public static final String EXTRA_RESOLUTION_PORT_INDEX =
            "android.service.euicc.extra.RESOLUTION_PORT_INDEX";

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = { "RESULT_" }, value = {
@@ -579,9 +585,32 @@ public abstract class EuiccService extends Service {
     * @return the result of the switch operation. May be one of the predefined {@code RESULT_}
     *     constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
     * @see android.telephony.euicc.EuiccManager#switchToSubscription
     *
     * @deprecated prefer {@link #onSwitchToSubscriptionWithPort(int, int, String, boolean)}
     */
    public abstract @Result int onSwitchToSubscription(int slotId, @Nullable String iccid,
            boolean forceDeactivateSim);
    @Deprecated public abstract @Result int onSwitchToSubscription(int slotId,
            @Nullable String iccid, boolean forceDeactivateSim);

    /**
     * Switch to the given subscription.
     *
     * @param slotId ID of the SIM slot to use for the operation.
     * @param portIndex which port on the eUICC to use
     * @param iccid the ICCID of the subscription to enable. May be null, in which case the current
     *     profile should be deactivated and no profile should be activated to replace it - this is
     *     equivalent to a physical SIM being ejected.
     * @param forceDeactivateSim If true, and if an active SIM must be deactivated to access the
     *     eUICC, perform this action automatically. Otherwise, {@link #RESULT_MUST_DEACTIVATE_SIM}
     *     should be returned to allow the user to consent to this operation first.
     * @return the result of the switch operation. May be one of the predefined {@code RESULT_}
     *     constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
     * @see android.telephony.euicc.EuiccManager#switchToSubscription
     */
    public @Result int onSwitchToSubscriptionWithPort(int slotId, int portIndex,
            @Nullable String iccid, boolean forceDeactivateSim) {
        // stub implementation, LPA needs to implement this
        throw new UnsupportedOperationException("LPA must override onSwitchToSubscriptionWithPort");
    }

    /**
     * Update the nickname of the given subscription.
@@ -821,16 +850,15 @@ public abstract class EuiccService extends Service {
                }
            });
        }

        @Override
        public void switchToSubscription(int slotId, String iccid, boolean forceDeactivateSim,
                ISwitchToSubscriptionCallback callback) {
        public void switchToSubscription(int slotId, int portIndex, String iccid,
                boolean forceDeactivateSim, ISwitchToSubscriptionCallback callback) {
            mExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    int result =
                            EuiccService.this.onSwitchToSubscription(
                                    slotId, iccid, forceDeactivateSim);
                            EuiccService.this.onSwitchToSubscriptionWithPort(
                                    slotId, portIndex, iccid, forceDeactivateSim);
                    try {
                        callback.onComplete(result);
                    } catch (RemoteException e) {
+1 −1
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ oneway interface IEuiccService {
            in IGetDefaultDownloadableSubscriptionListCallback callback);
    void getEuiccInfo(int slotId, in IGetEuiccInfoCallback callback);
    void deleteSubscription(int slotId, String iccid, in IDeleteSubscriptionCallback callback);
    void switchToSubscription(int slotId, String iccid, boolean forceDeactivateSim,
    void switchToSubscription(int slotId, int portIndex, String iccid, boolean forceDeactivateSim,
            in ISwitchToSubscriptionCallback callback);
    void updateSubscriptionNickname(int slotId, String iccid, String nickname,
            in IUpdateSubscriptionNicknameCallback callback);
+95 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package android.telephony.euicc;

import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -28,6 +29,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.RemoteException;
import android.telephony.TelephonyFrameworkInitializer;
@@ -35,11 +37,13 @@ import android.telephony.TelephonyManager;
import android.telephony.euicc.EuiccCardManager.ResetOption;

import com.android.internal.telephony.euicc.IEuiccController;
import com.android.internal.telephony.euicc.IResultCallback;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

/**
@@ -214,6 +218,20 @@ public class EuiccManager {
    public static final String ACTION_START_EUICC_ACTIVATION =
            "android.telephony.euicc.action.START_EUICC_ACTIVATION";

    /**
     * Result codes passed to the ResultListener by
     * {@link #switchToSubscription(int, int, Executor, ResultListener)}
     *
     * @hide
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = {"EMBEDDED_SUBSCRIPTION_RESULT_"}, value = {
            EMBEDDED_SUBSCRIPTION_RESULT_OK,
            EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
            EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR
    })
    public @interface ResultCode{}

    /**
     * Result code for an operation indicating that the operation succeeded.
     */
@@ -1125,7 +1143,12 @@ public class EuiccManager {
     *     permission, or the calling app must be authorized to manage the active subscription on
     *     the target eUICC.
     * @param callbackIntent a PendingIntent to launch when the operation completes.
     *
     * @deprecated From T, callers should use
     * {@link #switchToSubscription(int, int, Executor, ResultListener)} instead to specify a port
     * index on the card to switch to.
     */
    @Deprecated
    @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
    public void switchToSubscription(int subscriptionId, PendingIntent callbackIntent) {
        if (!isEnabled()) {
@@ -1140,6 +1163,71 @@ public class EuiccManager {
        }
    }

    /**
     * Switch to (enable) the given subscription.
     *
     * <p>Requires the {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission,
     * or the calling app must be authorized to manage both the currently-active subscription and
     * the subscription to be enabled according to the subscription metadata. Without the former,
     * an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback
     * intent to prompt the user to accept the download.
     *
     * <p>On a multi-active SIM device, requires the
     * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission, or a calling app
     * only if the targeted eUICC does not currently have an active subscription or the calling app
     * is authorized to manage the active subscription on the target eUICC, and the calling app is
     * authorized to manage any active subscription on any SIM. Without it, an
     * {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback
     * intent to prompt the user to accept the download. The caller should also be authorized to
     * manage the subscription to be enabled.
     *
     * @param subscriptionId the ID of the subscription to enable. May be
     *     {@link android.telephony.SubscriptionManager#INVALID_SUBSCRIPTION_ID} to deactivate the
     *     current profile without activating another profile to replace it. If it's a disable
     *     operation, requires the {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS}
     *     permission, or the calling app must be authorized to manage the active subscription on
     *     the target eUICC.
     * @param portIndex the index of the port to target for the enabled subscription
     * @param executor an Executor on which to run the callback
     * @param callback a {@link ResultListener} which will run when the operation completes
     */
    @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
    public void switchToSubscription(int subscriptionId, int portIndex,
            @NonNull @CallbackExecutor Executor executor,
            @NonNull ResultListener callback) {
        if (!isEnabled()) {
            sendUnavailableErrorToCallback(executor, callback);
            return;
        }
        try {
            IResultCallback internalCallback = new IResultCallback.Stub() {
                @Override
                public void onComplete(int result, Intent resultIntent) {
                    executor.execute(() -> Binder.withCleanCallingIdentity(
                            () -> callback.onComplete(result, resultIntent)));
                }
            };
            getIEuiccController().switchToSubscriptionWithPort(mCardId, portIndex,
                    subscriptionId, mContext.getOpPackageName(), internalCallback);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Callback to receive the result of an EuiccManager API.
     */
    public interface ResultListener {
        /**
         * Called on completion of some operation.
         * @param resultCode representing success or specific failure of the operation
         *                   (See {@link ResultCode})
         * @param resultIntent an intent used to start a resolution activity when an error
         *                     occurs that can be resolved by the user
         */
        void onComplete(@ResultCode int resultCode, @Nullable Intent resultIntent);
    }

    /**
     * Update the nickname for the given subscription.
     *
@@ -1411,6 +1499,13 @@ public class EuiccManager {
        }
    }

    private static void sendUnavailableErrorToCallback(@NonNull Executor executor,
            ResultListener callback) {
        Integer result = EMBEDDED_SUBSCRIPTION_RESULT_ERROR;
        executor.execute(() ->
                Binder.withCleanCallingIdentity(() -> callback.onComplete(result, null)));
    }

    private static IEuiccController getIEuiccController() {
        return IEuiccController.Stub.asInterface(
                TelephonyFrameworkInitializer
Loading