Closed idomo1 closed 2 years ago
@idomo1 what Android version(s) are you seeing this on?
Reproduced it myself on an Android 7 real device and emulators for Android 7, 7.1, 8, 8.1, 9, 10, 11 and 12 on SDK v.1.2.3. For Android 10+ I could only seem to get it to crash on sign out for whatever reason. Crash logs from production show it happening on Android 10, 11 and 12, though that's with SDK v1.2.2.
Thanks for the report. I'm able to reproduce.
The SDK is not intended to be called when your application is in the background. Before calling signIn, ensure your activity is in the foreground by using something along the lines of lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)
.
I've been working on a lot of fixes in this area for our new SDK. The new SDK will do the right thing for all of these cases to put less burden on you as an app developer.
@JayNewstrom I think you've misunderstood. The activity is started when the SDK is called, but because of the 2-3 second delay between calling WebAuthClient.signIn
and the custom tab opening, there is time for the user to background the app and cause the crash. There isn't anyway that I can see of preventing this from the SDK user side.
I see. This is one of the scenarios I fixed in the new mobile SDK. I'll see if there's anything I can do here.
Thanks for the clarification.
It looks like the best we can do in this SDK (due to some internal limitations) is to return a cancelled result if the activity has been backgrounded/destroyed.
I'll see if I can make a PR for it.
That's a lot better than crashing, thanks!
@idomo1 opened the PR for the fix here: https://github.com/okta/okta-oidc-android/pull/316
Hello, we are using version 1.3.2 and we are seeing the following crash. We noticed that your PR for the fix has been merged in version 1.2.5. Are any of you aware if this crash is still occurring?
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at androidx.fragment.app.FragmentManager.checkStateLoss(FragmentManager.java:1610)
at androidx.fragment.app.FragmentManager.enqueueAction(FragmentManager.java:1650)
at androidx.fragment.app.BackStackRecord.commitInternal(BackStackRecord.java:341)
at androidx.fragment.app.BackStackRecord.commit(BackStackRecord.java:306)
at com.okta.oidc.OktaResultFragment.addLogoutFragment(OktaResultFragment.java:65)
at com.okta.oidc.clients.web.SyncWebAuthClientImpl.lambda$startSignOut$4(SyncWebAuthClientImpl.java:336)
at com.okta.oidc.clients.web.SyncWebAuthClientImpl.$r8$lambda$9xGAYUir3zQW6WeNxzc89L77keM(SyncWebAuthClientImpl.java)
at com.okta.oidc.clients.web.SyncWebAuthClientImpl$$InternalSyntheticLambda$1$4f21a8c7c9ad1cac09d3351f8ce878563a9e121d919d104677a8d21e37f4789b$0.run$bridge(SyncWebAuthClientImpl.java:30)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8663)
at java.lang.reflect.Method.invoke(Method.java:-2)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
Thread 2:
0 dalvik.system.VMStack.getThreadStackTrace(VMStack.java:-2)
1 java.lang.Thread.getStackTrace(Thread.java:1841)
2 java.lang.Thread.getAllStackTraces(Thread.java:1909)
3 com.microsoft.appcenter.crashes.Crashes.y
4 t8.d.uncaughtException
5 java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1073)
6 java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1068)
7 java.lang.Thread.dispatchUncaughtException(Thread.java:2306)
Thread 31:
0 java.lang.Object.wait(Object.java:-2)
1 java.lang.Object.wait(Object.java:442)
2 java.lang.Object.wait(Object.java:568)
3 java.lang.Daemons$ReferenceQueueDaemon.runInternal(Daemons.java:232)
4 java.lang.Daemons$Daemon.run(Daemons.java:140)
5 java.lang.Thread.run(Thread.java:1012)
Thread 32:
0 java.lang.Object.wait(Object.java:-2)
1 java.lang.Object.wait(Object.java:442)
2 java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:203)
3 java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:224)
4 java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:300)
5 java.lang.Daemons$Daemon.run(Daemons.java:140)
6 java.lang.Thread.run(Thread.java:1012)
Thread 33:
0 java.lang.Object.wait(Object.java:-2)
1 java.lang.Object.wait(Object.java:442)
2 java.lang.Object.wait(Object.java:568)
3 java.lang.Daemons$FinalizerWatchdogDaemon.sleepUntilNeeded(Daemons.java:385)
4 java.lang.Daemons$FinalizerWatchdogDaemon.runInternal(Daemons.java:365)
5 java.lang.Daemons$Daemon.run(Daemons.java:140)
6 java.lang.Thread.run(Thread.java:1012)
Thread 39:
0 java.lang.Object.wait(Object.java:-2)
1 java.lang.Object.wait(Object.java:442)
2 java.lang.Object.wait(Object.java:568)
3 java.util.TimerThread.mainLoop(Timer.java:534)
4 java.util.TimerThread.run(Timer.java:513)
Thread 41:
0 jdk.internal.misc.Unsafe.park(Unsafe.java:-2)
1 java.util.concurrent.locks.LockSupport.park(LockSupport.java:194)
2 java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2081)
3 java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:433)
4 java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1063)
5 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)
6 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
7 java.lang.Thread.run(Thread.java:1012)
Thread 42:
0 android.os.MessageQueue.nativePollOnce(MessageQueue.java:-2)
1 android.os.MessageQueue.next(MessageQueue.java:335)
2 android.os.Looper.loopOnce(Looper.java:186)
3 android.os.Looper.loop(Looper.java:313)
4 android.os.HandlerThread.run(HandlerThread.java:67)
Thread 43:
0 android.os.MessageQueue.nativePollOnce(MessageQueue.java:-2)
1 android.os.MessageQueue.next(MessageQueue.java:335)
2 android.os.Looper.loopOnce(Looper.java:186)
3 android.os.Looper.loop(Looper.java:313)
4 android.os.HandlerThread.run(HandlerThread.java:67)
Thread 44:
0 android.os.MessageQueue.nativePollOnce(MessageQueue.java:-2)
1 android.os.MessageQueue.next(MessageQueue.java:335)
2 android.os.Looper.loopOnce(Looper.java:186)
3 android.os.Looper.loop(Looper.java:313)
4 android.os.HandlerThread.run(HandlerThread.java:67)
Thread 46:
0 android.os.MessageQueue.nativePollOnce(MessageQueue.java:-2)
1 android.os.MessageQueue.next(MessageQueue.java:335)
2 android.os.Looper.loopOnce(Looper.java:186)
3 android.os.Looper.loop(Looper.java:313)
4 android.os.HandlerThread.run(HandlerThread.java:67)
Thread 48:
0 android.os.MessageQueue.nativePollOnce(MessageQueue.java:-2)
1 android.os.MessageQueue.next(MessageQueue.java:335)
2 android.os.Looper.loopOnce(Looper.java:186)
3 android.os.Looper.loop(Looper.java:313)
4 android.os.HandlerThread.run(HandlerThread.java:67)
Thread 49:
0 jdk.internal.misc.Unsafe.park(Unsafe.java:-2)
1 java.util.concurrent.locks.LockSupport.park(LockSupport.java:194)
2 java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2081)
3 java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:433)
4 java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1063)
5 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)
6 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
7 java.lang.Thread.run(Thread.java:1012)
Thread 52:
0 java.net.SocketInputStream.socketRead0(SocketInputStream.java:-2)
1 java.net.SocketInputStream.socketRead(SocketInputStream.java:118)
2 java.net.SocketInputStream.read(SocketInputStream.java:173)
3 java.net.SocketInputStream.read(SocketInputStream.java:143)
4 com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readFromSocket(ConscryptEngineSocket.java:945)
5 com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:909)
6 com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readUntilDataAvailable(ConscryptEngineSocket.java:824)
7 com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.read(ConscryptEngineSocket.java:797)
8 com.android.okhttp.okio.Okio$2.read(Okio.java:138)
9 com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:213)
10 com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:307)
11 com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:301)
12 com.android.okhttp.okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:197)
13 com.android.okhttp.internal.http.Http1xStream.readResponse(Http1xStream.java:188)
14 com.android.okhttp.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:129)
15 com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:750)
16 com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:622)
17 com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:475)
18 com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:411)
19 com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:542)
20 com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:106)
21 com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:30)
22 y8.c.a
23 y8.c.doInBackground
24 android.os.AsyncTask$3.call(AsyncTask.java:394)
25 java.util.concurrent.FutureTask.run(FutureTask.java:264)
26 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
27 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
28 java.lang.Thread.run(Thread.java:1012)
Thread 53:
0 java.lang.Object.wait(Object.java:-2)
1 com.android.okhttp.ConnectionPool$1.run(ConnectionPool.java:106)
2 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
3 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
4 java.lang.Thread.run(Thread.java:1012)
Thread 54:
0 java.net.SocketInputStream.socketRead0(SocketInputStream.java:-2)
1 java.net.SocketInputStream.socketRead(SocketInputStream.java:118)
2 java.net.SocketInputStream.read(SocketInputStream.java:173)
3 java.net.SocketInputStream.read(SocketInputStream.java:143)
4 com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readFromSocket(ConscryptEngineSocket.java:945)
5 com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:909)
6 com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readUntilDataAvailable(ConscryptEngineSocket.java:824)
7 com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.read(ConscryptEngineSocket.java:797)
8 com.android.okhttp.okio.Okio$2.read(Okio.java:138)
9 com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:213)
10 com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:307)
11 com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:301)
12 com.android.okhttp.okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:197)
13 com.android.okhttp.internal.http.Http1xStream.readResponse(Http1xStream.java:188)
14 com.android.okhttp.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:129)
15 com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:750)
16 com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:622)
17 com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:475)
18 com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:411)
19 com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:542)
20 com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:106)
21 com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:30)
22 y8.c.a
23 y8.c.doInBackground
24 android.os.AsyncTask$3.call(AsyncTask.java:394)
25 java.util.concurrent.FutureTask.run(FutureTask.java:264)
26 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
27 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
28 java.lang.Thread.run(Thread.java:1012)
Thread 55:
0 java.net.SocketInputStream.socketRead0(SocketInputStream.java:-2)
1 java.net.SocketInputStream.socketRead(SocketInputStream.java:118)
2 java.net.SocketInputStream.read(SocketInputStream.java:173)
3 java.net.SocketInputStream.read(SocketInputStream.java:143)
4 com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readFromSocket(ConscryptEngineSocket.java:945)
5 com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:909)
6 com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readUntilDataAvailable(ConscryptEngineSocket.java:824)
7 com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.read(ConscryptEngineSocket.java:797)
8 com.android.okhttp.okio.Okio$2.read(Okio.java:138)
9 com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:213)
10 com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:307)
11 com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:301)
12 com.android.okhttp.okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:197)
13 com.android.okhttp.internal.http.Http1xStream.readResponse(Http1xStream.java:188)
14 com.android.okhttp.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:129)
15 com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:750)
16 com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:622)
17 com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:475)
18 com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:411)
19 com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:542)
20 com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:106)
21 com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:30)
22 y8.c.a
23 y8.c.doInBackground
24 android.os.AsyncTask$3.call(AsyncTask.java:394)
25 java.util.concurrent.FutureTask.run(FutureTask.java:264)
26 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
27 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
28 java.lang.Thread.run(Thread.java:1012)
Thread 56:
0 java.lang.Object.wait(Object.java:-2)
1 com.android.okhttp.okio.AsyncTimeout.awaitTimeout(AsyncTimeout.java:325)
2 com.android.okhttp.okio.AsyncTimeout.access$000(AsyncTimeout.java:42)
3 com.android.okhttp.okio.AsyncTimeout$Watchdog.run(AsyncTimeout.java:288)
Thread 57:
0 jdk.internal.misc.Unsafe.park(Unsafe.java:-2)
1 java.util.concurrent.locks.LockSupport.park(LockSupport.java:194)
2 java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:885)
3 java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1039)
4 java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1345)
5 java.util.concurrent.CountDownLatch.await(CountDownLatch.java:232)
6 com.okta.oidc.clients.web.SyncWebAuthClientImpl.startSignOut
7 com.okta.oidc.clients.web.SyncWebAuthClientImpl.signOutOfOkta
8 com.okta.oidc.clients.web.WebAuthClientImpl.lambda$signOutOfOkta$8
9 com.okta.oidc.clients.web.WebAuthClientImpl.i
10 com.okta.oidc.clients.web.g.run
11 java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:463)
12 java.util.concurrent.FutureTask.run(FutureTask.java:264)
13 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
14 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
15 java.lang.Thread.run(Thread.java:1012)
Describe the bug?
If the app is backgrounded between initiating
WebAuthClient.signIn/signout
and the web client opening, there is a crash.Sign out
Sign in
Note that calling
WebAuthClient.cancel()
inonStop
isn't a solution, sinceonStop
is called as well when the login/logout web client is launched.What is expected to happen?
The SDK should catch the error and pass it to
ResultCallback.onError
What is the actual behavior?
A fatal exception
Reproduction Steps?
WebAuthClient.signIn/signOut
Additional Information?
This is similar to this issue https://github.com/okta/okta-oidc-android/issues/263, but the fix applied makes no difference.
SDK Version
1.2.3
Build Information
No response