Defensively prevent gif playback in background.

This commit is contained in:
Cody Henthorne
2026-02-18 11:22:08 -05:00
committed by Alex Hart
parent e0cf0808cf
commit b80dd28b40
3 changed files with 27 additions and 6 deletions

View File

@@ -159,12 +159,22 @@ public final class GiphyMp4ProjectionPlayerHolder implements Player.Listener, De
@Override
public void onPause(@NonNull LifecycleOwner owner) {
if (player.getExoPlayer() != null) {
player.getExoPlayer().stop();
player.getExoPlayer().clearMediaItems();
player.getExoPlayer().removeListener(this);
AppDependencies.getExoPlayerPool().pool(player.getExoPlayer());
returnPlayerToPool();
}
@Override
public void onStop(@NonNull LifecycleOwner owner) {
returnPlayerToPool();
}
private void returnPlayerToPool() {
ExoPlayer exoPlayer = player.getExoPlayer();
if (exoPlayer != null) {
exoPlayer.stop();
exoPlayer.clearMediaItems();
exoPlayer.removeListener(this);
player.setExoPlayer(null);
AppDependencies.getExoPlayerPool().pool(exoPlayer);
}
}

View File

@@ -109,7 +109,7 @@ class MessageDetailsFragment : FullScreenDialogFragment(), MessageDetailsAdapter
private fun initializeVideoPlayer(view: View) {
val videoContainer = view.findViewById<FrameLayout>(R.id.video_container)
val recyclerView = view.findViewById<RecyclerView>(R.id.message_details_list)
val holders = GiphyMp4ProjectionPlayerHolder.injectVideoViews(requireContext(), lifecycle, videoContainer, 1)
val holders = GiphyMp4ProjectionPlayerHolder.injectVideoViews(requireContext(), viewLifecycleOwner.lifecycle, videoContainer, 1)
val callback = GiphyMp4ProjectionRecycler(holders)
GiphyMp4PlaybackController.attach(recyclerView, callback, 1)

View File

@@ -125,6 +125,9 @@ abstract class ExoPlayerPool<T : ExoPlayer>(
fun pool(exoPlayer: T) {
val poolState = pool[exoPlayer]
if (poolState != null) {
exoPlayer.stop()
exoPlayer.clearMediaItems()
pool[exoPlayer] = poolState.copy(available = true, tag = null)
} else {
throw IllegalArgumentException("Tried to return unknown ExoPlayer to pool :: ${poolStats()}")
@@ -185,6 +188,14 @@ abstract class ExoPlayerPool<T : ExoPlayer>(
@MainThread
override fun onBackground() {
for ((player, state) in pool) {
if (!state.available && player.playWhenReady) {
Log.w(TAG, "Force-stopping orphaned playing player on background. Owner: ${state.tag}")
player.stop()
player.clearMediaItems()
}
}
val playersToRelease = pool.filter { (_, v) -> v.available }.keys
pool -= playersToRelease