AppAuth-Android
AppAuth-Android copied to clipboard
NPE on AuthorizationManagementActivity.onResume (from Android framework?)
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)
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?
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.
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
Hi,
Any update on this issue? We also got a a few hundred crashes from this one with the same stacktrace.
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 can you please do a pull request for this?
@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 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 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.
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.
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.
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
@phusung will you still be opening a PR for your fix?
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?
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
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)