AppAuth-Android icon indicating copy to clipboard operation
AppAuth-Android copied to clipboard

NPE on AuthorizationManagementActivity.onResume (from Android framework?)

Open zoltanf opened this issue 7 years ago • 16 comments

I can't reproduce it myself, but on an app with around half million active users it's happening on production from time to time. (we are using the latest AppAuth version 0.7.0).

Usually happening on these devices:

  • Huawei 荣耀5X (HNKIW-Q) [Android 6.0]
  • Galaxy TabS 10.5 (chagalllte) [Android 6.0]
  • Gigaset GS170 (GS170) [Android 7.0]
  • Galaxy J1 (j13g) [Android 4.4]
  • Samsung Galaxy S5 mini (kminilte) [Android 6.0]

NPE:

java.lang.NullPointerException: android.app.Instrumentation in Attempt to invoke virtual method 'boolean android.content.Intent.migrateExtraStreamToClipData()' on a null object reference.execStartActivity

Stack trace:

at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4225)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4327)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3426)
at android.app.ActivityThread.access$1100(ActivityThread.java:229)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1821)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7331)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.content.Intent.migrateExtraStreamToClipData()' on a null object reference
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1534)
at android.app.Activity.startActivityForResult(Activity.java:4298)
at android.app.Activity.startActivityForResult(Activity.java:4245)
at android.app.Activity.startActivity(Activity.java:4582)
at android.app.Activity.startActivity(Activity.java:4550)
at net.openid.appauth.AuthorizationManagementActivity.onResume(AuthorizationManagementActivity.java)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1287)
at android.app.Activity.performResume(Activity.java:7015)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4214)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4327)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3426)
at android.app.ActivityThread.access$1100(ActivityThread.java:229)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1821)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7331)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

zoltanf avatar Mar 01 '18 09:03 zoltanf

Hmm, can't see from the code exactly what we could be doing wrong that would trigger this. From some googling around, Do you know whether the devices in question are rooted, or are devices that don't have Google Play Services installed? Searching for related errors brought that as related in some cases.

What percentage of your user base does this affect?

iainmcgin avatar Mar 02 '18 23:03 iainmcgin

Thanks for checking. It's a really low percentage of users affected (would say well bellow 1%) but it is still happening. I can't say if the users are on rooted devices, it's possible, however they do have Google Play Services since our app also requires it.

zoltanf avatar Mar 07 '18 14:03 zoltanf

Our tester has managed to reproduce this problem. This happens if the user interrupts the flow, by following steps:

  • Initiates the sign-in
  • In web view, clicks the 3 dots menu, open in chrome
  • Goes back to the app, so the auth flow is interrupted
  • At some point later goes to chrome, finishes the sign-in process and then when the app get's a callback, the app crashes.

Stacktrace from our reproduction:

Android: 8.1.0
Android Build: OPP6.171019.012
Manufacturer: LGE
Model: Nexus 5X
Thread: main-2
CrashReporter Key: 178ec6e2-b9b0-428d-908f-bbc7e8bc8f7b
Start Date: 2018-03-09T15:12:31.570Z
Date: 2018-03-09T15:21:13.380Z

java.lang.RuntimeException: Unable to resume activity {com.marktguru.android.beta/net.openid.appauth.AuthorizationManagementActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.content.Intent.migrateExtraStreamToClipData()' on a null object reference
	at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3581)
	at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3621)
	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2862)
	at android.app.ActivityThread.-wrap11(Unknown Source:0)
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
	at android.os.Handler.dispatchMessage(Handler.java:106)
	at android.os.Looper.loop(Looper.java:164)
	at android.app.ActivityThread.main(ActivityThread.java:6494)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.content.Intent.migrateExtraStreamToClipData()' on a null object reference
	at android.app.Instrumentation.execStartActivity(Instrumentation.java:1609)
	at android.app.Activity.startActivityForResult(Activity.java:4487)
	at android.app.Activity.startActivityForResult(Activity.java:4445)
	at android.app.Activity.startActivity(Activity.java:4806)
	at android.app.Activity.startActivity(Activity.java:4774)
	at net.openid.appauth.AuthorizationManagementActivity.onResume(AuthorizationManagementActivity.java:218)
	at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1355)
	at android.app.Activity.performResume(Activity.java:7107)
	at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3556)
	... 10 more

