Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wear OS home screen occasionally crashes with concurrent modification exception #3325

Open
dshokouhi opened this issue Feb 9, 2023 · 4 comments · May be fixed by #4680
Open

Wear OS home screen occasionally crashes with concurrent modification exception #3325

dshokouhi opened this issue Feb 9, 2023 · 4 comments · May be fixed by #4680
Labels
bug Something isn't working Wear OS

Comments

@dshokouhi
Copy link
Member

Home Assistant Android app version(s):
latest beta for both

Android version(s):

Phone: 13
Watch: 11

Device model(s):

Pixel 7 pro
Pixel watch

Home Assistant version:

2023.1.x

Last working Home Assistant release (if known):

n/a

Description of problem, include YAML if issue is related to notifications:

Sometimes the wear OS app will load and then crash within a few seconds after showing the areas.

Companion App Logs:

2023-02-09 09:40:54.755 16190-16190 AndroidRuntime          io....stant.companion.android.debug  E  FATAL EXCEPTION: main
                                                                                                    Process: io.homeassistant.companion.android.debug, PID: 16190
                                                                                                    java.util.ConcurrentModificationException
                                                                                                    	at androidx.compose.runtime.snapshots.StateListIterator.validateModification(SnapshotStateList.kt:278)
                                                                                                    	at androidx.compose.runtime.snapshots.StateListIterator.next(SnapshotStateList.kt:257)
                                                                                                    	at io.homeassistant.companion.android.home.views.MainViewKt$MainView$1$3$1.invoke(MainView.kt:259)
                                                                                                    	at io.homeassistant.companion.android.home.views.MainViewKt$MainView$1$3$1.invoke(MainView.kt:76)
                                                                                                    	at androidx.wear.compose.material.ScalingLazyColumnKt$ScalingLazyColumn$1$1$2$1.invoke(ScalingLazyColumn.kt:425)
                                                                                                    	at androidx.wear.compose.material.ScalingLazyColumnKt$ScalingLazyColumn$1$1$2$1.invoke(ScalingLazyColumn.kt:410)
                                                                                                    	at androidx.compose.foundation.lazy.LazyListItemProviderKt$rememberLazyListItemProvider$1$itemProviderState$1.invoke(LazyListItemProvider.kt:53)
                                                                                                    	at androidx.compose.foundation.lazy.LazyListItemProviderKt$rememberLazyListItemProvider$1$itemProviderState$1.invoke(LazyListItemProvider.kt:52)
                                                                                                    	at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2139)
                                                                                                    	at androidx.compose.runtime.DerivedSnapshotState.currentRecord(DerivedState.kt:161)
                                                                                                    	at androidx.compose.runtime.DerivedSnapshotState.getCurrentValue(DerivedState.kt:231)
                                                                                                    	at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.recordInvalidation(SnapshotStateObserver.kt:419)
                                                                                                    	at androidx.compose.runtime.snapshots.SnapshotStateObserver$applyObserver$1.invoke(SnapshotStateObserver.kt:42)
                                                                                                    	at androidx.compose.runtime.snapshots.SnapshotStateObserver$applyObserver$1.invoke(SnapshotStateObserver.kt:38)
                                                                                                    	at androidx.compose.runtime.snapshots.MutableSnapshot.apply(Snapshot.kt:748)
                                                                                                    	at androidx.compose.runtime.Recomposer.applyAndCheck(Recomposer.kt:1108)
                                                                                                    	at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:1476)
                                                                                                    	at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:125)
                                                                                                    	at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:534)
                                                                                                    	at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:503)
                                                                                                    	at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:34)
                                                                                                    	at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.android.kt:109)
                                                                                                    	at androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch(AndroidUiDispatcher.android.kt:41)
                                                                                                    	at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69)
                                                                                                    	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:970)
                                                                                                    	at android.view.Choreographer.doCallbacks(Choreographer.java:796)
                                                                                                    	at android.view.Choreographer.doFrame(Choreographer.java:727)
                                                                                                    	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:7651)
                                                                                                    	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)
                                                                                                    	Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [androidx.compose.runtime.PausableMonotonicFrameClock@21b070f, androidx.compose.ui.platform.MotionDurationScaleImpl@642c39c, StandaloneCoroutine{Cancelling}@8af01a5, AndroidUiDispatcher@fa2297a]

Screenshot or video of problem:

Additional information:

This does not occur when Show Only Favorites is enabled. The problem area is suspected to be in updateEntityDomains as that method is not used as often when the show only favorites option is enabled.

