From 438c737e982f19ecffe3850119bceb41503252bb Mon Sep 17 00:00:00 2001 From: Nayuta403 <40540394+Nayuta403@users.noreply.github.com> Date: Mon, 4 Jul 2022 10:39:03 +0800 Subject: [PATCH] Avoid crash caused by flutterImageView be null (flutter/engine#34395) --- .../embedding/android/FlutterView.java | 7 ++++- .../embedding/android/FlutterViewTest.java | 26 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/engine/src/flutter/shell/platform/android/io/flutter/embedding/android/FlutterView.java b/engine/src/flutter/shell/platform/android/io/flutter/embedding/android/FlutterView.java index f63e899b4e8..53cc25e1773 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/embedding/android/FlutterView.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/embedding/android/FlutterView.java @@ -1308,6 +1308,11 @@ public class FlutterView extends FrameLayout getContext(), getWidth(), getHeight(), FlutterImageView.SurfaceKind.background); } + @VisibleForTesting + public FlutterImageView getCurrentImageSurface() { + return flutterImageView; + } + /** * Converts the current render surface to a {@link FlutterImageView} if it's not one already. * Otherwise, it resizes the {@link FlutterImageView} based on the current view size. @@ -1370,7 +1375,7 @@ public class FlutterView extends FrameLayout public void onFlutterUiDisplayed() { renderer.removeIsDisplayingFlutterUiListener(this); onDone.run(); - if (!(renderSurface instanceof FlutterImageView)) { + if (!(renderSurface instanceof FlutterImageView) && flutterImageView != null) { flutterImageView.detachFromRenderer(); } } diff --git a/engine/src/flutter/shell/platform/android/test/io/flutter/embedding/android/FlutterViewTest.java b/engine/src/flutter/shell/platform/android/test/io/flutter/embedding/android/FlutterViewTest.java index 91b9244e4d8..beb05cc29e8 100644 --- a/engine/src/flutter/shell/platform/android/test/io/flutter/embedding/android/FlutterViewTest.java +++ b/engine/src/flutter/shell/platform/android/test/io/flutter/embedding/android/FlutterViewTest.java @@ -174,6 +174,32 @@ public class FlutterViewTest { verify(imageViewMock, times(1)).closeImageReader(); } + @Test + public void flutterImageView_revertImageViewAndAvoidNPE() { + FlutterView flutterView = new FlutterView(ctx); + FlutterEngine flutterEngine = spy(new FlutterEngine(ctx, mockFlutterLoader, mockFlutterJni)); + FlutterRenderer flutterRenderer = spy(new FlutterRenderer(mockFlutterJni)); + when(flutterEngine.getRenderer()).thenReturn(flutterRenderer); + + flutterView.attachToFlutterEngine(flutterEngine); + flutterView.convertToImageView(); + assertTrue(flutterView.renderSurface instanceof FlutterImageView); + + // Register a `FlutterUiDisplayListener` callback. + // During callback execution it will invoke `flutterImageView.detachFromRenderer()`. + flutterView.revertImageView( + () -> { + // No-op + }); + assertFalse(flutterView.renderSurface instanceof FlutterImageView); + + flutterView.detachFromFlutterEngine(); + assertEquals(null, flutterView.getCurrentImageSurface()); + + // Invoke all registered `FlutterUiDisplayListener` callback + mockFlutterJni.onFirstFrame(); + } + @Test public void onConfigurationChanged_fizzlesWhenNullEngine() { FlutterView flutterView = new FlutterView(Robolectric.setupActivity(Activity.class));