zoltanf avatar Mar 09 '18 15:03 zoltanf

Hi,

Any update on this issue? We also got a a few hundred crashes from this one with the same stacktrace.

tamaskarai avatar May 24 '18 15:05 tamaskarai

I fixed it by restore there value. Then everything is ok @Override protected void onResume() { super.onResume();

    if (savedInstanceState != null) {
        mAuthIntent = savedInstanceState.getParcelable(KEY_AUTH_INTENT);
        try {
            String authRequestJson = savedInstanceState.getString(KEY_AUTH_REQUEST, null);
            mAuthRequest = authRequestJson != null
                    ? AuthorizationRequest.jsonDeserialize(authRequestJson)
                    : null;
        } catch (JSONException ex) {
            throw new IllegalStateException("Unable to deserialize authorization request", ex);
        }
        mCompleteIntent = savedInstanceState.getParcelable(KEY_COMPLETE_INTENT);
        mCancelIntent = savedInstanceState.getParcelable(KEY_CANCEL_INTENT);
    }
    if (!mAuthorizationStarted) {
        startActivity(mAuthIntent);
        mAuthorizationStarted = true;
        return;
    }
    if (getIntent().getData() != null) {
        handleAuthorizationComplete();
    } else {
        handleAuthorizationCanceled();
    }
    finish();
}

phusung avatar May 25 '18 10:05 phusung

@phusung can you please do a pull request for this?

zoltanf avatar May 25 '18 10:05 zoltanf

@phusung I looked into it and I'm not sure that is the right way to solve this problem. There is a clear way to reproduce this problem given above. Since the problematic call happens after the auth flow is completed (interrupted), it should somehow be just completely ignored. At the moment I'm unsure how to implement this check properly on the state restoration of the AuthorizationManagementActivity.

I would still suggest you make a pull request to the project and then the code can be reviewed by someone who is a contributor.

zoltanf avatar Jun 01 '18 11:06 zoltanf

@zoltanf I have not permission to commit my code. Other way, It's fixed by adding: @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); if(savedInstanceState != null) { extractState(savedInstanceState); } }

phusung avatar Jun 04 '18 04:06 phusung

@phusung don't try to commit directly to the repo, but instead create a pull request. You can do this by forking the project and then look for instructions here.

zoltanf avatar Jun 04 '18 07:06 zoltanf

Hi, any update on this crash? About 500 users are experiencing it every day for me, and several had emailed me about it.

I can recreate the crash from @zoltanf's comment above, but I doubt real users are doing that exact flow. Any workaround or idea on the fix to this crash please?

Thanks.

richardn100 avatar Jul 16 '18 21:07 richardn100

Hi, I believe I found the cause for this crash:

