From 3c089996dcf45bdb15d51d2bc09d8024ee74c5d4 Mon Sep 17 00:00:00 2001 From: Jason Simmons Date: Thu, 2 Apr 2020 18:16:05 -0700 Subject: [PATCH] Disconnect from platform views and virtual displays before detaching from the engine (flutter/engine#17379) --- .../io/flutter/app/FlutterPluginRegistry.java | 4 ++-- .../embedding/engine/FlutterEngine.java | 2 ++ .../platform/PlatformViewsController.java | 16 +++++++++++++- .../embedding/engine/FlutterEngineTest.java | 22 +++++++++++++++++++ 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/engine/src/flutter/shell/platform/android/io/flutter/app/FlutterPluginRegistry.java b/engine/src/flutter/shell/platform/android/io/flutter/app/FlutterPluginRegistry.java index b1979694cff..2a7173634ec 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/app/FlutterPluginRegistry.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/app/FlutterPluginRegistry.java @@ -86,7 +86,7 @@ public class FlutterPluginRegistry public void detach() { mPlatformViewsController.detach(); - mPlatformViewsController.onFlutterViewDestroyed(); + mPlatformViewsController.onDetachedFromJNI(); mFlutterView = null; mActivity = null; } @@ -239,6 +239,6 @@ public class FlutterPluginRegistry } public void destroy() { - mPlatformViewsController.onFlutterViewDestroyed(); + mPlatformViewsController.onDetachedFromJNI(); } } diff --git a/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java b/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java index dfd2bd674c5..271a1a8ec24 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java @@ -225,6 +225,7 @@ public class FlutterEngine { textInputChannel = new TextInputChannel(dartExecutor); this.platformViewsController = platformViewsController; + this.platformViewsController.onAttachedToJNI(); this.pluginRegistry = new FlutterEnginePluginRegistry(context.getApplicationContext(), this, flutterLoader); @@ -289,6 +290,7 @@ public class FlutterEngine { Log.v(TAG, "Destroying."); // The order that these things are destroyed is important. pluginRegistry.destroy(); + platformViewsController.onDetachedFromJNI(); dartExecutor.onDetachedFromJNI(); flutterJNI.removeEngineLifecycleListener(engineLifecycleListener); flutterJNI.detachFromNativeAndReleaseResources(); diff --git a/engine/src/flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java b/engine/src/flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java index 6c87e20c0fd..cc5dfc91af8 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java @@ -404,7 +404,21 @@ public class PlatformViewsController implements PlatformViewsAccessibilityDelega return registry; } - public void onFlutterViewDestroyed() { + /** + * Invoked when the {@link io.flutter.embedding.engine.FlutterEngine} that owns this {@link + * PlatformViewsController} attaches to JNI. + */ + public void onAttachedToJNI() { + // Currently no action needs to be taken after JNI attachment. + } + + /** + * Invoked when the {@link io.flutter.embedding.engine.FlutterEngine} that owns this {@link + * PlatformViewsController} detaches from JNI. + */ + public void onDetachedFromJNI() { + // Dispose all virtual displays so that any future updates to textures will not be + // propagated to the native peer. flushAllViews(); } diff --git a/engine/src/flutter/shell/platform/android/test/io/flutter/embedding/engine/FlutterEngineTest.java b/engine/src/flutter/shell/platform/android/test/io/flutter/embedding/engine/FlutterEngineTest.java index c95612281f1..9a15364373b 100644 --- a/engine/src/flutter/shell/platform/android/test/io/flutter/embedding/engine/FlutterEngineTest.java +++ b/engine/src/flutter/shell/platform/android/test/io/flutter/embedding/engine/FlutterEngineTest.java @@ -102,6 +102,28 @@ public class FlutterEngineTest { verify(platformViewsController, times(1)).onPreEngineRestart(); } + @Test + public void itNotifiesPlatformViewsControllerAboutJNILifecycle() { + FlutterJNI mockFlutterJNI = mock(FlutterJNI.class); + when(mockFlutterJNI.isAttached()).thenReturn(true); + + PlatformViewsController platformViewsController = mock(PlatformViewsController.class); + + // Execute behavior under test. + FlutterEngine engine = + new FlutterEngine( + RuntimeEnvironment.application, + mock(FlutterLoader.class), + mockFlutterJNI, + platformViewsController, + /*dartVmArgs=*/ new String[] {}, + /*automaticallyRegisterPlugins=*/ false); + verify(platformViewsController, times(1)).onAttachedToJNI(); + + engine.destroy(); + verify(platformViewsController, times(1)).onDetachedFromJNI(); + } + @Test public void itUsesApplicationContext() { Context context = mock(Context.class);