diff --git a/packages/camera/camera_android_camerax/CHANGELOG.md b/packages/camera/camera_android_camerax/CHANGELOG.md index 913a5eeadbb..2818f35b8c8 100644 --- a/packages/camera/camera_android_camerax/CHANGELOG.md +++ b/packages/camera/camera_android_camerax/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.17+1 + +* Replaces deprecated `onSurfaceDestroyed` with `onSurfaceCleanup`. + ## 0.6.17 * Replaces `BroadcastReceiver` usage with an `OrientationEventListener` to detect changes in device diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/PreviewProxyApi.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/PreviewProxyApi.java index 65d8f8a37a5..8fedd79f245 100644 --- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/PreviewProxyApi.java +++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/PreviewProxyApi.java @@ -109,10 +109,7 @@ public void onSurfaceAvailable() { } @Override - // TODO(bparrishMines): Replace with onSurfaceCleanup once available on stable. See - // https://github.com/flutter/flutter/issues/161256. - @SuppressWarnings({"deprecation", "removal"}) - public void onSurfaceDestroyed() { + public void onSurfaceCleanup() { // Invalidate the SurfaceRequest so that CameraX knows to to make a new request // for a surface. request.invalidate(); diff --git a/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/PreviewTest.java b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/PreviewTest.java index a94f6f288ad..5c3f3578a24 100644 --- a/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/PreviewTest.java +++ b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/PreviewTest.java @@ -113,8 +113,8 @@ TextureRegistry getTextureRegistry() { final TextureRegistry.SurfaceProducer.Callback callback = callbackCaptor.getValue(); - // Verify callback's onSurfaceDestroyed invalidates SurfaceRequest. - simulateSurfaceDestruction(callback); + // Verify callback's onSurfaceCleanup invalidates SurfaceRequest. + simulateSurfaceCleanup(callback); verify(mockSurfaceRequest).invalidate(); reset(mockSurfaceRequest); @@ -286,7 +286,7 @@ TextureRegistry getTextureRegistry() { // see https://github.com/flutter/flutter/issues/16125. This separate method only exists to scope // the suppression. @SuppressWarnings({"deprecation", "removal"}) - void simulateSurfaceDestruction(TextureRegistry.SurfaceProducer.Callback producerLifecycle) { - producerLifecycle.onSurfaceDestroyed(); + void simulateSurfaceCleanup(TextureRegistry.SurfaceProducer.Callback producerLifecycle) { + producerLifecycle.onSurfaceCleanup(); } } diff --git a/packages/camera/camera_android_camerax/pubspec.yaml b/packages/camera/camera_android_camerax/pubspec.yaml index dbd2efbfd2a..329913bd16a 100644 --- a/packages/camera/camera_android_camerax/pubspec.yaml +++ b/packages/camera/camera_android_camerax/pubspec.yaml @@ -2,7 +2,7 @@ name: camera_android_camerax description: Android implementation of the camera plugin using the CameraX library. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android_camerax issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.6.17 +version: 0.6.17+1 environment: sdk: ^3.7.0 diff --git a/packages/video_player/video_player_android/CHANGELOG.md b/packages/video_player/video_player_android/CHANGELOG.md index d7e79f16cdb..bda736d6da4 100644 --- a/packages/video_player/video_player_android/CHANGELOG.md +++ b/packages/video_player/video_player_android/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.8.5 + +* Replaces deprecated `onSurfaceDestroyed` with `onSurfaceCleanup`. +* Restores background playback support. + ## 2.8.4 * Fixes incorrect width/height swap ([bug](https://github.com/flutter/flutter/issues/166097)). The swap was originally required for the uncorrected width/height of `Format` but was mistakenly retained after [switching to `VideoSize`](https://github.com/flutter/packages/pull/6535), which already accounts for rotation. diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerEventListener.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerEventListener.java index e96eca8b3a7..0ca4f867f5f 100644 --- a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerEventListener.java +++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerEventListener.java @@ -11,7 +11,7 @@ public abstract class ExoPlayerEventListener implements Player.Listener { private boolean isBuffering = false; - private boolean isInitialized; + private boolean isInitialized = false; protected final ExoPlayer exoPlayer; protected final VideoPlayerCallbacks events; @@ -42,10 +42,9 @@ public int getDegrees() { } public ExoPlayerEventListener( - @NonNull ExoPlayer exoPlayer, @NonNull VideoPlayerCallbacks events, boolean initialized) { + @NonNull ExoPlayer exoPlayer, @NonNull VideoPlayerCallbacks events) { this.exoPlayer = exoPlayer; this.events = events; - this.isInitialized = initialized; } private void setBuffering(boolean buffering) { diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerState.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerState.java deleted file mode 100644 index e0e9babaa02..00000000000 --- a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerState.java +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package io.flutter.plugins.videoplayer; - -import androidx.annotation.NonNull; -import androidx.media3.common.PlaybackParameters; -import androidx.media3.exoplayer.ExoPlayer; - -/** - * Internal state representing an {@link ExoPlayer} instance at a snapshot in time. - * - *

