From 00d6844db4ede29e5e43daa415b60e7275b496cd Mon Sep 17 00:00:00 2001 From: nayuta Date: Tue, 8 Nov 2022 20:51:57 +0800 Subject: [PATCH 1/3] remove image --- .../embedding/android/FlutterView.java | 20 +++++++++++-------- .../platform/PlatformViewsController.java | 1 + 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterView.java b/shell/platform/android/io/flutter/embedding/android/FlutterView.java index dd0026c3bab50..a0cf5c1fb2eb6 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterView.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterView.java @@ -1289,6 +1289,13 @@ public void detachFromFlutterEngine() { } renderSurface.detachFromRenderer(); + releaseImageView(); + + previousRenderSurface = null; + flutterEngine = null; + } + + private void releaseImageView() { if (flutterImageView != null) { flutterImageView.closeImageReader(); // Remove the FlutterImageView that was previously added by {@code convertToImageView} to @@ -1297,8 +1304,6 @@ public void detachFromFlutterEngine() { removeView(flutterImageView); flutterImageView = null; } - previousRenderSurface = null; - flutterEngine = null; } @VisibleForTesting @@ -1352,14 +1357,12 @@ public void revertImageView(@NonNull Runnable onDone) { } renderSurface = previousRenderSurface; previousRenderSurface = null; - if (flutterEngine == null) { - flutterImageView.detachFromRenderer(); - onDone.run(); - return; - } + final FlutterRenderer renderer = flutterEngine.getRenderer(); - if (renderer == null) { + + if (flutterEngine == null || renderer == null) { flutterImageView.detachFromRenderer(); + releaseImageView(); onDone.run(); return; } @@ -1377,6 +1380,7 @@ public void onFlutterUiDisplayed() { onDone.run(); if (!(renderSurface instanceof FlutterImageView) && flutterImageView != null) { flutterImageView.detachFromRenderer(); + releaseImageView(); } } diff --git a/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java b/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java index 87a04f567127e..a9fd907ae47ba 100644 --- a/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java +++ b/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java @@ -1205,6 +1205,7 @@ private void finishFrame(boolean isFrameRenderedUsingImageReaders) { } // Hide overlay surfaces that aren't rendered in the current frame. overlayView.setVisibility(View.GONE); + flutterView.removeView(overlayView); } } From 25769bde15c31539f7797b3e21aa45887efa9902 Mon Sep 17 00:00:00 2001 From: nayuta Date: Thu, 10 Nov 2022 15:19:52 +0800 Subject: [PATCH 2/3] add test --- .../platform/PlatformViewsController.java | 9 +++ .../platform/PlatformViewsControllerTest.java | 70 +++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java b/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java index a9fd907ae47ba..544472acef15d 100644 --- a/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java +++ b/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java @@ -1229,6 +1229,10 @@ private void finishFrame(boolean isFrameRenderedUsingImageReaders) { parentView.setVisibility(View.GONE); } } + + if (!isFrameRenderedUsingImageReaders) { + destroyOverlaySurfaces(); + } } /** @@ -1298,4 +1302,9 @@ private void removeOverlaySurfaces() { } overlayLayerViews.clear(); } + + @VisibleForTesting + public SparseArray getOverlayLayerViews() { + return overlayLayerViews; + } } diff --git a/shell/platform/android/test/io/flutter/plugin/platform/PlatformViewsControllerTest.java b/shell/platform/android/test/io/flutter/plugin/platform/PlatformViewsControllerTest.java index 5dd43edc132ce..87fb8eb8cee98 100644 --- a/shell/platform/android/test/io/flutter/plugin/platform/PlatformViewsControllerTest.java +++ b/shell/platform/android/test/io/flutter/plugin/platform/PlatformViewsControllerTest.java @@ -2,6 +2,8 @@ import static android.os.Looper.getMainLooper; import static io.flutter.embedding.engine.systemchannels.PlatformViewsChannel.PlatformViewTouch; +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -1214,6 +1216,74 @@ public void reattachToFlutterView() { verify(newFlutterView, times(1)).addView(any(PlatformViewWrapper.class)); } + @Config( + shadows = { + ShadowFlutterSurfaceView.class, + ShadowFlutterJNI.class, + ShadowPlatformTaskQueue.class + }) + public void revertImageViewAndRemoveImageView() { + final PlatformViewsController platformViewsController = new PlatformViewsController(); + + final int platformViewId = 0; + assertNull(platformViewsController.getPlatformViewById(platformViewId)); + + final PlatformViewFactory viewFactory = mock(PlatformViewFactory.class); + final PlatformView platformView = mock(PlatformView.class); + final View androidView = mock(View.class); + when(platformView.getView()).thenReturn(androidView); + when(viewFactory.create(any(), eq(platformViewId), any())).thenReturn(platformView); + + platformViewsController.getRegistry().registerViewFactory("testType", viewFactory); + + final FlutterJNI jni = new FlutterJNI(); + jni.attachToNative(); + + final FlutterView flutterView = attach(jni, platformViewsController); + + jni.onFirstFrame(); + + // Simulate create call from the framework. + createPlatformView(jni, platformViewsController, platformViewId, "testType", /* hybrid=*/ true); + + // The simulation creates an Overlay on top of the PlatformView + // This is going to be called `flutterView.convertToImageView` + platformViewsController.createOverlaySurface(); + platformViewsController.onDisplayOverlaySurface(platformViewId, 0, 0, 10, 10); + + // This will contain three views: Background ImageView、PlatformView、Overlay ImageView + assertEquals(flutterView.getChildCount(), 3); + + FlutterImageView imageView = flutterView.getCurrentImageSurface(); + + // Make sure the ImageView is inside the current FlutterView. + assertTrue(imageView != null); + assertTrue(flutterView.indexOfChild(imageView) != -1); + + // Make sure the overlayView is inside the current FlutterView + assertTrue(platformViewsController.getOverlayLayerViews().size() != 0); + PlatformOverlayView overlayView = platformViewsController.getOverlayLayerViews().get(0); + assertTrue(overlayView != null); + assertTrue(flutterView.indexOfChild(overlayView) != -1); + + // Simulate in a new frame, there's no PlatformView, which is called + // `flutterView.revertImageView`. And register a `FlutterUiDisplayListener` callback. + // During callback execution it will invoke `flutterImageView.detachFromRenderer()`. + platformViewsController.onBeginFrame(); + platformViewsController.onEndFrame(); + + // Invoke all registered `FlutterUiDisplayListener` callback + jni.onFirstFrame(); + + assertEquals(null, flutterView.getCurrentImageSurface()); + + // Make sure the background ImageVIew is not in the FlutterView + assertTrue(flutterView.indexOfChild(imageView) == -1); + + // Make sure the overlay ImageVIew is not in the FlutterView + assertTrue(flutterView.indexOfChild(overlayView) == -1); + } + private static ByteBuffer encodeMethodCall(MethodCall call) { final ByteBuffer buffer = StandardMethodCodec.INSTANCE.encodeMethodCall(call); buffer.rewind(); From 028dddf3a98f99ecf6c014f07be6ef53a58e59f9 Mon Sep 17 00:00:00 2001 From: nayuta Date: Thu, 10 Nov 2022 15:24:14 +0800 Subject: [PATCH 3/3] remove --- .../io/flutter/plugin/platform/PlatformViewsController.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java b/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java index 544472acef15d..2b2e97e5f3ce3 100644 --- a/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java +++ b/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java @@ -1229,10 +1229,6 @@ private void finishFrame(boolean isFrameRenderedUsingImageReaders) { parentView.setVisibility(View.GONE); } } - - if (!isFrameRenderedUsingImageReaders) { - destroyOverlaySurfaces(); - } } /**