-
Notifications
You must be signed in to change notification settings - Fork 309
Add stricter ExoPlayer clean-up logic
#6075
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
Add stricter ExoPlayer clean-up logic
#6075
Conversation
WalkthroughUpdates ExoPlayer/Media3 lifecycle and playback-state handling across Compose gallery, an Activity, and a Fragment: players are created on START, paused on PAUSE, save/restore playback position on STOP/START, and are explicitly released to avoid AudioMix partial wake locks; two changelog entries added. Changes
Sequence Diagram(s)sequenceDiagram
participant App as App Lifecycle
participant UI as UI (Compose / Activity / Fragment)
participant Player as ExoPlayer / Media3 Player
participant Store as Saved Playback State
App->>UI: onStart
UI->>Player: create player if null
Player->>Store: request saved position for current page
Store-->>Player: return position (default 0)
Player->>Player: setMediaItem(uri, startPosition) & prepare()
Player->>Player: set playWhenReady (autoPlay)
UI->>Player: render page using Player (if available)
App->>UI: onPause
UI->>Player: pause()
App->>UI: onStop
Player->>Store: save current position
UI->>Player: clear PlayerView reference
UI->>Player: release() and null reference
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 📜 Recent review detailsConfiguration used: Repository UI Review profile: CHILL Plan: Pro Disabled knowledge base sources:
📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.kt (1)
66-97: Fix lifecycle safety: addfinish()after invalid input, null-check URL before player creation, and preserve play state on resumeLine 77-81:
onCreate()returns withoutfinish()after validation fails, allowingonStart()to proceed with invalid data. Addfinish()aftershowPlaybackError().Line 92:
onStart()directly passes nullableurltoUri.parse(url)without null checking. This will crash if inputs were invalid butonCreate()didn't finish. Add a null guard or capture url before use.Line 108:
onStop()hard-codesautoPlay = false, losing the actual play state. When resuming, the player always resumes paused. Captureplayer?.playWhenReadybefore pausing inonPause()instead.Proposed diff
if ((type.isNullOrEmpty() && mimeType.isNullOrEmpty()) || url.isNullOrEmpty()) { logger.e { "This file can't be displayed. The TYPE or the URL are null" } showPlaybackError() + finish() return } override fun onStart() { super.onStart() // (Re)create player when returning to foreground. + val mediaUrl = url ?: return player = createPlayer() .apply { - setMediaItem(MediaItem.fromUri(Uri.parse(url)), savedPlaybackPosition) + setMediaItem(MediaItem.fromUri(Uri.parse(mediaUrl)), savedPlaybackPosition) prepare() playWhenReady = autoPlay } .also(::setupPlayerView) } override fun onPause() { super.onPause() + // Capture whether we should resume playing before pause() flips playWhenReady to false. + autoPlay = player?.playWhenReady == true player?.pause() } override fun onStop() { super.onStop() // Save playback position and release player to free wake lock. savedPlaybackPosition = player?.currentPosition ?: 0L - autoPlay = false + binding.playerView.player = null + binding.controls.player = null player?.release() player = null }stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/preview/MediaGalleryPreviewScreen.kt (1)
551-610: Add bounds check and clear stale media whenassetUrlis missing
Line 563 accesses
attachments[currentPage]without checking bounds. SinceLaunchedEffectdepends only on(currentPage, player)and notattachments, if the attachments list shrinks whilecurrentPageremains the same, this causes anIndexOutOfBoundsException.When
attachment.isVideo()is true butassetUrlis null (lines 565–576), the player retains the previous media item. The video page then renders with stale content that may not match the current page.The
onPlaybackErrorcallback captured inDisposableEffect(line 29) is not wrapped withrememberUpdatedState, so if the callback changes, the lifecycle observer retains a stale reference.Proposed fixes
+ val onPlaybackErrorState = rememberUpdatedState(onPlaybackError) LaunchedEffect(currentPage, player) { player?.let { activePlayer -> activePlayer.pause() // Pause the player when the page changes + if (currentPage !in attachments.indices) return@LaunchedEffect val attachment = attachments[currentPage] // Prepare the player with the media item if it's a video. if (attachment.isVideo()) { attachment.assetUrl?.let { assetUrl -> // Restore playback position if returning to the same page after app resume. val startPosition = savedPlaybackState ?.takeIf { (savedPage, _) => savedPage == currentPage } ?.second ?: 0L savedPlaybackState = null activePlayer.setMediaItem(MediaItem.fromUri(assetUrl), startPosition) activePlayer.prepare() - } + } ?: run { + // Prevent playing previous page's media + activePlayer.stop() + activePlayer.clearMediaItems() + } } } } DisposableEffect(lifecycleOwner, previewMode) { val observer = LifecycleEventObserver { _, event -> when (event) { Lifecycle.Event.ON_START -> { if (!previewMode && player == null) { player = createPlayer( context = context, onBuffering = { isBuffering -> showBuffering = isBuffering }, - onPlaybackError = onPlaybackError, + onPlaybackError = onPlaybackErrorState.value, ) } }
🤖 Fix all issues with AI agents
In
@stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/internal/AttachmentGalleryVideoPageFragment.kt:
- Around line 69-83: The fragment can crash when assetUrl is null and the player
lifecycle is mishandled: in onStart() use a null-safe URL (check assetUrl and
bail out or use Uri.EMPTY) before calling MediaItem.fromUri, and only
create/prepare the player when assetUrl is present (reference: onStart(),
assetUrl, createPlayer(), setMediaItem()). In onStop() clear the PlayerView's
player reference (the view set up by setupPlayerView / PlayerView) before
calling player.release() and save position into savedPlaybackPosition; then
remove the duplicate player.release() call from onDestroyView() so release
happens only once (references: onStop(), onDestroyView(), player, PlayerView,
savedPlaybackPosition, setupPlayerView).
🧹 Nitpick comments (2)
CHANGELOG.md (2)
61-63: Avoid “duplicate-looking” changelog entries; tailor wording per artifact (or centralize once).These two bullets are identical (one under
stream-chat-android-ui-components, one understream-chat-android-compose). If that’s intentional, consider slightly tailoring each line to the concrete surface (e.g., “AttachmentMediaActivity / AttachmentGalleryVideoPageFragment” vs “MediaGalleryPreviewScreen”) so it doesn’t read like an accidental duplicate. Otherwise, consider documenting it once in a shared/common section if that matches your release-note conventions.
62-62: Minor wording polish (“prevent holding” reads better).Current: “prevent keeping
AudioMixpartial wake locks” → consider “prevent holdingAudioMixpartial wake locks” (or “preventAudioMixpartial wake locks from being held after leaving the screen”).Also applies to: 74-74
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (4)
CHANGELOG.mdstream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/preview/MediaGalleryPreviewScreen.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/internal/AttachmentGalleryVideoPageFragment.kt
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{kt,kts}
📄 CodeRabbit inference engine (AGENTS.md)
Format and apply Kotlin style with Spotless (4 spaces, no wildcard imports, licence headers)
Files:
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/preview/MediaGalleryPreviewScreen.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/internal/AttachmentGalleryVideoPageFragment.kt
**/*.kt
📄 CodeRabbit inference engine (AGENTS.md)
**/*.kt: Use@OptInannotations explicitly; avoid suppressions unless documented
Document public APIs with KDoc, including thread expectations and state notes
Files:
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/preview/MediaGalleryPreviewScreen.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/internal/AttachmentGalleryVideoPageFragment.kt
**/stream-chat-android-compose/**/*.kt
📄 CodeRabbit inference engine (AGENTS.md)
**/stream-chat-android-compose/**/*.kt: Compose components should follow noun-based naming (e.g.,MessageList,ChannelListHeader)
Compose previews should use@StreamPreviewhelpers
Files:
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/preview/MediaGalleryPreviewScreen.kt
🧠 Learnings (3)
📚 Learning: 2025-12-17T15:00:07.506Z
Learnt from: CR
Repo: GetStream/stream-chat-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T15:00:07.506Z
Learning: Applies to **/stream-chat-android-compose/**/*.kt : Compose previews should use `StreamPreview` helpers
Applied to files:
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/preview/MediaGalleryPreviewScreen.kt
📚 Learning: 2025-12-17T15:00:07.506Z
Learnt from: CR
Repo: GetStream/stream-chat-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T15:00:07.506Z
Learning: Applies to **/stream-chat-android-compose/**/*Test.kt : Add Paparazzi snapshots for Compose UI regressions and run `verifyPaparazziDebug`
Applied to files:
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/preview/MediaGalleryPreviewScreen.kt
📚 Learning: 2025-12-17T15:00:07.506Z
Learnt from: CR
Repo: GetStream/stream-chat-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T15:00:07.506Z
Learning: Applies to **/stream-chat-android-ui-components/**/*Test.kt : Record Shot baselines when behaviour changes in XML kit UI tests
Applied to files:
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/internal/AttachmentGalleryVideoPageFragment.ktCHANGELOG.md
🧬 Code graph analysis (2)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/preview/MediaGalleryPreviewScreen.kt (3)
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/internal/AttachmentGalleryVideoPageFragment.kt (1)
createPlayer(225-245)stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/preview/internal/StreamMediaPlayerContent.kt (1)
createPlayer(191-213)stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/preview/internal/MediaGalleryPage.kt (1)
MediaGalleryVideoPage(292-332)
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.kt (1)
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/internal/AttachmentGalleryVideoPageFragment.kt (1)
createPlayer(225-245)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: compare-sdk-sizes / Compare SDK sizes
- GitHub Check: Build / compose apks
🔇 Additional comments (1)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/preview/MediaGalleryPreviewScreen.kt (1)
73-75: Import change only
.../io/getstream/chat/android/ui/feature/gallery/internal/AttachmentGalleryVideoPageFragment.kt
Show resolved
Hide resolved
SDK Size Comparison 📏
|
…leanup' into bug/AND-1010_improve_exoplayer_cleanup
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In
@stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.kt:
- Around line 87-97: The activity crashes because onStop dereferences binding
even when binding wasn't initialized and onStart can run after an onCreate early
return for invalid intent; fix by validating intent data early and bailing out
with finish() immediately if url/type are invalid, ensure binding is initialized
before any possible finish() (or move finish() to after binding.inflate), and
guard onStop/onStart to only touch player/binding when they are initialized
(e.g., check ::binding.isInitialized or that player != null) so
createPlayer()/setupPlayerView and player cleanup are only called when valid
data and binding exist.
- Around line 58-63: Capture the current playback intent in onPause() by setting
autoPlay = (player?.isPlaying == true) and save the playback position into
savedPlaybackPosition, remove the existing autoPlay = false assignment from
onStop(), and in onStop() clear both binding.playerView.player and
binding.controls.player (since setupPlayerView() assigns both) so the player is
properly released while preserving the user’s resume intent.
🧹 Nitpick comments (1)
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.kt (1)
58-63: PersistsavedPlaybackPositionacross config change / process death (currently it’s in-memory only).
If the Activity is recreated (rotation) or the process is killed, position resets to0L.Proposed fix
private var savedPlaybackPosition: Long = 0L private var autoPlay: Boolean = true +override fun onSaveInstanceState(outState: Bundle) { + outState.putLong("stream:savedPlaybackPosition", savedPlaybackPosition) + outState.putBoolean("stream:autoPlay", autoPlay) + super.onSaveInstanceState(outState) +} + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + + savedInstanceState?.let { + savedPlaybackPosition = it.getLong("stream:savedPlaybackPosition", 0L) + autoPlay = it.getBoolean("stream:autoPlay", true) + } ... }
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.ktstream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/internal/AttachmentGalleryVideoPageFragment.kt
🚧 Files skipped from review as they are similar to previous changes (1)
- stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/internal/AttachmentGalleryVideoPageFragment.kt
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{kt,kts}
📄 CodeRabbit inference engine (AGENTS.md)
Format and apply Kotlin style with Spotless (4 spaces, no wildcard imports, licence headers)
Files:
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.kt
**/*.kt
📄 CodeRabbit inference engine (AGENTS.md)
**/*.kt: Use@OptInannotations explicitly; avoid suppressions unless documented
Document public APIs with KDoc, including thread expectations and state notes
Files:
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.kt
🧠 Learnings (1)
📚 Learning: 2025-12-17T15:00:07.506Z
Learnt from: CR
Repo: GetStream/stream-chat-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T15:00:07.506Z
Learning: Applies to **/stream-chat-android-ui-components/**/*Test.kt : Record Shot baselines when behaviour changes in XML kit UI tests
Applied to files:
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.kt
🧬 Code graph analysis (1)
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.kt (1)
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/internal/AttachmentGalleryVideoPageFragment.kt (1)
createPlayer(224-244)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Build / compose apks
- GitHub Check: compare-sdk-sizes / Compare SDK sizes
- GitHub Check: base-android-ci / Run unit tests
- GitHub Check: base-android-ci / Run static checks
- GitHub Check: base-android-ci / Build
- GitHub Check: Detekt
...ents/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.kt
Show resolved
Hide resolved
...ents/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.kt
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.kt (1)
66-98: Add finish() call in onCreate() when invalid inputs detected to prevent crash in onStart().The issue is valid. The
urlproperty is nullable (String?), and when it's null,onCreate()returns after callingshowPlaybackError()without invokingfinish(). Sincebindingis already initialized before this validation check, the safety check inonStart()(if (!::binding.isInitialized) return) won't prevent execution. When the activity resumes,onStart()will attempt to pass the nullurltoUri.parse(url), risking a crash or undefined behavior.The proposed fix is correct:
- Add
finish()inonCreate()aftershowPlaybackError()to terminate the activity lifecycle- Add defensive null check in
onStart()as a safety measureThe androidx.media3 API (
Player.setMediaItem()andPlayer.release()) is available in the configured version.
🧹 Nitpick comments (1)
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.kt (1)
58-63: Consider persistingsavedPlaybackPositionacross process death / config change (optional).Right now
savedPlaybackPositionsurvives only while the Activity instance survives; if the process is killed you’ll restart from0L. If you want “killed by the system” restoration, persist viaonSaveInstanceState(and restore inonCreate).
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.kt
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{kt,kts}
📄 CodeRabbit inference engine (AGENTS.md)
Format and apply Kotlin style with Spotless (4 spaces, no wildcard imports, licence headers)
Files:
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.kt
**/*.kt
📄 CodeRabbit inference engine (AGENTS.md)
**/*.kt: Use@OptInannotations explicitly; avoid suppressions unless documented
Document public APIs with KDoc, including thread expectations and state notes
Files:
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.kt
🧠 Learnings (3)
📓 Common learnings
Learnt from: VelikovPetar
Repo: GetStream/stream-chat-android PR: 6075
File: stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.kt:58-63
Timestamp: 2026-01-09T11:00:38.487Z
Learning: In `AttachmentMediaActivity` (stream-chat-android-ui-components), the `autoPlay = false` in `onStop()` is intentional to maintain the original behavior where videos do not auto-resume after the activity is backgrounded.
📚 Learning: 2026-01-09T11:00:38.487Z
Learnt from: VelikovPetar
Repo: GetStream/stream-chat-android PR: 6075
File: stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.kt:58-63
Timestamp: 2026-01-09T11:00:38.487Z
Learning: In `AttachmentMediaActivity` (stream-chat-android-ui-components), the `autoPlay = false` in `onStop()` is intentional to maintain the original behavior where videos do not auto-resume after the activity is backgrounded.
Applied to files:
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.kt
📚 Learning: 2025-12-17T15:00:07.506Z
Learnt from: CR
Repo: GetStream/stream-chat-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T15:00:07.506Z
Learning: Applies to **/stream-chat-android-ui-components/**/*Test.kt : Record Shot baselines when behaviour changes in XML kit UI tests
Applied to files:
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.kt
🧬 Code graph analysis (1)
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.kt (1)
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/internal/AttachmentGalleryVideoPageFragment.kt (1)
createPlayer(224-244)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: compare-sdk-sizes / Compare SDK sizes
- GitHub Check: base-android-ci / Run unit tests
- GitHub Check: base-android-ci / Build
- GitHub Check: base-android-ci / Run static checks
- GitHub Check: Detekt
- GitHub Check: Build / compose apks
🔇 Additional comments (1)
stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/AttachmentMediaActivity.kt (1)
105-115: Cleanup flow looks correct;autoPlay = falsematches the intended “no auto-resume after background” behavior.Detaching
PlayerView/controls beforerelease()is good for avoiding leaked surfaces/listeners, and savingcurrentPositionbefore release enables your timestamp restore on the nextonStart(). Also callingautoPlay = falsehere aligns with the original behavior (per retrieved learnings).
|


🎯 Goal
Adds stricter ExoPlayer cleanup logic:
OnStartOnPauseOnStopThis is different from previously where we did the cleanup only in
OnDestroy/OnDispose. This is an optimistic fix forExoPlayerholding theAudioMixwake lock, in cases where the screen wasn't properly cleaned-up (destroyed in background, or killed by system).Additionally, introduces a
currentTimestamptracking, to ensure the video is restored at the timestamp when it was paused, to match the previous behaviour.🛠 Implementation details
ExoPlayerinOnStartExoPlayerinOnPauseOnStopsavedPlaybackPositiontracking and restoring logic🎨 UI Changes
NA
🧪 Testing
Test playing/pausing/minimizing/resuming video attachments. There should be no visible behaviour change from previously.
Summary by CodeRabbit
Bug Fixes
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.