Skip to content

Commit 1dc8695

Browse files
author
Emmanuel Garcia
authored
Replace Flutter surface only after all platform views are destroyed (#24363)
1 parent 1d53782 commit 1dc8695

3 files changed

Lines changed: 75 additions & 7 deletions

File tree

shell/platform/android/io/flutter/embedding/android/FlutterView.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,12 @@ public void detachFromFlutterEngine() {
999999
flutterEngine = null;
10001000
}
10011001

1002+
@VisibleForTesting
1003+
@NonNull
1004+
public RenderSurface getRenderSurface() {
1005+
return renderSurface;
1006+
}
1007+
10021008
@VisibleForTesting
10031009
@NonNull
10041010
public FlutterImageView createImageView() {

shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -784,11 +784,11 @@ public void onBeginFrame() {
784784

785785
public void onEndFrame() {
786786
final FlutterView view = (FlutterView) flutterView;
787-
// If there are no platform views in the current frame,
788-
// then revert the image view surface and use the previous surface.
787+
// If there are no platform views, then revert the image view surface,
788+
// and use the previous surface.
789789
//
790790
// Otherwise, acquire the latest image.
791-
if (flutterViewConvertedToImageView && currentFrameUsedPlatformViewIds.isEmpty()) {
791+
if (flutterViewConvertedToImageView && platformViews.size() == 0) {
792792
flutterViewConvertedToImageView = false;
793793
view.revertImageView(
794794
() -> {

shell/platform/android/test/io/flutter/plugin/platform/PlatformViewsControllerTest.java

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ public void onEndFrame__destroysOverlaySurfaceAfterFrameOnFlutterSurfaceView() {
415415

416416
// Produce a frame that doesn't display platform views.
417417
platformViewsController.onBeginFrame();
418+
disposePlatformView(jni, platformViewsController, platformViewId);
418419
platformViewsController.onEndFrame();
419420

420421
verify(overlayImageView, never()).detachFromRenderer();
@@ -485,17 +486,80 @@ public void onEndFrame__removesPlatformViewParent() {
485486

486487
// Simulate create call from the framework.
487488
createPlatformView(jni, platformViewsController, platformViewId, "testType");
488-
platformViewsController.initializePlatformViewIfNeeded(platformViewId);
489-
assertEquals(flutterView.getChildCount(), 2);
489+
assertEquals(flutterView.getChildCount(), 1);
490+
assertEquals(flutterView.getChildAt(0).getClass().getSimpleName(), "FlutterSurfaceView");
490491

491492
// Simulate first frame from the framework.
492493
jni.onFirstFrame();
493494
platformViewsController.onBeginFrame();
495+
platformViewsController.onDisplayPlatformView(
496+
platformViewId, 0, 0, 100, 100, 200, 200, new FlutterMutatorsStack());
497+
assertEquals(flutterView.getChildCount(), 3);
498+
assertEquals(flutterView.getChildAt(0).getClass().getSimpleName(), "FlutterSurfaceView");
499+
assertTrue(flutterView.getChildAt(1).getClass().getSimpleName().startsWith("FlutterImageView"));
500+
494501
platformViewsController.onEndFrame();
502+
assertEquals(flutterView.getChildCount(), 3);
503+
assertEquals(flutterView.getChildAt(0).getClass().getSimpleName(), "FlutterSurfaceView");
504+
assertTrue(flutterView.getChildAt(1).getClass().getSimpleName().startsWith("FlutterImageView"));
495505

496506
// Simulate dispose call from the framework.
497507
disposePlatformView(jni, platformViewsController, platformViewId);
508+
assertEquals(flutterView.getChildCount(), 2);
509+
assertEquals(flutterView.getChildAt(0).getClass().getSimpleName(), "FlutterSurfaceView");
510+
assertTrue(flutterView.getChildAt(1).getClass().getSimpleName().startsWith("FlutterImageView"));
511+
}
512+
513+
@Test
514+
@Config(shadows = {ShadowFlutterSurfaceView.class, ShadowFlutterJNI.class})
515+
public void onEndFrame__revertsFlutterSurface() {
516+
final PlatformViewsController platformViewsController = new PlatformViewsController();
517+
518+
final int platformViewId = 0;
519+
assertNull(platformViewsController.getPlatformViewById(platformViewId));
520+
521+
final PlatformViewFactory viewFactory = mock(PlatformViewFactory.class);
522+
final PlatformView platformView = mock(PlatformView.class);
523+
final View androidView = mock(View.class);
524+
when(platformView.getView()).thenReturn(androidView);
525+
when(viewFactory.create(any(), eq(platformViewId), any())).thenReturn(platformView);
526+
527+
platformViewsController.getRegistry().registerViewFactory("testType", viewFactory);
528+
529+
final FlutterJNI jni = new FlutterJNI();
530+
jni.attachToNative(false);
531+
532+
final FlutterView flutterView = attach(jni, platformViewsController);
533+
534+
jni.onFirstFrame();
535+
536+
// Simulate create call from the framework.
537+
createPlatformView(jni, platformViewsController, platformViewId, "testType");
498538
assertEquals(flutterView.getChildCount(), 1);
539+
assertEquals(flutterView.getChildAt(0).getClass().getSimpleName(), "FlutterSurfaceView");
540+
541+
// Simulate first frame from the framework.
542+
jni.onFirstFrame();
543+
platformViewsController.onBeginFrame();
544+
platformViewsController.onDisplayPlatformView(
545+
platformViewId, 0, 0, 100, 100, 200, 200, new FlutterMutatorsStack());
546+
assertTrue(
547+
flutterView.getRenderSurface().getClass().getSimpleName().contains("FlutterImageView"));
548+
549+
platformViewsController.onEndFrame();
550+
assertTrue(
551+
flutterView.getRenderSurface().getClass().getSimpleName().contains("FlutterImageView"));
552+
553+
platformViewsController.onBeginFrame();
554+
platformViewsController.onEndFrame();
555+
assertTrue(
556+
flutterView.getRenderSurface().getClass().getSimpleName().contains("FlutterImageView"));
557+
558+
platformViewsController.onBeginFrame();
559+
// Dispose the platform view is sufficient to flip the Flutter surface.
560+
disposePlatformView(jni, platformViewsController, platformViewId);
561+
platformViewsController.onEndFrame();
562+
assertEquals(flutterView.getRenderSurface().getClass().getSimpleName(), "FlutterSurfaceView");
499563
}
500564

501565
@Test
@@ -556,8 +620,6 @@ private static FlutterView attach(
556620
new FlutterView(context, FlutterView.RenderMode.surface) {
557621
@Override
558622
public FlutterImageView createImageView() {
559-
final FlutterImageView view = mock(FlutterImageView.class);
560-
when(view.acquireLatestImage()).thenReturn(true);
561623
return mock(FlutterImageView.class);
562624
}
563625
};

0 commit comments

Comments
 (0)