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

Commit effba65e authored by Chen Xu's avatar Chen Xu Committed by Automerger Merge Worker
Browse files

Merge "Add portIndex for switch subscription API" am: d9e8a4f5

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2037585

Change-Id: Ibb579deeb47826fc012e85001d0437710ebd61ba
parents 3d9bbd18 d9e8a4f5
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