From 42804e2d1f06e13f4a21443789e3dcc2c55e71d1 Mon Sep 17 00:00:00 2001 From: Amir Hardon Date: Thu, 2 Aug 2018 12:08:22 -0700 Subject: [PATCH 1/3] Flush all embedded Android view on hot restart. Adds an OnEngineRestarted method to PlatformView, this is currently only implemented for Android where we need to use it for embedded views. --- shell/common/engine.cc | 1 + shell/common/engine.h | 2 ++ shell/common/platform_view.cc | 2 ++ shell/common/platform_view.h | 2 ++ shell/common/shell.cc | 15 +++++++++++++++ shell/common/shell.h | 3 +++ .../io/flutter/app/FlutterPluginRegistry.java | 4 ++++ .../plugin/platform/PlatformViewsController.java | 15 +++++++++++---- .../io/flutter/view/FlutterNativeView.java | 8 ++++++++ shell/platform/android/platform_view_android.cc | 11 +++++++++++ shell/platform/android/platform_view_android.h | 3 +++ .../platform/android/platform_view_android_jni.cc | 13 +++++++++++++ .../platform/android/platform_view_android_jni.h | 2 ++ 13 files changed, 77 insertions(+), 4 deletions(-) diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 2375d02d7728b..a0b606e7b4a7a 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -103,6 +103,7 @@ bool Engine::Restart(RunConfiguration configuration) { } runtime_controller_ = runtime_controller_->Clone(); UpdateAssetManager(nullptr); + delegate_.OnEngineRestart(); return Run(std::move(configuration)); } diff --git a/shell/common/engine.h b/shell/common/engine.h index 1a2c75ee60191..5b7ee6d1e1f40 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -39,6 +39,8 @@ class Engine final : public blink::RuntimeDelegate { virtual void OnEngineHandlePlatformMessage( const Engine& engine, fml::RefPtr message) = 0; + + virtual void OnEngineRestart() = 0; }; Engine(Delegate& delegate, diff --git a/shell/common/platform_view.cc b/shell/common/platform_view.cc index 656fa91439e2d..d31201dc6191d 100644 --- a/shell/common/platform_view.cc +++ b/shell/common/platform_view.cc @@ -88,6 +88,8 @@ void PlatformView::HandlePlatformMessage( response->CompleteEmpty(); } +void PlatformView::OnEngineRestart() const {} + void PlatformView::RegisterTexture(std::shared_ptr texture) { delegate_.OnPlatformViewRegisterTexture(*this, std::move(texture)); } diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h index a6fccae56313e..a877875cae469 100644 --- a/shell/common/platform_view.h +++ b/shell/common/platform_view.h @@ -108,6 +108,8 @@ class PlatformView { virtual void HandlePlatformMessage( fml::RefPtr message); + virtual void OnEngineRestart() const; + void SetNextFrameCallback(fml::closure closure); void DispatchPointerDataPacket( diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 1e3085ca1d894..16dd45fc68362 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -740,6 +740,21 @@ void Shell::OnEngineHandlePlatformMessage( }); } +// |shell::Engine::Delegate| +void Shell::OnEngineRestart() { + fml::AutoResetWaitableEvent latch; + task_runners_.GetPlatformTaskRunner()->PostTask( + [view = platform_view_->GetWeakPtr(), &latch] { + if (view) { + view->OnEngineRestart(); + } + latch.Signal(); + }); + // This is blocking as any embedded platform views has to be flushed before + // we re-run the Dart code. + latch.Wait(); +} + // |blink::ServiceProtocol::Handler| fml::RefPtr Shell::GetServiceProtocolHandlerTaskRunner( fml::StringView method) const { diff --git a/shell/common/shell.h b/shell/common/shell.h index c8bd76731209f..574027a646a4d 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -195,6 +195,9 @@ class Shell final : public PlatformView::Delegate, const Engine& engine, fml::RefPtr message) override; + // |shell::Engine::Delegate| + void OnEngineRestart() override; + // |blink::ServiceProtocol::Handler| fml::RefPtr GetServiceProtocolHandlerTaskRunner( fml::StringView method) const override; diff --git a/shell/platform/android/io/flutter/app/FlutterPluginRegistry.java b/shell/platform/android/io/flutter/app/FlutterPluginRegistry.java index ebf9b5f3ed3e6..ef6d187093a93 100644 --- a/shell/platform/android/io/flutter/app/FlutterPluginRegistry.java +++ b/shell/platform/android/io/flutter/app/FlutterPluginRegistry.java @@ -82,6 +82,10 @@ public void detach() { mActivity = null; } + public void onEngineRestart() { + mPlatformViewsController.onEngineRestart(); + } + private class FlutterRegistrar implements Registrar { private final String pluginKey; diff --git a/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java b/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java index 0515c0291b1cf..8e179b195f9f2 100644 --- a/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java +++ b/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java @@ -69,10 +69,11 @@ public PlatformViewRegistry getRegistry() { } public void onFlutterViewDestroyed() { - for (VirtualDisplayController controller : vdControllers.values()) { - controller.dispose(); - } - vdControllers.clear(); + flushAllViews(); + } + + public void onEngineRestart() { + flushAllViews(); } @Override @@ -297,4 +298,10 @@ private int toPhysicalPixels(double logicalPixels) { return (int) Math.round(logicalPixels * density); } + private void flushAllViews() { + for (VirtualDisplayController controller : vdControllers.values()) { + controller.dispose(); + } + vdControllers.clear(); + } } diff --git a/shell/platform/android/io/flutter/view/FlutterNativeView.java b/shell/platform/android/io/flutter/view/FlutterNativeView.java index 46d8f5cb0d0d7..649ea90a57a75 100644 --- a/shell/platform/android/io/flutter/view/FlutterNativeView.java +++ b/shell/platform/android/io/flutter/view/FlutterNativeView.java @@ -198,6 +198,14 @@ private void onFirstFrame() { mFlutterView.onFirstFrame(); } + // Called by native to notify when the engine is restarted (cold reload). + @SuppressWarnings("unused") + private void onEngineRestart() { + if (mPluginRegistry == null) + return; + mPluginRegistry.onEngineRestart(); + } + private static native long nativeAttach(FlutterNativeView view); private static native void nativeDestroy(long nativePlatformViewAndroid); private static native void nativeDetach(long nativePlatformViewAndroid); diff --git a/shell/platform/android/platform_view_android.cc b/shell/platform/android/platform_view_android.cc index 808b5fa72a32b..e068a78d14230 100644 --- a/shell/platform/android/platform_view_android.cc +++ b/shell/platform/android/platform_view_android.cc @@ -157,6 +157,17 @@ void PlatformViewAndroid::HandlePlatformMessage( } } +// |shell::PlatformView| +void PlatformViewAndroid::OnEngineRestart() const { + JNIEnv* env = fml::jni::AttachCurrentThread(); + fml::jni::ScopedJavaLocalRef view = java_object_.get(env); + if (view.is_null()) { + // The Java object died. + return; + } + FlutterViewOnEngineRestart(fml::jni::AttachCurrentThread(), view.obj()); +} + void PlatformViewAndroid::DispatchSemanticsAction(JNIEnv* env, jint id, jint action, diff --git a/shell/platform/android/platform_view_android.h b/shell/platform/android/platform_view_android.h index be7cf2c197322..7c7d55d7a8b9e 100644 --- a/shell/platform/android/platform_view_android.h +++ b/shell/platform/android/platform_view_android.h @@ -83,6 +83,9 @@ class PlatformViewAndroid final : public PlatformView { void HandlePlatformMessage( fml::RefPtr message) override; + // |shell::PlatformView| + void OnEngineRestart() const override; + // |shell::PlatformView| std::unique_ptr CreateVSyncWaiter() override; diff --git a/shell/platform/android/platform_view_android_jni.cc b/shell/platform/android/platform_view_android_jni.cc index 933a34dff9427..4c602a52dc302 100644 --- a/shell/platform/android/platform_view_android_jni.cc +++ b/shell/platform/android/platform_view_android_jni.cc @@ -96,6 +96,12 @@ void FlutterViewOnFirstFrame(JNIEnv* env, jobject obj) { FML_CHECK(CheckException(env)); } +static jmethodID g_on_engine_restart_method = nullptr; +void FlutterViewOnEngineRestart(JNIEnv* env, jobject obj) { + env->CallVoidMethod(obj, g_on_engine_restart_method); + FML_CHECK(CheckException(env)); +} + static jmethodID g_attach_to_gl_context_method = nullptr; void SurfaceTextureAttachToGLContext(JNIEnv* env, jobject obj, jint textureId) { env->CallVoidMethod(obj, g_attach_to_gl_context_method, textureId); @@ -698,6 +704,13 @@ bool PlatformViewAndroid::Register(JNIEnv* env) { return false; } + g_on_engine_restart_method = env->GetMethodID( + g_flutter_native_view_class->obj(), "onEngineRestart", "()V"); + + if (g_on_engine_restart_method == nullptr) { + return false; + } + g_attach_to_gl_context_method = env->GetMethodID( g_surface_texture_class->obj(), "attachToGLContext", "(I)V"); diff --git a/shell/platform/android/platform_view_android_jni.h b/shell/platform/android/platform_view_android_jni.h index 4927e35cc981b..9fefc4b750a26 100644 --- a/shell/platform/android/platform_view_android_jni.h +++ b/shell/platform/android/platform_view_android_jni.h @@ -34,6 +34,8 @@ void FlutterViewUpdateCustomAccessibilityActions(JNIEnv* env, void FlutterViewOnFirstFrame(JNIEnv* env, jobject obj); +void FlutterViewOnEngineRestart(JNIEnv* env, jobject obj); + void SurfaceTextureAttachToGLContext(JNIEnv* env, jobject obj, jint textureId); void SurfaceTextureUpdateTexImage(JNIEnv* env, jobject obj); From 63891d1688b88d52cd2782cdedb7aebba30d1b64 Mon Sep 17 00:00:00 2001 From: Amir Hardon Date: Thu, 2 Aug 2018 14:18:52 -0700 Subject: [PATCH 2/3] review comments followup --- shell/common/shell.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 16dd45fc68362..f76066ef94c09 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -742,9 +742,13 @@ void Shell::OnEngineHandlePlatformMessage( // |shell::Engine::Delegate| void Shell::OnEngineRestart() { + FML_DCHECK(is_setup_); + FML_DCHECK(task_runners_.GetUITaskRunner()->RunsTasksOnCurrentThread()); + fml::AutoResetWaitableEvent latch; - task_runners_.GetPlatformTaskRunner()->PostTask( - [view = platform_view_->GetWeakPtr(), &latch] { + fml::TaskRunner::RunNowOrPostTask( + task_runners_.GetPlatformTaskRunner(), + [view = platform_view_->GetWeakPtr(), &latch]() { if (view) { view->OnEngineRestart(); } From 1585169a77986b5746e414b5cf44ed7d52796f37 Mon Sep 17 00:00:00 2001 From: Amir Hardon Date: Thu, 2 Aug 2018 16:22:32 -0700 Subject: [PATCH 3/3] rename to OnPreEngineRestart, call before Clone --- shell/common/engine.cc | 2 +- shell/common/engine.h | 2 +- shell/common/platform_view.cc | 2 +- shell/common/platform_view.h | 2 +- shell/common/shell.cc | 4 ++-- shell/common/shell.h | 2 +- .../android/io/flutter/app/FlutterPluginRegistry.java | 4 ++-- .../io/flutter/plugin/platform/PlatformViewsController.java | 2 +- shell/platform/android/io/flutter/view/FlutterNativeView.java | 4 ++-- shell/platform/android/platform_view_android.cc | 4 ++-- shell/platform/android/platform_view_android.h | 2 +- shell/platform/android/platform_view_android_jni.cc | 4 ++-- shell/platform/android/platform_view_android_jni.h | 2 +- 13 files changed, 18 insertions(+), 18 deletions(-) diff --git a/shell/common/engine.cc b/shell/common/engine.cc index a0b606e7b4a7a..3c4bc493f1ec7 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -101,9 +101,9 @@ bool Engine::Restart(RunConfiguration configuration) { FML_LOG(ERROR) << "Engine run configuration was invalid."; return false; } + delegate_.OnPreEngineRestart(); runtime_controller_ = runtime_controller_->Clone(); UpdateAssetManager(nullptr); - delegate_.OnEngineRestart(); return Run(std::move(configuration)); } diff --git a/shell/common/engine.h b/shell/common/engine.h index 5b7ee6d1e1f40..2dfe73b78bd35 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -40,7 +40,7 @@ class Engine final : public blink::RuntimeDelegate { const Engine& engine, fml::RefPtr message) = 0; - virtual void OnEngineRestart() = 0; + virtual void OnPreEngineRestart() = 0; }; Engine(Delegate& delegate, diff --git a/shell/common/platform_view.cc b/shell/common/platform_view.cc index d31201dc6191d..dc04f6302717f 100644 --- a/shell/common/platform_view.cc +++ b/shell/common/platform_view.cc @@ -88,7 +88,7 @@ void PlatformView::HandlePlatformMessage( response->CompleteEmpty(); } -void PlatformView::OnEngineRestart() const {} +void PlatformView::OnPreEngineRestart() const {} void PlatformView::RegisterTexture(std::shared_ptr texture) { delegate_.OnPlatformViewRegisterTexture(*this, std::move(texture)); diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h index a877875cae469..0d09a7c1657e7 100644 --- a/shell/common/platform_view.h +++ b/shell/common/platform_view.h @@ -108,7 +108,7 @@ class PlatformView { virtual void HandlePlatformMessage( fml::RefPtr message); - virtual void OnEngineRestart() const; + virtual void OnPreEngineRestart() const; void SetNextFrameCallback(fml::closure closure); diff --git a/shell/common/shell.cc b/shell/common/shell.cc index f76066ef94c09..c992bc4b3fc40 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -741,7 +741,7 @@ void Shell::OnEngineHandlePlatformMessage( } // |shell::Engine::Delegate| -void Shell::OnEngineRestart() { +void Shell::OnPreEngineRestart() { FML_DCHECK(is_setup_); FML_DCHECK(task_runners_.GetUITaskRunner()->RunsTasksOnCurrentThread()); @@ -750,7 +750,7 @@ void Shell::OnEngineRestart() { task_runners_.GetPlatformTaskRunner(), [view = platform_view_->GetWeakPtr(), &latch]() { if (view) { - view->OnEngineRestart(); + view->OnPreEngineRestart(); } latch.Signal(); }); diff --git a/shell/common/shell.h b/shell/common/shell.h index 574027a646a4d..41798664cda63 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -196,7 +196,7 @@ class Shell final : public PlatformView::Delegate, fml::RefPtr message) override; // |shell::Engine::Delegate| - void OnEngineRestart() override; + void OnPreEngineRestart() override; // |blink::ServiceProtocol::Handler| fml::RefPtr GetServiceProtocolHandlerTaskRunner( diff --git a/shell/platform/android/io/flutter/app/FlutterPluginRegistry.java b/shell/platform/android/io/flutter/app/FlutterPluginRegistry.java index ef6d187093a93..67ef70a3c566e 100644 --- a/shell/platform/android/io/flutter/app/FlutterPluginRegistry.java +++ b/shell/platform/android/io/flutter/app/FlutterPluginRegistry.java @@ -82,8 +82,8 @@ public void detach() { mActivity = null; } - public void onEngineRestart() { - mPlatformViewsController.onEngineRestart(); + public void onPreEngineRestart() { + mPlatformViewsController.onPreEngineRestart(); } private class FlutterRegistrar implements Registrar { diff --git a/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java b/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java index 8e179b195f9f2..8c8993ccbd17f 100644 --- a/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java +++ b/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java @@ -72,7 +72,7 @@ public void onFlutterViewDestroyed() { flushAllViews(); } - public void onEngineRestart() { + public void onPreEngineRestart() { flushAllViews(); } diff --git a/shell/platform/android/io/flutter/view/FlutterNativeView.java b/shell/platform/android/io/flutter/view/FlutterNativeView.java index 649ea90a57a75..f7b0b1b362484 100644 --- a/shell/platform/android/io/flutter/view/FlutterNativeView.java +++ b/shell/platform/android/io/flutter/view/FlutterNativeView.java @@ -200,10 +200,10 @@ private void onFirstFrame() { // Called by native to notify when the engine is restarted (cold reload). @SuppressWarnings("unused") - private void onEngineRestart() { + private void onPreEngineRestart() { if (mPluginRegistry == null) return; - mPluginRegistry.onEngineRestart(); + mPluginRegistry.onPreEngineRestart(); } private static native long nativeAttach(FlutterNativeView view); diff --git a/shell/platform/android/platform_view_android.cc b/shell/platform/android/platform_view_android.cc index e068a78d14230..2df879cb40ad6 100644 --- a/shell/platform/android/platform_view_android.cc +++ b/shell/platform/android/platform_view_android.cc @@ -158,14 +158,14 @@ void PlatformViewAndroid::HandlePlatformMessage( } // |shell::PlatformView| -void PlatformViewAndroid::OnEngineRestart() const { +void PlatformViewAndroid::OnPreEngineRestart() const { JNIEnv* env = fml::jni::AttachCurrentThread(); fml::jni::ScopedJavaLocalRef view = java_object_.get(env); if (view.is_null()) { // The Java object died. return; } - FlutterViewOnEngineRestart(fml::jni::AttachCurrentThread(), view.obj()); + FlutterViewOnPreEngineRestart(fml::jni::AttachCurrentThread(), view.obj()); } void PlatformViewAndroid::DispatchSemanticsAction(JNIEnv* env, diff --git a/shell/platform/android/platform_view_android.h b/shell/platform/android/platform_view_android.h index 7c7d55d7a8b9e..c3903d59e712b 100644 --- a/shell/platform/android/platform_view_android.h +++ b/shell/platform/android/platform_view_android.h @@ -84,7 +84,7 @@ class PlatformViewAndroid final : public PlatformView { fml::RefPtr message) override; // |shell::PlatformView| - void OnEngineRestart() const override; + void OnPreEngineRestart() const override; // |shell::PlatformView| std::unique_ptr CreateVSyncWaiter() override; diff --git a/shell/platform/android/platform_view_android_jni.cc b/shell/platform/android/platform_view_android_jni.cc index 4c602a52dc302..3426d5bbb5d3d 100644 --- a/shell/platform/android/platform_view_android_jni.cc +++ b/shell/platform/android/platform_view_android_jni.cc @@ -97,7 +97,7 @@ void FlutterViewOnFirstFrame(JNIEnv* env, jobject obj) { } static jmethodID g_on_engine_restart_method = nullptr; -void FlutterViewOnEngineRestart(JNIEnv* env, jobject obj) { +void FlutterViewOnPreEngineRestart(JNIEnv* env, jobject obj) { env->CallVoidMethod(obj, g_on_engine_restart_method); FML_CHECK(CheckException(env)); } @@ -705,7 +705,7 @@ bool PlatformViewAndroid::Register(JNIEnv* env) { } g_on_engine_restart_method = env->GetMethodID( - g_flutter_native_view_class->obj(), "onEngineRestart", "()V"); + g_flutter_native_view_class->obj(), "onPreEngineRestart", "()V"); if (g_on_engine_restart_method == nullptr) { return false; diff --git a/shell/platform/android/platform_view_android_jni.h b/shell/platform/android/platform_view_android_jni.h index 9fefc4b750a26..9a4a411a9d303 100644 --- a/shell/platform/android/platform_view_android_jni.h +++ b/shell/platform/android/platform_view_android_jni.h @@ -34,7 +34,7 @@ void FlutterViewUpdateCustomAccessibilityActions(JNIEnv* env, void FlutterViewOnFirstFrame(JNIEnv* env, jobject obj); -void FlutterViewOnEngineRestart(JNIEnv* env, jobject obj); +void FlutterViewOnPreEngineRestart(JNIEnv* env, jobject obj); void SurfaceTextureAttachToGLContext(JNIEnv* env, jobject obj, jint textureId);