jbibik 49d929b212 [ui-compose] Eliminate race condition in PresentationState
PresentationState creation and listener registration are not an atomic operation. This happens because the LaunchedEffect which starts the listen-to-Player-Events coroutine can be pre-empted with other side effects, including the ones that change something in the Player.

rememberPresentationState function creates a PresentationState object and initialises it with the correct fresh values pulled out of the Player. The subscription to Player events with a registration of a Listener (via PresentationState.observe()) is not immediate. It *returns* immediately, but is instead scheduled to happen later, although within the same Handler message. Other LaunchedEffects could have been scheduled earlier and could take place between the button state creation and listener subscription.

This is not a problem if no changes to the player happen, but if we miss the relevant player events, we might end up with a UI that is out of sync with reality. The way to fix this is to pull the latest values out of the Player on demand upon starting to listen to Player events.

PiperOrigin-RevId: 753129489
2025-04-30 05:39:15 -07:00
..

UI module written using Jetpack Compose

Provides UI-related functionality such as Composable functions and Compose State classes. For example, the Surface for rendering media playback, UI state classes for widgets, buttons, and other interactive components.

Getting the module

The easiest way to use the module is to add it as a gradle dependency:

implementation 'androidx.media3:media3-ui-compose:1.X.X'

where 1.X.X is the version, which must match the version of the other media modules being used.

Alternatively, you can clone this GitHub project and depend on the module locally. Instructions for doing this can be found in the top level README.