Using androids layout inspector I can see the recomposition counts for everything increases anytime there is any update which might be a bit inefficient

image

@dshokouhi dshokouhi added bug Something isn't working Wear OS labels Feb 9, 2023
@dshokouhi
Copy link
Member Author

Looks like this error is also in the play console. We have a few thousand users getting impacted by this. first appearance of this error is Beta 3044

@dshokouhi
Copy link
Member Author

Most recent crash log

Exception java.util.ConcurrentModificationException:
  at androidx.compose.runtime.snapshots.StateListIterator.validateModification (SnapshotStateList.kt:295)
  at androidx.compose.runtime.snapshots.StateListIterator.next (SnapshotStateList.kt:274)
  at io.homeassistant.companion.android.home.views.MainViewKt$MainView$1$3$1.invoke (MainView.kt:382)
  at io.homeassistant.companion.android.home.views.MainViewKt$MainView$1$3$1.invoke (MainView.kt:77)
  at androidx.wear.compose.material.ScalingLazyColumnKt$ScalingLazyColumn$1$1$2$1.invoke (ScalingLazyColumn.kt:425)
  at androidx.wear.compose.material.ScalingLazyColumnKt$ScalingLazyColumn$1$1$2$1.invoke (ScalingLazyColumn.kt:410)
  at androidx.compose.foundation.lazy.LazyListItemProviderKt$rememberLazyListItemProvider$1$itemProviderState$1.invoke (LazyListItemProvider.kt:54)
  at androidx.compose.foundation.lazy.LazyListItemProviderKt$rememberLazyListItemProvider$1$itemProviderState$1.invoke (LazyListItemProvider.kt:53)
  at androidx.compose.runtime.snapshots.Snapshot$Companion.observe (Snapshot.kt:2200)
  at androidx.compose.runtime.DerivedSnapshotState.currentRecord (DerivedState.kt:161)
  at androidx.compose.runtime.DerivedSnapshotState.getCurrentValue (DerivedState.kt:231)
  at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.recordInvalidation (SnapshotStateObserver.kt:523)
  at androidx.compose.runtime.snapshots.SnapshotStateObserver.drainChanges (SnapshotStateObserver.kt:66)
  at androidx.compose.runtime.snapshots.SnapshotStateObserver.access$drainChanges (SnapshotStateObserver.kt:38)
  at androidx.compose.runtime.snapshots.SnapshotStateObserver$applyObserver$1.invoke (SnapshotStateObserver.kt:45)
  at androidx.compose.runtime.snapshots.SnapshotStateObserver$applyObserver$1.invoke (SnapshotStateObserver.kt:43)
  at androidx.compose.runtime.snapshots.MutableSnapshot.apply (Snapshot.kt:748)
  at androidx.compose.runtime.Recomposer.applyAndCheck (Recomposer.kt:1124)
  at androidx.compose.runtime.Recomposer.performRecompose (Recomposer.kt:1483)
  at androidx.compose.runtime.Recomposer.access$performRecompose (Recomposer.kt:124)
  at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke (Recomposer.kt:541)
  at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke (Recomposer.kt:510)
  at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame (AndroidUiFrameClock.android.kt:34)
  at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch (AndroidUiDispatcher.android.kt:109)
  at androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch (AndroidUiDispatcher.android.kt:41)
  at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame (AndroidUiDispatcher.android.kt:69)
  at android.view.Choreographer$CallbackRecord.run (Choreographer.java:996)
  at android.view.Choreographer.doCallbacks (Choreographer.java:796)
  at android.view.Choreographer.doFrame (Choreographer.java:727)
  at android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:983)
  at android.os.Handler.handleCallback (Handler.java:938)
  at android.os.Handler.dispatchMessage (Handler.java:99)
  at android.os.Looper.loop (Looper.java:246)
  at android.app.ActivityThread.main (ActivityThread.java:7690)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:593)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:995)

@slovdahl
Copy link
Contributor

Happened for me in the development environment too:

