Skip to content

Conversation

@RBusarow
Copy link
Contributor

fixes #570

@RBusarow RBusarow requested review from a team and zach-klippenstein as code owners January 19, 2022 15:58
@CLAassistant
Copy link

CLAassistant commented Jan 19, 2022

CLA assistant check
All committers have signed the CLA.

Copy link
Contributor

@steve-the-edwards steve-the-edwards left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this just pulling this fix into main from the ui-update branch?

// We're only allowed to restore from an INITIALIZED state, but this callback can also be
// invoked while the owner is already CREATED.
// https://github.com/square/workflow-kotlin/issues/570
?.takeIf { it.lifecycle.currentState == Lifecycle.State.INITIALIZED }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @rjrjr originally tried this solution but decided against it? I can't remember now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it was just a matter of being able to reproduce the bug first.

If this line is removed, everything still passes except for the new test, even if you call scenario.recreate(), or change orientation or something.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, I feel fine about the fix, just didn't want to do it w/o proof.

it.nestedTestView().viewState = "some state"
}

// Recreating the activity sends one ONE_CREATE event,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤩

@rjrjr
Copy link
Collaborator

rjrjr commented Jan 19, 2022

@RBusarow what changed in those last couple of force pushes?

@RBusarow
Copy link
Contributor Author

@RBusarow what changed in those last couple of force pushes?

I fixed this typo:
image

And I added that same .api file change.

@RBusarow RBusarow merged commit 1882f1d into square:main Jan 20, 2022
@rjrjr
Copy link
Collaborator

rjrjr commented Feb 8, 2022

Debugging a problem where a ComposeRendering in a dialog is crashing in a pretty similar way:

    java.lang.IllegalStateException: You can consumeRestoredStateForKey only after super.onCreate of corresponding component
        at androidx.savedstate.SavedStateRegistry.consumeRestoredStateForKey(SavedStateRegistry.java:77)
        at androidx.compose.ui.platform.DisposableSaveableStateRegistry_androidKt.DisposableSaveableStateRegistry(DisposableSaveableStateRegistry.android.kt:75)
        at androidx.compose.ui.platform.DisposableSaveableStateRegistry_androidKt.DisposableSaveableStateRegistry(DisposableSaveableStateRegistry.android.kt:54)
        at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt.ProvideAndroidCompositionLocals(AndroidCompositionLocals.android.kt:105)
        at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$3.invoke(Wrapper.android.kt:157)
        at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$3.invoke(Wrapper.android.kt:156)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
        at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
        at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(Wrapper.android.kt:156)
        at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(Wrapper.android.kt:140)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
        at androidx.compose.runtime.ComposerKt.invokeComposable(Composer.kt:3337)
        at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:2582)
        at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:2571)
        at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:247)
        at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source:1)
        at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:2571)
        at androidx.compose.runtime.ComposerImpl.composeContent$runtime_release(Composer.kt:2522)
        at androidx.compose.runtime.CompositionImpl.composeContent(Composition.kt:478)
        at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:748)
        at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:433)
        at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:140)
        at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:131)
        at androidx.compose.ui.platform.AndroidComposeView.setOnViewTreeOwnersAvailable(AndroidComposeView.android.kt:907)
        at androidx.compose.ui.platform.WrappedComposition.setContent(Wrapper.android.kt:131)
        at androidx.compose.ui.platform.WrappedComposition.onStateChanged(Wrapper.android.kt:182)
        at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:354)
        at androidx.lifecycle.LifecycleRegistry.addObserver(LifecycleRegistry.java:196)
        at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:138)
        at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:131)
        at androidx.compose.ui.platform.AndroidComposeView.onAttachedToWindow(AndroidComposeView.android.kt:994)
        at android.view.View.dispatchAttachedToWindow(View.java:20479)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3489)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496)
E/AndroidRuntime:     at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2417)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1952)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8171)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:972)
        at android.view.Choreographer.doCallbacks(Choreographer.java:796)
        at android.view.Choreographer.doFrame(Choreographer.java:731)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

I'm starting to think that the real problem here is that RealWorkflowLifecycleOwner is too eager to reflect its parent's state. It gets to RESUMED long before restore happens, and so we crash.

Wondering if we should link it and StateRegistryAggregator, and stay in CREATED until a restore happens.

Update: not so much "similar" as maybe related. Like b/c we're squelching the restore call, downstream we puke b/c of trying to consume something that never was restored.

@rjrjr
Copy link
Collaborator

rjrjr commented Feb 8, 2022

@RBusarow When I revert everything but the test from this, the test still passes. Do you remember if there was any particular AVD or API level you were using to reproduce the failure?

@RBusarow
Copy link
Contributor Author

RBusarow commented Feb 8, 2022

@rjrjr I just tested against a 31 "Pixel 5" AVD and with just the INITIALIZED check commented out it failed. I then ran it against API 29 and it passed.

@rjrjr
Copy link
Collaborator

rjrjr commented Feb 8, 2022

Perfect, thanks.

I don't know that these two issues are actually related, still debugging.

@rjrjr
Copy link
Collaborator

rjrjr commented Feb 9, 2022

Seems unrelated, just a missing call to restoreRegistryControllerIfReady in ModalContainer. Phew!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Occasional "IllegalStateException: Restarter must be created only during owner's initialization stage"

4 participants