From 50e6ff7f862a89229848f90f61e1805e8f8667e0 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 6 Jun 2024 14:26:28 -0700 Subject: [PATCH 1/4] =?UTF-8?q?Revert=20"Migrate=20`video=5Fplayer/android?= =?UTF-8?q?`=20from=20`SurfaceTexture`->`SurfaceProduce=E2=80=A6"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit a5dd3140f1b076a0ad9297db649687bee7b77010. --- .../video_player_android/CHANGELOG.md | 4 - .../plugins/videoplayer/VideoPlayer.java | 64 ++++------------ .../videoplayer/VideoPlayerPlugin.java | 75 ++----------------- .../plugins/videoplayer/VideoPlayerTest.java | 26 ++++--- .../FlutterActivityTest.java | 2 +- .../video_player_android/pubspec.yaml | 3 +- 6 files changed, 38 insertions(+), 136 deletions(-) diff --git a/packages/video_player/video_player_android/CHANGELOG.md b/packages/video_player/video_player_android/CHANGELOG.md index 9486013f634..cc9d5ceaa17 100644 --- a/packages/video_player/video_player_android/CHANGELOG.md +++ b/packages/video_player/video_player_android/CHANGELOG.md @@ -1,7 +1,3 @@ -## 2.4.16 - -* [Supports Impeller](https://docs.flutter.dev/release/breaking-changes/android-surface-plugins). - ## 2.4.15 * Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. 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 5cb5f0e2b30..b8b78191230 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 @@ -9,6 +9,7 @@ import android.content.Context; import android.net.Uri; +import android.view.Surface; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import com.google.android.exoplayer2.C; @@ -47,7 +48,9 @@ final class VideoPlayer { private ExoPlayer exoPlayer; - private TextureRegistry.SurfaceProducer surfaceProducer; + private Surface surface; + + private final TextureRegistry.SurfaceTextureEntry textureEntry; private QueuingEventSink eventSink; @@ -55,29 +58,22 @@ final class VideoPlayer { private static final String USER_AGENT = "User-Agent"; - private MediaSource mediaSource; - @VisibleForTesting boolean isInitialized = false; - // State that must be reset when the surface is re-created. private final VideoPlayerOptions options; - private long restoreVideoLocation = 0; - private int restoreRepeatMode = 0; - private float restoreVolume = 0; - private PlaybackParameters restorePlaybackParameters; private DefaultHttpDataSource.Factory httpDataSourceFactory = new DefaultHttpDataSource.Factory(); VideoPlayer( Context context, EventChannel eventChannel, - TextureRegistry.SurfaceProducer surfaceProducer, + TextureRegistry.SurfaceTextureEntry textureEntry, String dataSource, String formatHint, @NonNull Map httpHeaders, VideoPlayerOptions options) { this.eventChannel = eventChannel; - this.surfaceProducer = surfaceProducer; + this.textureEntry = textureEntry; this.options = options; ExoPlayer exoPlayer = new ExoPlayer.Builder(context).build(); @@ -87,7 +83,7 @@ final class VideoPlayer { DataSource.Factory dataSourceFactory = new DefaultDataSource.Factory(context, httpDataSourceFactory); - mediaSource = buildMediaSource(uri, dataSourceFactory, formatHint); + MediaSource mediaSource = buildMediaSource(uri, dataSourceFactory, formatHint); exoPlayer.setMediaSource(mediaSource); exoPlayer.prepare(); @@ -100,12 +96,12 @@ final class VideoPlayer { VideoPlayer( ExoPlayer exoPlayer, EventChannel eventChannel, - TextureRegistry.SurfaceProducer surfaceProducer, + TextureRegistry.SurfaceTextureEntry textureEntry, VideoPlayerOptions options, QueuingEventSink eventSink, DefaultHttpDataSource.Factory httpDataSourceFactory) { this.eventChannel = eventChannel; - this.surfaceProducer = surfaceProducer; + this.textureEntry = textureEntry; this.options = options; this.httpDataSourceFactory = httpDataSourceFactory; @@ -173,40 +169,6 @@ private MediaSource buildMediaSource( } } - public void recreateSurface(Context context) { - ExoPlayer exoPlayer = new ExoPlayer.Builder(context).build(); - - exoPlayer.setMediaSource(mediaSource); - exoPlayer.prepare(); - - setUpVideoPlayer(exoPlayer, new QueuingEventSink()); - exoPlayer.setVideoSurface(surfaceProducer.getSurface()); - exoPlayer.seekTo(restoreVideoLocation); - exoPlayer.setRepeatMode(restoreRepeatMode); - exoPlayer.setVolume(restoreVolume); - if (restorePlaybackParameters != null) { - exoPlayer.setPlaybackParameters(restorePlaybackParameters); - } - } - - public void pauseSurface() { - if (!isInitialized) { - return; - } - restoreVideoLocation = exoPlayer.getCurrentPosition(); - restoreRepeatMode = exoPlayer.getRepeatMode(); - restoreVolume = exoPlayer.getVolume(); - restorePlaybackParameters = exoPlayer.getPlaybackParameters(); - eventChannel.setStreamHandler(null); - if (isInitialized) { - exoPlayer.stop(); - } - if (exoPlayer != null) { - exoPlayer.release(); - } - isInitialized = false; - } - private void setUpVideoPlayer(ExoPlayer exoPlayer, QueuingEventSink eventSink) { this.exoPlayer = exoPlayer; this.eventSink = eventSink; @@ -224,7 +186,8 @@ public void onCancel(Object o) { } }); - exoPlayer.setVideoSurface(surfaceProducer.getSurface()); + surface = new Surface(textureEntry.surfaceTexture()); + exoPlayer.setVideoSurface(surface); setAudioAttributes(exoPlayer, options.mixWithOthers); exoPlayer.addListener( @@ -371,8 +334,11 @@ void dispose() { if (isInitialized) { exoPlayer.stop(); } - surfaceProducer.release(); + textureEntry.release(); eventChannel.setStreamHandler(null); + if (surface != null) { + surface.release(); + } if (exoPlayer != null) { exoPlayer.release(); } diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java index 54234dd6df8..5259e1ad3fe 100644 --- a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java +++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java @@ -8,16 +8,9 @@ import android.os.Build; import android.util.LongSparseArray; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.lifecycle.DefaultLifecycleObserver; -import androidx.lifecycle.Lifecycle; -import androidx.lifecycle.LifecycleOwner; import io.flutter.FlutterInjector; import io.flutter.Log; import io.flutter.embedding.engine.plugins.FlutterPlugin; -import io.flutter.embedding.engine.plugins.activity.ActivityAware; -import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; -import io.flutter.embedding.engine.plugins.lifecycle.FlutterLifecycleAdapter; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.EventChannel; import io.flutter.plugins.videoplayer.Messages.AndroidVideoPlayerApi; @@ -36,13 +29,11 @@ import javax.net.ssl.HttpsURLConnection; /** Android platform implementation of the VideoPlayerPlugin. */ -public class VideoPlayerPlugin - implements FlutterPlugin, AndroidVideoPlayerApi, DefaultLifecycleObserver, ActivityAware { +public class VideoPlayerPlugin implements FlutterPlugin, AndroidVideoPlayerApi { private static final String TAG = "VideoPlayerPlugin"; private final LongSparseArray videoPlayers = new LongSparseArray<>(); private FlutterState flutterState; private final VideoPlayerOptions options = new VideoPlayerOptions(); - @Nullable Lifecycle lifecycle; /** Register this with the v2 embedding for the plugin to respond to lifecycle callbacks. */ public VideoPlayerPlugin() {} @@ -92,7 +83,7 @@ public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { } flutterState.stopListening(binding.getBinaryMessenger()); flutterState = null; - performDestroy(); + onDestroy(); } private void disposeAllPlayers() { @@ -102,7 +93,7 @@ private void disposeAllPlayers() { videoPlayers.clear(); } - public void performDestroy() { + public void onDestroy() { // The whole FlutterView is being destroyed. Here we release resources acquired for all // instances // of VideoPlayer. Once https://github.com/flutter/flutter/issues/19358 is resolved this may @@ -116,7 +107,8 @@ public void initialize() { } public @NonNull TextureMessage create(@NonNull CreateMessage arg) { - TextureRegistry.SurfaceProducer handle = flutterState.textureRegistry.createSurfaceProducer(); + TextureRegistry.SurfaceTextureEntry handle = + flutterState.textureRegistry.createSurfaceTexture(); EventChannel eventChannel = new EventChannel( flutterState.binaryMessenger, "flutter.io/videoPlayer/videoEvents" + handle.id()); @@ -152,6 +144,7 @@ public void initialize() { options); } videoPlayers.put(handle.id(), player); + return new TextureMessage.Builder().setTextureId(handle.id()).build(); } @@ -207,62 +200,6 @@ public void setMixWithOthers(@NonNull MixWithOthersMessage arg) { options.mixWithOthers = arg.getMixWithOthers(); } - // Activity Aware - - @Override - public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) { - lifecycle = FlutterLifecycleAdapter.getActivityLifecycle(binding); - lifecycle.addObserver(this); - } - - @Override - public void onDetachedFromActivity() {} - - @Override - public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) { - onAttachedToActivity(binding); - } - - @Override - public void onDetachedFromActivityForConfigChanges() { - onDetachedFromActivity(); - } - - // DefaultLifecycleObserver - @Override - public void onResume(@NonNull LifecycleOwner owner) { - recreateAllSurfaces(); - } - - @Override - public void onPause(@NonNull LifecycleOwner owner) { - destroyAllSurfaces(); - } - - @Override - public void onStop(@NonNull LifecycleOwner owner) { - destroyAllSurfaces(); - } - - @Override - public void onDestroy(@NonNull LifecycleOwner owner) { - if (lifecycle != null) { - lifecycle.removeObserver(this); - } - } - - private void destroyAllSurfaces() { - for (int i = 0; i < videoPlayers.size(); i++) { - videoPlayers.valueAt(i).pauseSurface(); - } - } - - private void recreateAllSurfaces() { - for (int i = 0; i < videoPlayers.size(); i++) { - videoPlayers.valueAt(i).recreateSurface(flutterState.applicationContext); - } - } - private interface KeyForAssetFn { String get(String asset); } diff --git a/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoPlayerTest.java b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoPlayerTest.java index e9f69a57d36..7ff5000d3cf 100644 --- a/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoPlayerTest.java +++ b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoPlayerTest.java @@ -13,6 +13,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; +import android.graphics.SurfaceTexture; import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.PlaybackException; @@ -37,7 +38,8 @@ public class VideoPlayerTest { private ExoPlayer fakeExoPlayer; private EventChannel fakeEventChannel; - private TextureRegistry.SurfaceProducer fakeSurfaceProducer; + private TextureRegistry.SurfaceTextureEntry fakeSurfaceTextureEntry; + private SurfaceTexture fakeSurfaceTexture; private VideoPlayerOptions fakeVideoPlayerOptions; private QueuingEventSink fakeEventSink; private DefaultHttpDataSource.Factory httpDataSourceFactorySpy; @@ -50,7 +52,9 @@ public void before() { fakeExoPlayer = mock(ExoPlayer.class); fakeEventChannel = mock(EventChannel.class); - fakeSurfaceProducer = mock(TextureRegistry.SurfaceProducer.class); + fakeSurfaceTextureEntry = mock(TextureRegistry.SurfaceTextureEntry.class); + fakeSurfaceTexture = mock(SurfaceTexture.class); + when(fakeSurfaceTextureEntry.surfaceTexture()).thenReturn(fakeSurfaceTexture); fakeVideoPlayerOptions = mock(VideoPlayerOptions.class); fakeEventSink = mock(QueuingEventSink.class); httpDataSourceFactorySpy = spy(new DefaultHttpDataSource.Factory()); @@ -62,7 +66,7 @@ public void videoPlayer_buildsHttpDataSourceFactoryProperlyWhenHttpHeadersNull() new VideoPlayer( fakeExoPlayer, fakeEventChannel, - fakeSurfaceProducer, + fakeSurfaceTextureEntry, fakeVideoPlayerOptions, fakeEventSink, httpDataSourceFactorySpy); @@ -81,7 +85,7 @@ public void videoPlayer_buildsHttpDataSourceFactoryProperlyWhenHttpHeadersNull() new VideoPlayer( fakeExoPlayer, fakeEventChannel, - fakeSurfaceProducer, + fakeSurfaceTextureEntry, fakeVideoPlayerOptions, fakeEventSink, httpDataSourceFactorySpy); @@ -107,7 +111,7 @@ public void videoPlayer_buildsHttpDataSourceFactoryProperlyWhenHttpHeadersNull() new VideoPlayer( fakeExoPlayer, fakeEventChannel, - fakeSurfaceProducer, + fakeSurfaceTextureEntry, fakeVideoPlayerOptions, fakeEventSink, httpDataSourceFactorySpy); @@ -131,7 +135,7 @@ public void sendInitializedSendsExpectedEvent_90RotationDegrees() { new VideoPlayer( fakeExoPlayer, fakeEventChannel, - fakeSurfaceProducer, + fakeSurfaceTextureEntry, fakeVideoPlayerOptions, fakeEventSink, httpDataSourceFactorySpy); @@ -160,7 +164,7 @@ public void sendInitializedSendsExpectedEvent_270RotationDegrees() { new VideoPlayer( fakeExoPlayer, fakeEventChannel, - fakeSurfaceProducer, + fakeSurfaceTextureEntry, fakeVideoPlayerOptions, fakeEventSink, httpDataSourceFactorySpy); @@ -189,7 +193,7 @@ public void sendInitializedSendsExpectedEvent_0RotationDegrees() { new VideoPlayer( fakeExoPlayer, fakeEventChannel, - fakeSurfaceProducer, + fakeSurfaceTextureEntry, fakeVideoPlayerOptions, fakeEventSink, httpDataSourceFactorySpy); @@ -218,7 +222,7 @@ public void sendInitializedSendsExpectedEvent_180RotationDegrees() { new VideoPlayer( fakeExoPlayer, fakeEventChannel, - fakeSurfaceProducer, + fakeSurfaceTextureEntry, fakeVideoPlayerOptions, fakeEventSink, httpDataSourceFactorySpy); @@ -247,7 +251,7 @@ public void onIsPlayingChangedSendsExpectedEvent() { new VideoPlayer( fakeExoPlayer, fakeEventChannel, - fakeSurfaceProducer, + fakeSurfaceTextureEntry, fakeVideoPlayerOptions, fakeEventSink, httpDataSourceFactorySpy); @@ -292,7 +296,7 @@ public void behindLiveWindowErrorResetsPlayerToDefaultPosition() { new VideoPlayer( fakeExoPlayer, fakeEventChannel, - fakeSurfaceProducer, + fakeSurfaceTextureEntry, fakeVideoPlayerOptions, fakeEventSink, httpDataSourceFactorySpy); diff --git a/packages/video_player/video_player_android/example/android/app/src/test/java/io/flutter/plugins/videoplayerexample/FlutterActivityTest.java b/packages/video_player/video_player_android/example/android/app/src/test/java/io/flutter/plugins/videoplayerexample/FlutterActivityTest.java index d41e80cf6d1..750d4a486dd 100644 --- a/packages/video_player/video_player_android/example/android/app/src/test/java/io/flutter/plugins/videoplayerexample/FlutterActivityTest.java +++ b/packages/video_player/video_player_android/example/android/app/src/test/java/io/flutter/plugins/videoplayerexample/FlutterActivityTest.java @@ -45,6 +45,6 @@ public void disposeAllPlayers() { engine.destroy(); verify(videoPlayerPlugin, times(1)).onDetachedFromEngine(pluginBindingCaptor.capture()); - verify(videoPlayerPlugin, times(1)).performDestroy(); + verify(videoPlayerPlugin, times(1)).onDestroy(); } } diff --git a/packages/video_player/video_player_android/pubspec.yaml b/packages/video_player/video_player_android/pubspec.yaml index b9de2c60ffe..35c7d0ee55c 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.4.16 +version: 2.4.15 environment: sdk: ^3.4.0 @@ -20,7 +20,6 @@ flutter: dependencies: flutter: sdk: flutter - flutter_plugin_android_lifecycle: ^2.0.1 video_player_platform_interface: ">=6.1.0 <7.0.0" dev_dependencies: From 531abce201919065d964f4089f510bf7c864368a Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 6 Jun 2024 14:29:33 -0700 Subject: [PATCH 2/4] fix changelog and version. --- packages/video_player/video_player_android/CHANGELOG.md | 8 ++++++++ packages/video_player/video_player_android/pubspec.yaml | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/video_player/video_player_android/CHANGELOG.md b/packages/video_player/video_player_android/CHANGELOG.md index cc9d5ceaa17..c579d0be306 100644 --- a/packages/video_player/video_player_android/CHANGELOG.md +++ b/packages/video_player/video_player_android/CHANGELOG.md @@ -1,3 +1,11 @@ +## 2.4.16+0 + +* Revert Impeller support. + +## 2.4.16 + +* [Supports Impeller](https://docs.flutter.dev/release/breaking-changes/android-surface-plugins). + ## 2.4.15 * Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. diff --git a/packages/video_player/video_player_android/pubspec.yaml b/packages/video_player/video_player_android/pubspec.yaml index 35c7d0ee55c..88762be9082 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.4.15 +version: 2.4.16+0 environment: sdk: ^3.4.0 From 8ef2d464d52cc8e24c948aa739e4d0560b9cfc9d Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 6 Jun 2024 15:18:41 -0700 Subject: [PATCH 3/4] Update CHANGELOG.md --- packages/video_player/video_player_android/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/video_player/video_player_android/CHANGELOG.md b/packages/video_player/video_player_android/CHANGELOG.md index c579d0be306..e2b39f8f44f 100644 --- a/packages/video_player/video_player_android/CHANGELOG.md +++ b/packages/video_player/video_player_android/CHANGELOG.md @@ -1,4 +1,4 @@ -## 2.4.16+0 +## 2.4.17 * Revert Impeller support. From dfeb01f549c0370bd945ae5d67ed4ac86a714307 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 6 Jun 2024 15:18:55 -0700 Subject: [PATCH 4/4] Update pubspec.yaml --- packages/video_player/video_player_android/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/video_player/video_player_android/pubspec.yaml b/packages/video_player/video_player_android/pubspec.yaml index 88762be9082..864c3ec8efa 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.4.16+0 +version: 2.4.17 environment: sdk: ^3.4.0