2023-08-17 22:15:21.478 21395-21395 AndroidRuntime          io....stant.companion.android.debug  E  FATAL EXCEPTION: main
                                                                                                    Process: io.homeassistant.companion.android.debug, PID: 21395
                                                                                                    java.util.ConcurrentModificationException
                                                                                                    	at androidx.compose.runtime.snapshots.StateListIterator.validateModification(SnapshotStateList.kt:295)
                                                                                                    	at androidx.compose.runtime.snapshots.StateListIterator.next(SnapshotStateList.kt:274)
                                                                                                    	at io.homeassistant.companion.android.home.views.MainViewKt$MainView$1$3$1.invoke(MainView.kt:263)
                                                                                                    	at io.homeassistant.companion.android.home.views.MainViewKt$MainView$1$3$1.invoke(MainView.kt:77)
                                                                                                    	at androidx.wear.compose.material.ScalingLazyColumnKt$ScalingLazyColumn$1$1$2$1.invoke(ScalingLazyColumn.kt:425)
                                                                                                    	at androidx.wear.compose.material.ScalingLazyColumnKt$ScalingLazyColumn$1$1$2$1.invoke(ScalingLazyColumn.kt:410)
                                                                                                    	at androidx.compose.foundation.lazy.LazyListItemProviderKt$rememberLazyListItemProvider$1$itemProviderState$1.invoke(LazyListItemProvider.kt:54)
                                                                                                    	at androidx.compose.foundation.lazy.LazyListItemProviderKt$rememberLazyListItemProvider$1$itemProviderState$1.invoke(LazyListItemProvider.kt:53)
                                                                                                    	at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2200)
                                                                                                    	at androidx.compose.runtime.DerivedSnapshotState.currentRecord(DerivedState.kt:161)
                                                                                                    	at androidx.compose.runtime.DerivedSnapshotState.getCurrentValue(DerivedState.kt:231)
                                                                                                    	at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.recordInvalidation(SnapshotStateObserver.kt:523)
                                                                                                    	at androidx.compose.runtime.snapshots.SnapshotStateObserver.drainChanges(SnapshotStateObserver.kt:66)
                                                                                                    	at androidx.compose.runtime.snapshots.SnapshotStateObserver.access$drainChanges(SnapshotStateObserver.kt:38)
                                                                                                    	at androidx.compose.runtime.snapshots.SnapshotStateObserver$applyObserver$1.invoke(SnapshotStateObserver.kt:45)
                                                                                                    	at androidx.compose.runtime.snapshots.SnapshotStateObserver$applyObserver$1.invoke(SnapshotStateObserver.kt:43)
                                                                                                    	at androidx.compose.runtime.snapshots.SnapshotKt.advanceGlobalSnapshot(Snapshot.kt:1768)
                                                                                                    	at androidx.compose.runtime.snapshots.SnapshotKt.advanceGlobalSnapshot(Snapshot.kt:1779)
                                                                                                    	at androidx.compose.runtime.snapshots.SnapshotKt.access$advanceGlobalSnapshot(Snapshot.kt:1)
                                                                                                    	at androidx.compose.runtime.snapshots.GlobalSnapshot.notifyObjectsInitialized$runtime_release(Snapshot.kt:1337)
                                                                                                    	at androidx.compose.runtime.snapshots.Snapshot$Companion.notifyObjectsInitialized(Snapshot.kt:551)
                                                                                                    	at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:641)
                                                                                                    	at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:510)
                                                                                                    	at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:34)
                                                                                                    	at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.android.kt:109)
                                                                                                    	at androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch(AndroidUiDispatcher.android.kt:41)
                                                                                                    	at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69)
                                                                                                    	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:996)
                                                                                                    	at android.view.Choreographer.doCallbacks(Choreographer.java:796)
                                                                                                    	at android.view.Choreographer.doFrame(Choreographer.java:727)
                                                                                                    	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:983)
                                                                                                    	at android.os.Handler.handleCallback(Handler.java:938)
                                                                                                    	at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                                                    	at android.os.Looper.loop(Looper.java:246)
                                                                                                    	at android.app.ActivityThread.main(ActivityThread.java:7690)
                                                                                                    	at java.lang.reflect.Method.invoke(Native Method)
                                                                                                    	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593)
                                                                                                    	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:995)
                                                                                                    	Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [androidx.compose.runtime.PausableMonotonicFrameClock@8127c81, androidx.compose.ui.platform.MotionDurationScaleImpl@e948126, StandaloneCoroutine{Cancelling}@df8c167, AndroidUiDispatcher@a81eb14]

@JBou
Copy link

JBou commented Sep 28, 2023

This problem is already reported in the compose issue tracker:
https://issuetracker.google.com/issues/272334463

Maybe you can add a +1 vote there in the upper right, or even better add a comment that it affects this app and a few thousand users, so the issue gets a bit more attention and the suggested solution gets implemented.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Wear OS
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants