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

Commit 53178817 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix double prompt when downloading profiles." into oc-dr1-dev

parents 706cbe16 9af64248
Loading
Loading
Loading
Loading
+49 −17
Original line number Diff line number Diff line
@@ -170,21 +170,23 @@ public class EuiccController extends IEuiccController.Stub {

    @Override
    public void getDownloadableSubscriptionMetadata(DownloadableSubscription subscription,
            PendingIntent callbackIntent) {
            String callingPackage, PendingIntent callbackIntent) {
        getDownloadableSubscriptionMetadata(
                subscription, false /* forceDeactivateSim */, callbackIntent);
                subscription, false /* forceDeactivateSim */, callingPackage, callbackIntent);
    }

    void getDownloadableSubscriptionMetadata(DownloadableSubscription subscription,
            boolean forceDeactivateSim, PendingIntent callbackIntent) {
            boolean forceDeactivateSim, String callingPackage, PendingIntent callbackIntent) {
        if (!callerCanWriteEmbeddedSubscriptions()) {
            throw new SecurityException("Must have WRITE_EMBEDDED_SUBSCRIPTIONS to get metadata");
        }
        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
        long token = Binder.clearCallingIdentity();
        try {
            mConnector.getDownloadableSubscriptionMetadata(
                    subscription, forceDeactivateSim,
                    new GetMetadataCommandCallback(token, subscription, callbackIntent));
                    new GetMetadataCommandCallback(
                            token, subscription, callingPackage, callbackIntent));
        } finally {
            Binder.restoreCallingIdentity(token);
        }
