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

Commit 7bd2985f authored by Holly Jiuyu Sun's avatar Holly Jiuyu Sun Committed by Gerrit Code Review
Browse files

Merge "Support profile policy rules as a resolvable error."

parents 253824fb f9a96b6c
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -30,10 +30,12 @@ import android.content.pm.ComponentInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.service.euicc.DownloadSubscriptionResult;
import android.service.euicc.EuiccService;
import android.service.euicc.GetDefaultDownloadableSubscriptionListResult;
import android.service.euicc.GetDownloadableSubscriptionMetadataResult;
@@ -225,13 +227,14 @@ public class EuiccConnector extends StateMachine implements ServiceConnection {
        boolean mSwitchAfterDownload;
        boolean mForceDeactivateSim;
        DownloadCommandCallback mCallback;
        Bundle mResolvedBundle;
    }

    /** Callback class for {@link #downloadSubscription}. */
    @VisibleForTesting(visibility = PACKAGE)
    public interface DownloadCommandCallback extends BaseEuiccCommandCallback {
        /** Called when the download has completed (though it may have failed). */
        void onDownloadComplete(int result);
        void onDownloadComplete(DownloadSubscriptionResult result);
    }

    interface GetEuiccProfileInfoListCommandCallback extends BaseEuiccCommandCallback {
@@ -423,11 +426,12 @@ public class EuiccConnector extends StateMachine implements ServiceConnection {
    @VisibleForTesting(visibility = PACKAGE)
    public void downloadSubscription(DownloadableSubscription subscription,
            boolean switchAfterDownload, boolean forceDeactivateSim,
            DownloadCommandCallback callback) {
            Bundle resolvedBundle, DownloadCommandCallback callback) {
        DownloadRequest request = new DownloadRequest();
        request.mSubscription = subscription;
        request.mSwitchAfterDownload = switchAfterDownload;
        request.mForceDeactivateSim = forceDeactivateSim;
        request.mResolvedBundle = resolvedBundle;
        request.mCallback = callback;
        sendMessage(CMD_DOWNLOAD_SUBSCRIPTION, request);
    }
@@ -709,9 +713,10 @@ public class EuiccConnector extends StateMachine implements ServiceConnection {
                                    request.mSubscription,
                                    request.mSwitchAfterDownload,
                                    request.mForceDeactivateSim,
                                    request.mResolvedBundle,
                                    new IDownloadSubscriptionCallback.Stub() {
                                        @Override
                                        public void onComplete(int result) {
                                        public void onComplete(DownloadSubscriptionResult result) {
                                            sendMessage(CMD_COMMAND_COMPLETE, (Runnable) () -> {
                                                ((DownloadCommandCallback) callback)
                                                    .onDownloadComplete(result);
+51 −21
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.ServiceManager;
import android.provider.Settings;
import android.service.euicc.DownloadSubscriptionResult;
import android.service.euicc.EuiccService;
import android.service.euicc.GetDefaultDownloadableSubscriptionListResult;
import android.service.euicc.GetDownloadableSubscriptionMetadataResult;
@@ -274,6 +275,7 @@ public class EuiccController extends IEuiccController.Stub {
                    addResolutionIntent(extrasIntent,
                            EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM,
                            mCallingPackage,
                            0 /* resolvableErrors */,
                            false /* confirmationCodeRetried */,
                            getOperationForDeactivateSim());
                    break;
@@ -301,14 +303,15 @@ public class EuiccController extends IEuiccController.Stub {

    @Override
    public void downloadSubscription(DownloadableSubscription subscription,
            boolean switchAfterDownload, String callingPackage, PendingIntent callbackIntent) {
            boolean switchAfterDownload, String callingPackage, Bundle resolvedBundle,
            PendingIntent callbackIntent) {
        downloadSubscription(subscription, switchAfterDownload, callingPackage,
                false /* forceDeactivateSim */, callbackIntent);
                false /* forceDeactivateSim */, resolvedBundle, callbackIntent);
    }

    void downloadSubscription(DownloadableSubscription subscription,
            boolean switchAfterDownload, String callingPackage, boolean forceDeactivateSim,
            PendingIntent callbackIntent) {
            Bundle resolvedBundle, PendingIntent callbackIntent) {
        boolean callerCanWriteEmbeddedSubscriptions = callerCanWriteEmbeddedSubscriptions();
        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);

@@ -318,7 +321,7 @@ public class EuiccController extends IEuiccController.Stub {
                // With WRITE_EMBEDDED_SUBSCRIPTIONS, we can skip profile-specific permission checks
                // and move straight to the profile download.
                downloadSubscriptionPrivileged(token, subscription, switchAfterDownload,
                        forceDeactivateSim, callingPackage, callbackIntent);
                        forceDeactivateSim, callingPackage, resolvedBundle, callbackIntent);
                return;
            }
            // Without WRITE_EMBEDDED_SUBSCRIPTIONS, the caller *must* be whitelisted per the
@@ -355,6 +358,7 @@ public class EuiccController extends IEuiccController.Stub {
                Intent extrasIntent = new Intent();
                addResolutionIntent(extrasIntent, EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
                            mCallingPackage,
                            0 /* resolvableErrors */,
                            false /* confirmationCodeRetried */,
                            EuiccOperation.forDownloadNoPrivileges(
                                    mCallingToken, mSubscription, mSwitchAfterDownload,
@@ -400,7 +404,8 @@ public class EuiccController extends IEuiccController.Stub {
                    if (canManageActiveSubscription(mCallingPackage)) {
                        downloadSubscriptionPrivileged(
                                mCallingToken, subscription, mSwitchAfterDownload,
                                mForceDeactivateSim, mCallingPackage, mCallbackIntent);
                                mForceDeactivateSim, mCallingPackage, null /* resolvedBundle */,
                                mCallbackIntent);
                        return;
                    }

@@ -408,6 +413,7 @@ public class EuiccController extends IEuiccController.Stub {
                    Intent extrasIntent = new Intent();
                    addResolutionIntent(extrasIntent, EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
                            mCallingPackage,
                            0 /* resolvableErrors */,
                            false /* confirmationCodeRetried */,
                            EuiccOperation.forDownloadNoPrivileges(
                                    mCallingToken, subscription, mSwitchAfterDownload,
@@ -429,18 +435,19 @@ public class EuiccController extends IEuiccController.Stub {

    void downloadSubscriptionPrivileged(final long callingToken,
            DownloadableSubscription subscription, boolean switchAfterDownload,
            boolean forceDeactivateSim, final String callingPackage,
            boolean forceDeactivateSim, final String callingPackage, Bundle resolvedBundle,
            final PendingIntent callbackIntent) {
        mConnector.downloadSubscription(
                subscription,
                switchAfterDownload,
                forceDeactivateSim,
                resolvedBundle,
                new EuiccConnector.DownloadCommandCallback() {
                    @Override
                    public void onDownloadComplete(int result) {
                    public void onDownloadComplete(DownloadSubscriptionResult result) {
                        Intent extrasIntent = new Intent();
                        final int resultCode;
                        switch (result) {
                        switch (result.getResult()) {
                            case EuiccService.RESULT_OK:
                                resultCode = OK;
                                // Now that a profile has been successfully downloaded, mark the
@@ -465,30 +472,47 @@ public class EuiccController extends IEuiccController.Stub {
                                addResolutionIntent(extrasIntent,
                                        EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM,
                                        callingPackage,
                                        0 /* resolvableErrors */,
                                        false /* confirmationCodeRetried */,
                                        EuiccOperation.forDownloadDeactivateSim(
                                                callingToken, subscription, switchAfterDownload,
                                                callingPackage));
                                break;
                            case EuiccService.RESULT_NEED_CONFIRMATION_CODE:
                            case EuiccService.RESULT_RESOLVABLE_ERRORS:
                                // Same value as the deprecated
                                // {@link EuiccService#RESULT_NEED_CONFIRMATION_CODE}. For the
                                // deprecated case, the resolvableErrors is set as 0 in
                                // EuiccService.
                                resultCode = RESOLVABLE_ERROR;
                                boolean retried = false;
                                if (!TextUtils.isEmpty(subscription.getConfirmationCode())) {
                                    retried = true;
                                }
                                if (result.getResolvableErrors() != 0) {
                                    addResolutionIntent(extrasIntent,
                                            EuiccService.ACTION_RESOLVE_RESOLVABLE_ERRORS,
                                            callingPackage,
                                            result.getResolvableErrors(),
                                            retried,
                                            EuiccOperation.forDownloadResolvableErrors(
                                                callingToken, subscription, switchAfterDownload,
                                                callingPackage, result.getResolvableErrors()));
                                }  else { // Deprecated case
                                    addResolutionIntent(extrasIntent,
                                            EuiccService.ACTION_RESOLVE_CONFIRMATION_CODE,
                                            callingPackage,
                                            0 /* resolvableErrors */,
                                            retried /* confirmationCodeRetried */,
                                            EuiccOperation.forDownloadConfirmationCode(
                                                callingToken, subscription, switchAfterDownload,
                                                callingPackage));
                                }
                                break;
                            default:
                                resultCode = ERROR;
                                extrasIntent.putExtra(
                                        EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE,
                                        result);
                                        result.getResult());
                                break;
                        }

@@ -587,6 +611,7 @@ public class EuiccController extends IEuiccController.Stub {
                    addResolutionIntent(extrasIntent,
                            EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM,
                            mCallingPackage,
                            0 /* resolvableErrors */,
                            false /* confirmationCodeRetried */,
                            EuiccOperation.forGetDefaultListDeactivateSim(
                                    mCallingToken, mCallingPackage));
@@ -739,6 +764,7 @@ public class EuiccController extends IEuiccController.Stub {
                addResolutionIntent(extrasIntent,
                        EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
                        callingPackage,
                        0 /* resolvableErrors */,
                        false /* confirmationCodeRetried */,
                        EuiccOperation.forSwitchNoPrivileges(
                                token, subscriptionId, callingPackage));
@@ -785,6 +811,7 @@ public class EuiccController extends IEuiccController.Stub {
                                addResolutionIntent(extrasIntent,
                                        EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM,
                                        callingPackage,
                                        0 /* resolvableErrors */,
                                        false /* confirmationCodeRetried */,
                                        EuiccOperation.forSwitchDeactivateSim(
                                                callingToken, subscriptionId, callingPackage));
@@ -953,11 +980,14 @@ public class EuiccController extends IEuiccController.Stub {
    /** Add a resolution intent to the given extras intent. */
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    public void addResolutionIntent(Intent extrasIntent, String resolutionAction,
            String callingPackage, boolean confirmationCodeRetried, EuiccOperation op) {
            String callingPackage, int resolvableErrors, boolean confirmationCodeRetried,
            EuiccOperation op) {
        Intent intent = new Intent(EuiccManager.ACTION_RESOLVE_ERROR);
        intent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_ACTION,
                resolutionAction);
        intent.putExtra(EuiccService.EXTRA_RESOLUTION_CALLING_PACKAGE, callingPackage);
        // TODO(jiuyu): Also pass cardId in the intent.
        intent.putExtra(EuiccService.EXTRA_RESOLVABLE_ERRORS, resolvableErrors);
        intent.putExtra(EuiccService.EXTRA_RESOLUTION_CONFIRMATION_CODE_RETRIED,
                confirmationCodeRetried);
        intent.putExtra(EXTRA_OPERATION, op);
+101 −11
Original line number Diff line number Diff line
@@ -61,7 +61,10 @@ public class EuiccOperation implements Parcelable {
            ACTION_GET_METADATA_DEACTIVATE_SIM,
            ACTION_DOWNLOAD_DEACTIVATE_SIM,
            ACTION_DOWNLOAD_NO_PRIVILEGES,
            ACTION_DOWNLOAD_CONFIRMATION_CODE,
            ACTION_GET_DEFAULT_LIST_DEACTIVATE_SIM,
            ACTION_SWITCH_DEACTIVATE_SIM,
            ACTION_SWITCH_NO_PRIVILEGES,
            ACTION_DOWNLOAD_RESOLVABLE_ERRORS,
    })
    @interface Action {}

@@ -78,7 +81,13 @@ public class EuiccOperation implements Parcelable {
    @VisibleForTesting
    static final int ACTION_SWITCH_NO_PRIVILEGES = 6;
    @VisibleForTesting
    static final int ACTION_DOWNLOAD_CONFIRMATION_CODE = 7;
    static final int ACTION_DOWNLOAD_RESOLVABLE_ERRORS = 7;
    /**
     * @deprecated Use ACTION_DOWNLOAD_RESOLVABLE_ERRORS and pass the resolvable errors in bit map.
     */
    @VisibleForTesting
    @Deprecated
    static final int ACTION_DOWNLOAD_CONFIRMATION_CODE = 8;

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    public final @Action int mAction;
@@ -91,6 +100,8 @@ public class EuiccOperation implements Parcelable {
    private final boolean mSwitchAfterDownload;
    @Nullable
    private final String mCallingPackage;
    @Nullable
    private final int mResolvableErrors;

    /**
     * {@link EuiccManager#getDownloadableSubscriptionMetadata} failed with
@@ -130,7 +141,12 @@ public class EuiccOperation implements Parcelable {
    /**
     * {@link EuiccManager#downloadSubscription} failed with
     * {@link EuiccService#RESULT_NEED_CONFIRMATION_CODE} error.
     *
     * @deprecated Use
     * {@link #forDownloadResolvableErrors(long, DownloadableSubscription, boolean, String, int)}
     * instead.
     */
    @Deprecated
    public static EuiccOperation forDownloadConfirmationCode(long callingToken,
            DownloadableSubscription subscription, boolean switchAfterDownload,
            String callingPackage) {
@@ -138,6 +154,18 @@ public class EuiccOperation implements Parcelable {
            subscription, 0 /* subscriptionId */, switchAfterDownload, callingPackage);
    }

    /**
     * {@link EuiccManager#downloadSubscription} failed with
     * {@link EuiccService#RESULT_RESOLVABLE_ERRORS} error.
     */
    public static EuiccOperation forDownloadResolvableErrors(long callingToken,
            DownloadableSubscription subscription, boolean switchAfterDownload,
            String callingPackage, int resolvableErrors) {
        return new EuiccOperation(ACTION_DOWNLOAD_RESOLVABLE_ERRORS, callingToken,
                subscription, 0 /* subscriptionId */, switchAfterDownload,
                callingPackage, resolvableErrors);
    }

    static EuiccOperation forGetDefaultListDeactivateSim(long callingToken, String callingPackage) {
        return new EuiccOperation(ACTION_GET_DEFAULT_LIST_DEACTIVATE_SIM, callingToken,
                null /* downloadableSubscription */, 0 /* subscriptionId */,
@@ -158,6 +186,22 @@ public class EuiccOperation implements Parcelable {
                false /* switchAfterDownload */, callingPackage);
    }

    EuiccOperation(@Action int action,
            long callingToken,
            @Nullable DownloadableSubscription downloadableSubscription,
            int subscriptionId,
            boolean switchAfterDownload,
            String callingPackage,
            int resolvableErrors) {
        mAction = action;
        mCallingToken = callingToken;
        mDownloadableSubscription = downloadableSubscription;
        mSubscriptionId = subscriptionId;
        mSwitchAfterDownload = switchAfterDownload;
        mCallingPackage = callingPackage;
        mResolvableErrors = resolvableErrors;
    }

    EuiccOperation(@Action int action,
            long callingToken,
            @Nullable DownloadableSubscription downloadableSubscription,
@@ -170,6 +214,7 @@ public class EuiccOperation implements Parcelable {
        mSubscriptionId = subscriptionId;
        mSwitchAfterDownload = switchAfterDownload;
        mCallingPackage = callingPackage;
        mResolvableErrors = 0;
    }

    EuiccOperation(Parcel in) {
@@ -179,6 +224,7 @@ public class EuiccOperation implements Parcelable {
        mSubscriptionId = in.readInt();
        mSwitchAfterDownload = in.readBoolean();
        mCallingPackage = in.readString();
        mResolvableErrors = in.readInt();
    }

    @Override
@@ -189,6 +235,7 @@ public class EuiccOperation implements Parcelable {
        dest.writeInt(mSubscriptionId);
        dest.writeBoolean(mSwitchAfterDownload);
        dest.writeString(mCallingPackage);
        dest.writeInt(mResolvableErrors);
    }

    /**
@@ -220,11 +267,14 @@ public class EuiccOperation implements Parcelable {
                        resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT),
                        callbackIntent);
                break;
            case ACTION_DOWNLOAD_CONFIRMATION_CODE:
            case ACTION_DOWNLOAD_CONFIRMATION_CODE: // Deprecated case
                resolvedDownloadConfirmationCode(
                        resolutionExtras.getString(EuiccService.EXTRA_RESOLUTION_CONFIRMATION_CODE),
                        callbackIntent);
                break;
            case ACTION_DOWNLOAD_RESOLVABLE_ERRORS:
                resolvedDownloadResolvableErrors(resolutionExtras, callbackIntent);
                break;
            case ACTION_GET_DEFAULT_LIST_DEACTIVATE_SIM:
                resolvedGetDefaultListDeactivateSim(
                        resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT),
@@ -272,6 +322,7 @@ public class EuiccOperation implements Parcelable {
                    mSwitchAfterDownload,
                    mCallingPackage,
                    true /* forceDeactivateSim */,
                    null /* resolvedBundle */,
                    callbackIntent);
        } else {
            // User has not consented; fail the operation.
@@ -294,6 +345,7 @@ public class EuiccOperation implements Parcelable {
                        mSwitchAfterDownload,
                        true /* forceDeactivateSim */,
                        mCallingPackage,
                        null /* resolvedBundle */,
                        callbackIntent);
            } finally {
                Binder.restoreCallingIdentity(token);
@@ -304,18 +356,56 @@ public class EuiccOperation implements Parcelable {
        }
    }

    /**
     * @deprecated The resolvable errors in download step are solved by
     * {@link #resolvedDownloadResolvableErrors(Bundle, PendingIntent)} from Q.
     */
    @Deprecated
    private void resolvedDownloadConfirmationCode(String confirmationCode,
            PendingIntent callbackIntent) {
        if (TextUtils.isEmpty(confirmationCode)) {
            fail(callbackIntent);
        } else {
            mDownloadableSubscription.setConfirmationCode(confirmationCode);
            EuiccController.get()
                    .downloadSubscription(
            EuiccController.get().downloadSubscription(
                    mDownloadableSubscription,
                    mSwitchAfterDownload,
                    mCallingPackage,
                    true /* forceDeactivateSim */,
                    null,
                    callbackIntent);
        }
    }

    private void resolvedDownloadResolvableErrors(Bundle resolvedBundle,
            PendingIntent callbackIntent) {
        boolean pass = true;
        String confirmationCode = null;
        if ((mResolvableErrors & EuiccService.RESOLVABLE_ERROR_POLICY_RULES) != 0) {
            if (!resolvedBundle.getBoolean(EuiccService.EXTRA_RESOLUTION_ALLOW_POLICY_RULES)) {
                pass = false;
            }
        }
        if ((mResolvableErrors & EuiccService.RESOLVABLE_ERROR_CONFIRMATION_CODE) != 0) {
            confirmationCode = resolvedBundle.getString(
                EuiccService.EXTRA_RESOLUTION_CONFIRMATION_CODE);
            // The check here just makes sure the entered confirmation code is non-empty. The actual
            // check to valid the confirmation code is done by LPA on the ensuing download attemp.
            if (TextUtils.isEmpty(confirmationCode)) {
                pass = false;
            }
        }

        if (!pass) {
            fail(callbackIntent);
        } else {
            mDownloadableSubscription.setConfirmationCode(confirmationCode);
            EuiccController.get().downloadSubscription(
                    mDownloadableSubscription,
                    mSwitchAfterDownload,
                    mCallingPackage,
                    true /* forceDeactivateSim */,
                    resolvedBundle,
                    callbackIntent);
        }
    }
+5 −3
Original line number Diff line number Diff line
@@ -566,14 +566,16 @@ public class EuiccCard extends UiccCard {
                    int size = nodes.size();
                    for (int i = 0; i < size; i++) {
                        Asn1Node node = nodes.get(i);
                        List<Asn1Node> opIdNodes = node.getChild(Tags.TAG_CTX_COMP_1).getChildren();
                        List<Asn1Node> opIdNodes =
                                node.getChild(Tags.TAG_SEQUENCE, Tags.TAG_CTX_COMP_1).getChildren();
                        int opIdSize = opIdNodes.size();
                        CarrierIdentifier[] opIds = new CarrierIdentifier[opIdSize];
                        for (int j = 0; j < opIdSize; j++) {
                            opIds[j] = buildCarrierIdentifier(opIdNodes.get(j));
                        }
                        builder.add(node.getChild(Tags.TAG_CTX_0).asBits(), Arrays.asList(opIds),
                                node.getChild(Tags.TAG_CTX_2).asBits());
                        builder.add(node.getChild(Tags.TAG_SEQUENCE, Tags.TAG_CTX_0).asBits(),
                                Arrays.asList(opIds), node.getChild(Tags.TAG_SEQUENCE,
                                Tags.TAG_CTX_2).asBits());
                    }
                    return builder.build();
                },
+1 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ class Tags {
    // Universal tags
    static final int TAG_UNI_2 = 0x02;
    static final int TAG_UNI_4 = 0x04;
    static final int TAG_SEQUENCE = 0x30;
    // Context tags for primitive types
    static final int TAG_CTX_0 = 0x80;
    static final int TAG_CTX_1 = 0x81;
Loading