During the Android application lifecycle, the underlying {@link android.view.Surface} being - * rendered to by the player can be destroyed when the application is in the background and memory - * is reclaimed. Upon resume, the player will need to be recreated, but start again at the - * previous point (and settings). - */ -public final class ExoPlayerState { - /** - * Saves a representation of the current state of the player at the current point in time. - * - *

The inverse of this operation is {@link #restore(ExoPlayer)}. - * - * @param exoPlayer the active player instance. - * @return an opaque object representing the state. - */ - @NonNull - public static ExoPlayerState save(@NonNull ExoPlayer exoPlayer) { - return new ExoPlayerState( - /* position= */ exoPlayer.getCurrentPosition(), - /* repeatMode= */ exoPlayer.getRepeatMode(), - /* volume= */ exoPlayer.getVolume(), - /* playbackParameters= */ exoPlayer.getPlaybackParameters()); - } - - private ExoPlayerState( - long position, int repeatMode, float volume, PlaybackParameters playbackParameters) { - this.position = position; - this.repeatMode = repeatMode; - this.volume = volume; - this.playbackParameters = playbackParameters; - } - - /** Previous value of {@link ExoPlayer#getCurrentPosition()}. */ - private final long position; - - /** Previous value of {@link ExoPlayer#getRepeatMode()}. */ - private final int repeatMode; - - /** Previous value of {@link ExoPlayer#getVolume()}. */ - private final float volume; - - /** Previous value of {@link ExoPlayer#getPlaybackParameters()}. */ - private final PlaybackParameters playbackParameters; - - /** - * Restores the captured state onto the provided player. - * - *

This will typically be done after creating a new player, setting up a media source, and - * listening to events. - * - * @param exoPlayer the new player instance to reflect the state back to. - */ - public void restore(@NonNull ExoPlayer exoPlayer) { - exoPlayer.seekTo(position); - exoPlayer.setRepeatMode(repeatMode); - exoPlayer.setVolume(volume); - exoPlayer.setPlaybackParameters(playbackParameters); - } -} diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java index 0b46bfe4e93..87ad4cb6273 100644 --- a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java +++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java @@ -22,9 +22,6 @@ *