@@ -193,14 +195,17 @@ public class EuiccController extends IEuiccController.Stub {
    class GetMetadataCommandCallback implements EuiccConnector.GetMetadataCommandCallback {
        protected final long mCallingToken;
        protected final DownloadableSubscription mSubscription;
        protected final String mCallingPackage;
        protected final PendingIntent mCallbackIntent;

        GetMetadataCommandCallback(
                long callingToken,
                DownloadableSubscription subscription,
                String callingPackage,
                PendingIntent callbackIntent) {
            mCallingToken = callingToken;
            mSubscription = subscription;
            mCallingPackage = callingPackage;
            mCallbackIntent = callbackIntent;
        }

@@ -220,6 +225,7 @@ public class EuiccController extends IEuiccController.Stub {
                    resultCode = RESOLVABLE_ERROR;
                    addResolutionIntent(extrasIntent,
                            EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM,
                            mCallingPackage,
                            getOperationForDeactivateSim());
                    break;
                default:
@@ -239,7 +245,8 @@ public class EuiccController extends IEuiccController.Stub {
        }

        protected EuiccOperation getOperationForDeactivateSim() {
            return EuiccOperation.forGetMetadataDeactivateSim(mCallingToken, mSubscription);
            return EuiccOperation.forGetMetadataDeactivateSim(
                    mCallingToken, mSubscription, mCallingPackage);
        }
    }

@@ -279,22 +286,33 @@ public class EuiccController extends IEuiccController.Stub {

    class DownloadSubscriptionGetMetadataCommandCallback extends GetMetadataCommandCallback {
        private final boolean mSwitchAfterDownload;
        private final String mCallingPackage;
        private final boolean mForceDeactivateSim;

        DownloadSubscriptionGetMetadataCommandCallback(long callingToken,
                DownloadableSubscription subscription, boolean switchAfterDownload,
                String callingPackage, boolean forceDeactivateSim,
                PendingIntent callbackIntent) {
            super(callingToken, subscription, callbackIntent);
            super(callingToken, subscription, callingPackage, callbackIntent);
            mSwitchAfterDownload = switchAfterDownload;
            mCallingPackage = callingPackage;
            mForceDeactivateSim = forceDeactivateSim;
        }

        @Override
        public void onGetMetadataComplete(
                GetDownloadableSubscriptionMetadataResult result) {
            if (result.result == EuiccService.RESULT_MUST_DEACTIVATE_SIM) {
                // If we need to deactivate the current SIM to even check permissions, go ahead and
                // require that the user resolve the stronger permission dialog.
                Intent extrasIntent = new Intent();
                addResolutionIntent(extrasIntent, EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
                        mCallingPackage,
                        EuiccOperation.forDownloadNoPrivileges(
                                mCallingToken, mSubscription, mSwitchAfterDownload,
                                mCallingPackage));
                sendResult(mCallbackIntent, RESOLVABLE_ERROR, extrasIntent);
                return;
            }

            if (result.result != EuiccService.RESULT_OK) {
                // Just propagate the error as normal.
                super.onGetMetadataComplete(result);
@@ -335,6 +353,7 @@ public class EuiccController extends IEuiccController.Stub {
                    // Switch might still be permitted, but the user must consent first.
                    Intent extrasIntent = new Intent();
                    addResolutionIntent(extrasIntent, EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
                            mCallingPackage,
                            EuiccOperation.forDownloadNoPrivileges(
                                    mCallingToken, subscription, mSwitchAfterDownload,
                                    mCallingPackage));
@@ -386,6 +405,7 @@ public class EuiccController extends IEuiccController.Stub {
                                resultCode = RESOLVABLE_ERROR;
                                addResolutionIntent(extrasIntent,
                                        EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM,
                                        callingPackage,
                                        EuiccOperation.forDownloadDeactivateSim(
                                                callingToken, subscription, switchAfterDownload,
                                                callingPackage));
@@ -439,31 +459,38 @@ public class EuiccController extends IEuiccController.Stub {
    }

    @Override
    public void getDefaultDownloadableSubscriptionList(PendingIntent callbackIntent) {
        getDefaultDownloadableSubscriptionList(false /* forceDeactivateSim */, callbackIntent);
    public void getDefaultDownloadableSubscriptionList(
            String callingPackage, PendingIntent callbackIntent) {
        getDefaultDownloadableSubscriptionList(
                false /* forceDeactivateSim */, callingPackage, callbackIntent);
    }

    void getDefaultDownloadableSubscriptionList(
            boolean forceDeactivateSim, PendingIntent callbackIntent) {
            boolean forceDeactivateSim, String callingPackage, PendingIntent callbackIntent) {
        if (!callerCanWriteEmbeddedSubscriptions()) {
            throw new SecurityException(
                    "Must have WRITE_EMBEDDED_SUBSCRIPTIONS to get default list");
        }
        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
        long token = Binder.clearCallingIdentity();
        try {
            mConnector.getDefaultDownloadableSubscriptionList(
                    forceDeactivateSim, new GetDefaultListCommandCallback(token, callbackIntent));
                    forceDeactivateSim, new GetDefaultListCommandCallback(
                            token, callingPackage, callbackIntent));
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    class GetDefaultListCommandCallback implements EuiccConnector.GetDefaultListCommandCallback {
        protected final long mCallingToken;
        protected final PendingIntent mCallbackIntent;
        final long mCallingToken;
        final String mCallingPackage;
        final PendingIntent mCallbackIntent;

        GetDefaultListCommandCallback(long callingToken, PendingIntent callbackIntent) {
        GetDefaultListCommandCallback(long callingToken, String callingPackage,
                PendingIntent callbackIntent) {
            mCallingToken = callingToken;
            mCallingPackage = callingPackage;
            mCallbackIntent = callbackIntent;
        }

@@ -482,7 +509,9 @@ public class EuiccController extends IEuiccController.Stub {
                    resultCode = RESOLVABLE_ERROR;
                    addResolutionIntent(extrasIntent,
                            EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM,
                            EuiccOperation.forGetDefaultListDeactivateSim(mCallingToken));
                            mCallingPackage,
                            EuiccOperation.forGetDefaultListDeactivateSim(
                                    mCallingToken, mCallingPackage));
                    break;
                default:
                    resultCode = ERROR;
@@ -624,6 +653,7 @@ public class EuiccController extends IEuiccController.Stub {
                Intent extrasIntent = new Intent();
                addResolutionIntent(extrasIntent,
                        EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
                        callingPackage,
                        EuiccOperation.forSwitchNoPrivileges(
                                token, subscriptionId, callingPackage));
                sendResult(callbackIntent, RESOLVABLE_ERROR, extrasIntent);
@@ -668,6 +698,7 @@ public class EuiccController extends IEuiccController.Stub {
                                resultCode = RESOLVABLE_ERROR;
                                addResolutionIntent(extrasIntent,
                                        EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM,
                                        callingPackage,
                                        EuiccOperation.forSwitchDeactivateSim(
                                                callingToken, subscriptionId, callingPackage));
                                break;
@@ -790,10 +821,11 @@ 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,
            EuiccOperation op) {
            String callingPackage, 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);
        intent.putExtra(EXTRA_OPERATION, op);
        PendingIntent resolutionIntent = PendingIntent.getActivity(
                mContext, 0 /* requestCode */, intent, PendingIntent.FLAG_ONE_SHOT);
+13 −13
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.service.euicc.EuiccService;
import android.service.euicc.GetDownloadableSubscriptionMetadataResult;
import android.telephony.euicc.DownloadableSubscription;
import android.telephony.euicc.EuiccManager;
import android.util.Log;
@@ -91,18 +90,19 @@ public class EuiccOperation implements Parcelable {

    /**
     * {@link EuiccManager#getDownloadableSubscriptionMetadata} failed with
     * {@link GetDownloadableSubscriptionMetadataResult#mustDeactivateSim}.
     * {@link EuiccService#RESULT_MUST_DEACTIVATE_SIM}.
     */
    public static EuiccOperation forGetMetadataDeactivateSim(long callingToken,
            DownloadableSubscription subscription) {
            DownloadableSubscription subscription, String callingPackage) {
        return new EuiccOperation(ACTION_GET_METADATA_DEACTIVATE_SIM, callingToken,
                subscription, 0 /* subscriptionId */, false /* switchAfterDownload */,
                null /* callingPackage */);
                callingPackage);
    }

    /**
     * {@link EuiccManager#downloadSubscription} failed with a mustDeactivateSim error (either in
     * the metadata lookup for unprivileged callers or the download itself for privileged ones).
     * {@link EuiccManager#downloadSubscription} failed with a mustDeactivateSim error. Should only
     * be used for privileged callers; for unprivileged callers, use
     * {@link #forDownloadNoPrivileges} to avoid a double prompt.
     */
    public static EuiccOperation forDownloadDeactivateSim(long callingToken,
            DownloadableSubscription subscription, boolean switchAfterDownload,
@@ -113,7 +113,8 @@ public class EuiccOperation implements Parcelable {

    /**
     * {@link EuiccManager#downloadSubscription} failed because the calling app does not have
     * permission to manage the current active subscription.
     * permission to manage the current active subscription, or because we cannot determine the
     * privileges without deactivating the current SIM first.
     */
    public static EuiccOperation forDownloadNoPrivileges(long callingToken,
            DownloadableSubscription subscription, boolean switchAfterDownload,
@@ -122,10 +123,10 @@ public class EuiccOperation implements Parcelable {
                subscription,  0 /* subscriptionId */, switchAfterDownload, callingPackage);
    }

    static EuiccOperation forGetDefaultListDeactivateSim(long callingToken) {
    static EuiccOperation forGetDefaultListDeactivateSim(long callingToken, String callingPackage) {
        return new EuiccOperation(ACTION_GET_DEFAULT_LIST_DEACTIVATE_SIM, callingToken,
                null /* downloadableSubscription */, 0 /* subscriptionId */,
                false /* switchAfterDownload */, null /* callingPackage */);
                false /* switchAfterDownload */, callingPackage);
    }

    static EuiccOperation forSwitchDeactivateSim(long callingToken, int subscriptionId,
@@ -233,6 +234,7 @@ public class EuiccOperation implements Parcelable {
            EuiccController.get().getDownloadableSubscriptionMetadata(
                    mDownloadableSubscription,
                    true /* forceDeactivateSim */,
                    mCallingPackage,
                    callbackIntent);
        } else {
            // User has not consented; fail the operation.
@@ -265,9 +267,7 @@ public class EuiccOperation implements Parcelable {
                // Note: We turn on "forceDeactivateSim" here under the assumption that the
                // privilege prompt should also cover permission to deactivate an active SIM, as
                // the privilege prompt makes it clear that we're switching from the current
                // 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.
                // carrier.
                EuiccController.get().downloadSubscriptionPrivileged(
                        token,
                        mDownloadableSubscription,
@@ -290,7 +290,7 @@ public class EuiccOperation implements Parcelable {
            // User has consented; perform the lookup, but this time, tell the LPA to deactivate any
            // required active SIMs.
            EuiccController.get().getDefaultDownloadableSubscriptionList(
                    true /* forceDeactivateSim */, callbackIntent);
                    true /* forceDeactivateSim */, mCallingPackage, callbackIntent);
        } else {
            // User has not consented; fail the operation.
            fail(callbackIntent);
+8 −5
Original line number Diff line number Diff line
@@ -119,7 +119,8 @@ public class EuiccControllerTest extends TelephonyTest {
        }

        @Override
        public void addResolutionIntent(Intent extrasIntent, String resolutionAction,
        public void addResolutionIntent(
                Intent extrasIntent, String resolutionAction, String callingPackage,
                EuiccOperation op) {
            mResolutionAction = resolutionAction;
            mOp = op;
@@ -381,8 +382,10 @@ public class EuiccControllerTest extends TelephonyTest {
                12345, PACKAGE_NAME /* callingPackage */);
        verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR,
                0 /* detailedCode */);
        verifyResolutionIntent(EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM,
                EuiccOperation.ACTION_DOWNLOAD_DEACTIVATE_SIM);
        // In this case we go with the potentially stronger NO_PRIVILEGES consent dialog to avoid
        // double prompting.
        verifyResolutionIntent(EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
                EuiccOperation.ACTION_DOWNLOAD_NO_PRIVILEGES);
    }

    @Test
@@ -776,7 +779,7 @@ public class EuiccControllerTest extends TelephonyTest {
            boolean complete, GetDownloadableSubscriptionMetadataResult result) {
        prepareGetDownloadableSubscriptionMetadataCall(complete, result);
        PendingIntent resultCallback = PendingIntent.getBroadcast(mContext, 0, new Intent(), 0);
        mController.getDownloadableSubscriptionMetadata(subscription, resultCallback);
        mController.getDownloadableSubscriptionMetadata(subscription, PACKAGE_NAME, resultCallback);
    }

    private void callGetDefaultDownloadableSubscriptionList(
@@ -794,7 +797,7 @@ public class EuiccControllerTest extends TelephonyTest {
            }
        }).when(mMockConnector).getDefaultDownloadableSubscriptionList(anyBoolean(), any());
        PendingIntent resultCallback = PendingIntent.getBroadcast(mContext, 0, new Intent(), 0);
        mController.getDefaultDownloadableSubscriptionList(resultCallback);
        mController.getDefaultDownloadableSubscriptionList(PACKAGE_NAME, resultCallback);
    }

    private void callDownloadSubscription(DownloadableSubscription subscription,