It occurs when you open the authorization request twice in a row (e.g. double-clicking your app's login button which calls the AppAuth SDK twice via "performAuthorizationRequest" or "getAuthorizationRequestIntent"). The crash occurs after completing the login process and it tries to return back to your app.

I am temporarily fixing this issue by adding a boolean in my app to determine if the authorization is occurring already.

richardn100 avatar Aug 02 '18 18:08 richardn100

Hi,

I have found the same exception randomly in my project while nation wide roll out.

I found one common reason was that almost all devices have the custom ROM installed. they were not with official OS build.

as per zoltanf, all the list devices in his 1st message are having custom ROM.

Regards

s00mr0 avatar Aug 04 '18 08:08 s00mr0

@phusung will you still be opening a PR for your fix?

AesSedai101 avatar Jan 28 '19 07:01 AesSedai101

I was able to reproduce this as well using the steps provided by @phusung. I have a few reported crashes for this isolated to a couple users. I'm consuming AppAuth indirectly via react-native-app-auth. What is the progress on resolving this?

dajaffe avatar Feb 07 '19 16:02 dajaffe

I just noticed that the exact code that produces a crash in Android 7 and 8.1 works OK in Android 9.

To the people asking about progress about this issue, @phusung sent a PR but never signed the CLA so it was abandoned . I just asked on that PR to see if the solution is indeed appropriate, and if that is the case I, or anyone, can just send the same code in a new PR so we can get this merged

Fideas avatar Sep 24 '19 09:09 Fideas

We also have some users facing this crash with latest version 0.11.1. cannot reproduce with any steps listed above.

Fatal Exception: java.lang.RuntimeException: Unable to resume activity {com.***/net.openid.appauth.AuthorizationManagementActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.content.Intent.migrateExtraStreamToClipData()' on a null object reference at android.app.ActivityThread.performResumeActivity(ActivityThread.java:5083) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:5126) at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52) at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:190) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:105) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2618) at android.os.Handler.dispatchMessage(Handler.java:110) at android.os.Looper.loop(Looper.java:219) at android.app.ActivityThread.main(ActivityThread.java:8673) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1109)

Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.content.Intent.migrateExtraStreamToClipData()' on a null object reference at android.app.Instrumentation.execStartActivity(Instrumentation.java:1731) at android.app.Activity.startActivityForResult(Activity.java:5412) at com.microsoft.intune.mam.client.app.MAMActivity.startActivityForResultReal(MAMActivity.java:344) at java.lang.reflect.Method.invoke(Method.java) at com.microsoft.intune.mam.InterProxy$InterInvocationHandler.invoke(:84) at java.lang.reflect.Proxy.invoke(Proxy.java:1006) at $Proxy22.startActivityForResultReal() at com.microsoft.intune.mam.client.app.ActivityBehaviorImpl.startActivityForResult(:759) at java.lang.reflect.Method.invoke(Method.java) at com.microsoft.intune.mam.InterProxy$InterInvocationHandler.invoke(:84) at java.lang.reflect.Proxy.invoke(Proxy.java:1006) at $Proxy21.startActivityForResult() at com.microsoft.intune.mam.client.app.MAMActivity.startActivityForResult(MAMActivity.java:301) at androidx.activity.ComponentActivity.startActivityForResult(ComponentActivity.java:709) at android.app.Activity.startActivity(Activity.java:5819) at android.app.Activity.startActivity(Activity.java:5787) at net.openid.appauth.AuthorizationManagementActivity.onMAMResume(AuthorizationManagementActivity.java:228) at java.lang.reflect.Method.invoke(Method.java) at com.microsoft.intune.mam.InterProxy$InterInvocationHandler.invoke(:84) at java.lang.reflect.Proxy.invoke(Proxy.java:1006) at $Proxy22.onMAMResume() at com.microsoft.intune.mam.client.app.ActivityBehaviorImpl.onResume(:427) at java.lang.reflect.Method.invoke(Method.java) at com.microsoft.intune.mam.InterProxy$InterInvocationHandler.invoke(:84) at java.lang.reflect.Proxy.invoke(Proxy.java:1006) at $Proxy21.onResume() at com.microsoft.intune.mam.client.app.MAMActivity.onResume(MAMActivity.java:106) at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1472) at android.app.Activity.performResume(Activity.java:8351) at android.app.ActivityThread.performResumeActivity(ActivityThread.java:5073) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:5126) at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52) at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:190) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:105) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2618) at android.os.Handler.dispatchMessage(Handler.java:110) at android.os.Looper.loop(Looper.java:219) at android.app.ActivityThread.main(ActivityThread.java:8673) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1109)

jovanhuxiaowen avatar Mar 06 '24 03:03 jovanhuxiaowen