It provides methods to control playback, adjust volume, and handle seeking. */ public abstract class VideoPlayer { - @NonNull private final ExoPlayerProvider exoPlayerProvider; - @NonNull private final MediaItem mediaItem; - @NonNull private final VideoPlayerOptions options; @NonNull protected final VideoPlayerCallbacks videoPlayerEvents; @Nullable protected final SurfaceProducer surfaceProducer; @NonNull protected ExoPlayer exoPlayer; @@ -47,22 +44,12 @@ public VideoPlayer( @Nullable SurfaceProducer surfaceProducer, @NonNull ExoPlayerProvider exoPlayerProvider) { this.videoPlayerEvents = events; - this.mediaItem = mediaItem; - this.options = options; - this.exoPlayerProvider = exoPlayerProvider; this.surfaceProducer = surfaceProducer; - this.exoPlayer = createVideoPlayer(); - } - - @NonNull - protected ExoPlayer createVideoPlayer() { - ExoPlayer exoPlayer = exoPlayerProvider.get(); + exoPlayer = exoPlayerProvider.get(); exoPlayer.setMediaItem(mediaItem); exoPlayer.prepare(); exoPlayer.addListener(createExoPlayerEventListener(exoPlayer, surfaceProducer)); setAudioAttributes(exoPlayer, options.mixWithOthers); - - return exoPlayer; } @NonNull diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/platformview/PlatformViewExoPlayerEventListener.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/platformview/PlatformViewExoPlayerEventListener.java index 82343d796f2..6fdc0b24b0d 100644 --- a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/platformview/PlatformViewExoPlayerEventListener.java +++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/platformview/PlatformViewExoPlayerEventListener.java @@ -6,7 +6,6 @@ import androidx.annotation.NonNull; import androidx.annotation.OptIn; -import androidx.annotation.VisibleForTesting; import androidx.media3.common.Format; import androidx.media3.common.util.UnstableApi; import androidx.media3.exoplayer.ExoPlayer; @@ -15,15 +14,9 @@ import java.util.Objects; public final class PlatformViewExoPlayerEventListener extends ExoPlayerEventListener { - @VisibleForTesting public PlatformViewExoPlayerEventListener( @NonNull ExoPlayer exoPlayer, @NonNull VideoPlayerCallbacks events) { - this(exoPlayer, events, false); - } - - public PlatformViewExoPlayerEventListener( - @NonNull ExoPlayer exoPlayer, @NonNull VideoPlayerCallbacks events, boolean initialized) { - super(exoPlayer, events, initialized); + super(exoPlayer, events); } @OptIn(markerClass = UnstableApi.class) diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/platformview/PlatformViewVideoPlayer.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/platformview/PlatformViewVideoPlayer.java index 7d033ba67b3..f1da6cf5b5e 100644 --- a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/platformview/PlatformViewVideoPlayer.java +++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/platformview/PlatformViewVideoPlayer.java @@ -62,8 +62,6 @@ public static PlatformViewVideoPlayer create( @Override protected ExoPlayerEventListener createExoPlayerEventListener( @NonNull ExoPlayer exoPlayer, @Nullable SurfaceProducer surfaceProducer) { - // Platform view video player does not suspend and re-create the exoPlayer, hence initialized - // is always false. It also does not require a reference to the SurfaceProducer. - return new PlatformViewExoPlayerEventListener(exoPlayer, videoPlayerEvents, false); + return new PlatformViewExoPlayerEventListener(exoPlayer, videoPlayerEvents); } } diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/texture/TextureExoPlayerEventListener.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/texture/TextureExoPlayerEventListener.java index e6013eff8c7..b6e33546cd5 100644 --- a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/texture/TextureExoPlayerEventListener.java +++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/texture/TextureExoPlayerEventListener.java @@ -7,7 +7,6 @@ import android.os.Build; import androidx.annotation.NonNull; import androidx.annotation.OptIn; -import androidx.annotation.VisibleForTesting; import androidx.media3.common.Format; import androidx.media3.common.VideoSize; import androidx.media3.exoplayer.ExoPlayer; @@ -18,20 +17,11 @@ public final class TextureExoPlayerEventListener extends ExoPlayerEventListener { private boolean surfaceProducerHandlesCropAndRotation; - @VisibleForTesting public TextureExoPlayerEventListener( @NonNull ExoPlayer exoPlayer, @NonNull VideoPlayerCallbacks events, boolean surfaceProducerHandlesCropAndRotation) { - this(exoPlayer, events, surfaceProducerHandlesCropAndRotation, false); - } - - public TextureExoPlayerEventListener( - @NonNull ExoPlayer exoPlayer, - @NonNull VideoPlayerCallbacks events, - boolean surfaceProducerHandlesCropAndRotation, - boolean initialized) { - super(exoPlayer, events, initialized); + super(exoPlayer, events); this.surfaceProducerHandlesCropAndRotation = surfaceProducerHandlesCropAndRotation; } diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/texture/TextureVideoPlayer.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/texture/TextureVideoPlayer.java index 2e8f1c789d9..c9d18dccce4 100644 --- a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/texture/TextureVideoPlayer.java +++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/texture/TextureVideoPlayer.java @@ -5,6 +5,7 @@ package io.flutter.plugins.videoplayer.texture; import android.content.Context; +import android.view.Surface; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RestrictTo; @@ -12,7 +13,6 @@ import androidx.media3.common.MediaItem; import androidx.media3.exoplayer.ExoPlayer; import io.flutter.plugins.videoplayer.ExoPlayerEventListener; -import io.flutter.plugins.videoplayer.ExoPlayerState; import io.flutter.plugins.videoplayer.VideoAsset; import io.flutter.plugins.videoplayer.VideoPlayer; import io.flutter.plugins.videoplayer.VideoPlayerCallbacks; @@ -27,8 +27,8 @@ * the texture. */ public final class TextureVideoPlayer extends VideoPlayer implements SurfaceProducer.Callback { - @Nullable private ExoPlayerState savedStateDuring; - + // True when the ExoPlayer instance has a null surface. + private boolean needsSurface = true; /** * Creates a texture video player. * @@ -70,7 +70,9 @@ public TextureVideoPlayer( surfaceProducer.setCallback(this); - this.exoPlayer.setVideoSurface(surfaceProducer.getSurface()); + Surface surface = surfaceProducer.getSurface(); + this.exoPlayer.setVideoSurface(surface); + needsSurface = surface == null; } @NonNull @@ -83,44 +85,31 @@ protected ExoPlayerEventListener createExoPlayerEventListener( } boolean surfaceProducerHandlesCropAndRotation = surfaceProducer.handlesCropAndRotation(); return new TextureExoPlayerEventListener( - exoPlayer, - videoPlayerEvents, - surfaceProducerHandlesCropAndRotation, - playerHasBeenSuspended()); + exoPlayer, videoPlayerEvents, surfaceProducerHandlesCropAndRotation); } @RestrictTo(RestrictTo.Scope.LIBRARY) public void onSurfaceAvailable() { - if (savedStateDuring != null) { - exoPlayer = createVideoPlayer(); + if (needsSurface) { + // TextureVideoPlayer must always set a surfaceProducer. + assert surfaceProducer != null; exoPlayer.setVideoSurface(surfaceProducer.getSurface()); - savedStateDuring.restore(exoPlayer); - savedStateDuring = null; + needsSurface = false; } } @RestrictTo(RestrictTo.Scope.LIBRARY) - // TODO(bparrishMines): Replace with onSurfaceCleanup once available on stable. See - // https://github.com/flutter/flutter/issues/161256. - @SuppressWarnings({"deprecation", "removal"}) - public void onSurfaceDestroyed() { - // Intentionally do not call pause/stop here, because the surface has already been released - // at this point (see https://github.com/flutter/flutter/issues/156451). - savedStateDuring = ExoPlayerState.save(exoPlayer); - exoPlayer.release(); - } - - private boolean playerHasBeenSuspended() { - return savedStateDuring != null; + public void onSurfaceCleanup() { + exoPlayer.setVideoSurface(null); + needsSurface = true; } public void dispose() { // Super must be called first to ensure the player is released before the surface. super.dispose(); + // TextureVideoPlayer must always set a surfaceProducer. + assert surfaceProducer != null; surfaceProducer.release(); - // TODO(matanlurey): Remove when embedder no longer calls-back once released. - // https://github.com/flutter/flutter/issues/156434. - surfaceProducer.setCallback(null); } } diff --git a/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/ExoPlayerEventListenerTest.java b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/ExoPlayerEventListenerTest.java index ac40efbcf3b..891773c2c82 100644 --- a/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/ExoPlayerEventListenerTest.java +++ b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/ExoPlayerEventListenerTest.java @@ -44,7 +44,7 @@ public final class ExoPlayerEventListenerTest { */ private static final class TestExoPlayerEventListener extends ExoPlayerEventListener { public TestExoPlayerEventListener(ExoPlayer exoPlayer, VideoPlayerCallbacks callbacks) { - super(exoPlayer, callbacks, false); + super(exoPlayer, callbacks); } @Override diff --git a/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/TextureVideoPlayerTest.java b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/TextureVideoPlayerTest.java index 4bbc89d810b..0d6e0bf5e91 100644 --- a/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/TextureVideoPlayerTest.java +++ b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/TextureVideoPlayerTest.java @@ -77,16 +77,17 @@ public void loadsAndPreparesProvidedMediaEnablesAudioFocusByDefault() { verify(mockExoPlayer).setVideoSurface(any()); verify(mockExoPlayer).setAudioAttributes(attributesCaptor.capture(), eq(true)); - assertEquals(attributesCaptor.getValue().contentType, C.AUDIO_CONTENT_TYPE_MOVIE); + assertEquals(C.AUDIO_CONTENT_TYPE_MOVIE, attributesCaptor.getValue().contentType); videoPlayer.dispose(); } @Test - public void onSurfaceProducerDestroyedAndAvailableReleasesAndThenRecreatesAndResumesPlayer() { + public void onSurfaceProducerCleanupAndAvailableRemovesAndRestoresSurface() { VideoPlayer videoPlayer = createVideoPlayer(); verify(mockProducer).setCallback(callbackCaptor.capture()); + verify(mockExoPlayer).setVideoSurface(notNull()); verify(mockExoPlayer, never()).release(); when(mockExoPlayer.getCurrentPosition()).thenReturn(10L); @@ -95,30 +96,25 @@ public void onSurfaceProducerDestroyedAndAvailableReleasesAndThenRecreatesAndRes when(mockExoPlayer.getPlaybackParameters()).thenReturn(new PlaybackParameters(2.5f)); TextureRegistry.SurfaceProducer.Callback producerLifecycle = callbackCaptor.getValue(); - simulateSurfaceDestruction(producerLifecycle); + producerLifecycle.onSurfaceCleanup(); - verify(mockExoPlayer).release(); + verify(mockExoPlayer).setVideoSurface(null); - // Create a new mock exo player so that we get a new instance. - mockExoPlayer = mock(ExoPlayer.class); + reset(mockExoPlayer); producerLifecycle.onSurfaceAvailable(); - verify(mockExoPlayer).setVideoSurface(any()); - verify(mockExoPlayer).seekTo(10L); - verify(mockExoPlayer).setRepeatMode(Player.REPEAT_MODE_ALL); - verify(mockExoPlayer).setVolume(0.5f); - verify(mockExoPlayer).setPlaybackParameters(new PlaybackParameters(2.5f)); + verify(mockExoPlayer).setVideoSurface(notNull()); videoPlayer.dispose(); } @Test - public void onSurfaceProducerDestroyedDoesNotStopOrPauseVideo() { + public void onSurfaceProducerCleanupDoesNotStopOrPauseVideo() { VideoPlayer videoPlayer = createVideoPlayer(); verify(mockProducer).setCallback(callbackCaptor.capture()); TextureRegistry.SurfaceProducer.Callback producerLifecycle = callbackCaptor.getValue(); - simulateSurfaceDestruction(producerLifecycle); + producerLifecycle.onSurfaceCleanup(); verify(mockExoPlayer, never()).stop(); verify(mockExoPlayer, never()).pause(); @@ -127,16 +123,6 @@ public void onSurfaceProducerDestroyedDoesNotStopOrPauseVideo() { videoPlayer.dispose(); } - @Test - public void onDisposeSurfaceProducerCallbackIsDisconnected() { - // Regression test for https://github.com/flutter/flutter/issues/156158. - VideoPlayer videoPlayer = createVideoPlayer(); - verify(mockProducer).setCallback(any()); - - videoPlayer.dispose(); - verify(mockProducer).setCallback(null); - } - @Test public void onInitializedCalledWhenVideoPlayerInitiallyCreated() { VideoPlayer videoPlayer = createVideoPlayer(); @@ -163,39 +149,39 @@ public void onSurfaceAvailableDoesNotSendInitializeEventAgain() { VideoPlayer videoPlayer = createVideoPlayer(); when(mockExoPlayer.getVideoSize()).thenReturn(new VideoSize(300, 200)); - // Capture the lifecycle events so we can simulate onSurfaceAvailableDestroyed. + // Capture the lifecycle events so we can simulate onSurfaceAvailable/Cleanup. verify(mockProducer).setCallback(callbackCaptor.capture()); TextureRegistry.SurfaceProducer.Callback producerLifecycle = callbackCaptor.getValue(); - // Trigger destroyed/available. - simulateSurfaceDestruction(producerLifecycle); - producerLifecycle.onSurfaceAvailable(); - - // Initial listener, and the new one from the resume. - verify(mockExoPlayer, times(2)).addListener(listenerCaptor.capture()); + verify(mockExoPlayer).addListener(listenerCaptor.capture()); Player.Listener listener = listenerCaptor.getValue(); - // Now trigger that same event, which would happen in the case of a background/resume. + // Trigger ready state, which should trigger initialization. listener.onPlaybackStateChanged(Player.STATE_READY); + verify(mockEvents).onInitialized(anyInt(), anyInt(), anyLong(), anyInt()); - // Was not called because it was a result of a background/resume. - verify(mockEvents, never()).onInitialized(anyInt(), anyInt(), anyLong(), anyInt()); + // Trigger cleanup/available. + producerLifecycle.onSurfaceCleanup(); + producerLifecycle.onSurfaceAvailable(); + + // It should still only have been called the one time. + verify(mockEvents).onInitialized(anyInt(), anyInt(), anyLong(), anyInt()); videoPlayer.dispose(); } @Test - public void onSurfaceAvailableWithoutDestroyDoesNotRecreate() { + public void onSurfaceAvailableWithoutCleanupDoesNotRecreate() { // Initially create the video player, which creates the initial surface. VideoPlayer videoPlayer = createVideoPlayer(); verify(mockProducer).getSurface(); verify(mockProducer).handlesCropAndRotation(); - // Capture the lifecycle events so we can simulate onSurfaceAvailable/Destroyed. + // Capture the lifecycle events so we can simulate onSurfaceAvailable/Cleanup. verify(mockProducer).setCallback(callbackCaptor.capture()); TextureRegistry.SurfaceProducer.Callback producerLifecycle = callbackCaptor.getValue(); - // Calling onSurfaceAvailable does not do anything, since the surface was never destroyed. + // Calling onSurfaceAvailable does not do anything, since the surface was never cleaned up. producerLifecycle.onSurfaceAvailable(); verifyNoMoreInteractions(mockProducer); @@ -214,20 +200,4 @@ public void disposeReleasesExoPlayerBeforeTexture() { inOrder.verify(mockExoPlayer).release(); inOrder.verify(mockProducer).release(); } - - // TODO(matanlurey): Replace with inline calls to onSurfaceAvailable once - // available on stable; see https://github.com/flutter/flutter/issues/155131. - // This separate method only exists to scope the suppression. - @SuppressWarnings({"deprecation", "removal"}) - void simulateSurfaceCreation(TextureRegistry.SurfaceProducer.Callback producerLifecycle) { - producerLifecycle.onSurfaceCreated(); - } - - // TODO(bparrishMines): Replace with inline calls to onSurfaceCleanup once available on stable; - // see https://github.com/flutter/flutter/issues/16125. This separate method only exists to scope - // the suppression. - @SuppressWarnings({"deprecation", "removal"}) - void simulateSurfaceDestruction(TextureRegistry.SurfaceProducer.Callback producerLifecycle) { - producerLifecycle.onSurfaceDestroyed(); - } } diff --git a/packages/video_player/video_player_android/pubspec.yaml b/packages/video_player/video_player_android/pubspec.yaml index 37fcd5f80cf..a7d200897ac 100644 --- a/packages/video_player/video_player_android/pubspec.yaml +++ b/packages/video_player/video_player_android/pubspec.yaml @@ -2,7 +2,7 @@ name: video_player_android description: Android implementation of the video_player plugin. repository: https://github.com/flutter/packages/tree/main/packages/video_player/video_player_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22 -version: 2.8.4 +version: 2.8.5 environment: sdk: ^3.7.0