EuiccManager#startResolutionActivity behavior changed in Android 12 (API 31)

958 views Asked by At

After upgrading our app to use the targetSdkVersion & compileSdkVersion to 31, we're facing a different behaviour in the esim activation process, when calling startResolutionActivity the app now crashes with:

08-27 10:49:06.288  6641  6641 D DownloadEsimSubscription: 2 - Event received!, com.myapp.download_subscription - 1
08-27 10:49:06.288  6641  6641 D DownloadEsimSubscription: 2 - Subscription downloaded, com.myapp.download_subscription - 1
08-27 10:49:06.296  6641  6641 E AndroidRuntime: FATAL EXCEPTION: main
08-27 10:49:06.296  6641  6641 E AndroidRuntime: Process: com.myapp, PID: 6641
08-27 10:49:06.296  6641  6641 E AndroidRuntime: io.reactivex.exceptions.OnErrorNotImplementedException: Invalid result intent
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:704)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:701)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at io.reactivex.internal.observers.LambdaObserver.onError(LambdaObserver.java:74)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at io.reactivex.internal.observers.LambdaObserver.onNext(LambdaObserver.java:64)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:200)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:252)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker$BooleanRunnable.run(ExecutorScheduler.java:260)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker.run(ExecutorScheduler.java:225)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at android.os.Handler.handleCallback(Handler.java:938)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at android.os.Handler.dispatchMessage(Handler.java:99)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at android.os.Looper.loopOnce(Looper.java:201)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at android.os.Looper.loop(Looper.java:288)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at android.app.ActivityThread.main(ActivityThread.java:7822)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at java.lang.reflect.Method.invoke(Native Method)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
08-27 10:49:06.296  6641  6641 E AndroidRuntime: Caused by: java.lang.IllegalArgumentException: Invalid result intent
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at android.telephony.euicc.EuiccManager.startResolutionActivity(EuiccManager.java:954)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at com.myapp.esim.system.StartResolvableErrorActivity.invoke(StartResolvableErrorActivity.kt:33)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at com.myapp.esim.ui.EsimFlowView$onCreate$$inlined$observe$1.onChanged(ArchitectureComponentsExtensions.kt:29)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at androidx.lifecycle.LiveData.considerNotify(LiveData.java:133)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:151)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at androidx.lifecycle.LiveData.setValue(LiveData.java:309)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at com.myapp.ui.-$$Lambda$Hv4SBqiTm1O-ghpLWVMxBLQvcAA.accept(Unknown Source:4)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    at io.reactivex.internal.observers.LambdaObserver.onNext(LambdaObserver.java:60)
08-27 10:49:06.296  6641  6641 E AndroidRuntime:    ... 12 more

Checking the source code it seems that now there is a required extra in the intent:

    public void startResolutionActivity(Activity activity, int requestCode, Intent resultIntent,
            PendingIntent callbackIntent) throws IntentSender.SendIntentException {
        PendingIntent resolutionIntent =
                resultIntent.getParcelableExtra(EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT);
        if (resolutionIntent == null) {
            throw new IllegalArgumentException("Invalid result intent");
        }
        Intent fillInIntent = new Intent();
        fillInIntent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT,
                callbackIntent);
        activity.startIntentSenderForResult(resolutionIntent.getIntentSender(), requestCode,
                fillInIntent, 0 /* flagsMask */, 0 /* flagsValues */, 0 /* extraFlags */);
    }

Which is:

    /**
     * Key for an extra set on {@link PendingIntent} result callbacks providing the resolution
     * pending intent for {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}s.
     * @hide
     */
    public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT =
            "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT";

But I'm not clear about what should this extra be. Also this is not mentioned (yet, I suppose) in the documentation.

Testing the same code targeting and building the app against api 30 works.

The relevant code:


 open operator fun invoke(intent: Intent) {
        val callbackIntent = PendingIntent.getBroadcast(activity,
            RequestCodes.REQUEST_DOWNLOAD,
            Intent(DownloadEsimSubscription.getActionDownloadSubscriptionName(activity)),
            PendingIntent.FLAG_UPDATE_CURRENT
        )

        val euiccManager = activity.getSystemService(Context.EUICC_SERVICE) as EuiccManager

        try {
            euiccManager.startResolutionActivity(
                activity,
                RequestCodes.REQUEST_SOLVE_ISSUE,
                intent,
                callbackIntent
            )
        } catch (e: IntentSender.SendIntentException) {
            Logger.e(LOGTAG, "SendIntentException when calling again startResolutionActivity - ", e)
        }

        esimActivationFlowBL.switch()
    }

where the intent passed to this method is the returned in the broadcastReceiver that listens for the subscription process

Has anyone else faced this?

1

There are 1 answers

2
Guillermo Merino On BEST ANSWER

The callback intent used in

euiccManager.downloadSubscription(subscription, true, callbackIntent)

should have the mutable flag, so the system can add the extras needed for the resolution activity.

In my case:

val callbackIntent = PendingIntent.getBroadcast(context, RequestCodes.REQUEST_DOWNLOAD, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE)

val euiccManager = context.getSystemService(Context.EUICC_SERVICE) as EuiccManager
       euiccManager.downloadSubscription(subscription, true, callbackIntent)