home-assistant / home-assistant/android

Wear OS home screen occasionally crashes with concurrent modification exception

Open
#3,325 5 comments 1 reaction 0 assignees View on GitHub
3rd party bug Wear OS
Dominant language
Kotlin
Stars
3.9k
Forks
1.1k
Avg merge
1d 12h
Merged PRs (30d)
81

Description

**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`](https://github.com/home-assistant/android/blob/047abe93ba4cab1347debc5c307c55e7753880ac/wear/src/main/java/io/homeassistant/companion/android/home/MainViewModel.kt#L251) 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](https://user-images.githubusercontent.com/1634145/217905457-1aafc3d7-dc60-44fc-a84d-42886acbfd6e.png)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.