Skip to content

Commit ffbafc8

Browse files
authored
Flush all embedded Android views on hot restart. (flutter#5929)
* 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. * review comments followup * rename to OnPreEngineRestart, call before Clone
1 parent 9fe6a57 commit ffbafc8

13 files changed

+81
-4
lines changed

shell/common/engine.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ bool Engine::Restart(RunConfiguration configuration) {
101101
FML_LOG(ERROR) << "Engine run configuration was invalid.";
102102
return false;
103103
}
104+
delegate_.OnPreEngineRestart();
104105
runtime_controller_ = runtime_controller_->Clone();
105106
UpdateAssetManager(nullptr);
106107
return Run(std::move(configuration));

shell/common/engine.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ class Engine final : public blink::RuntimeDelegate {
3939
virtual void OnEngineHandlePlatformMessage(
4040
const Engine& engine,
4141
fml::RefPtr<blink::PlatformMessage> message) = 0;
42+
43+
virtual void OnPreEngineRestart() = 0;
4244
};
4345

4446
Engine(Delegate& delegate,

shell/common/platform_view.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ void PlatformView::HandlePlatformMessage(
8888
response->CompleteEmpty();
8989
}
9090

91+
void PlatformView::OnPreEngineRestart() const {}
92+
9193
void PlatformView::RegisterTexture(std::shared_ptr<flow::Texture> texture) {
9294
delegate_.OnPlatformViewRegisterTexture(*this, std::move(texture));
9395
}

shell/common/platform_view.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ class PlatformView {
108108
virtual void HandlePlatformMessage(
109109
fml::RefPtr<blink::PlatformMessage> message);
110110

111+
virtual void OnPreEngineRestart() const;
112+
111113
void SetNextFrameCallback(fml::closure closure);
112114

113115
void DispatchPointerDataPacket(

shell/common/shell.cc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,25 @@ void Shell::OnEngineHandlePlatformMessage(
740740
});
741741
}
742742

743+
// |shell::Engine::Delegate|
744+
void Shell::OnPreEngineRestart() {
745+
FML_DCHECK(is_setup_);
746+
FML_DCHECK(task_runners_.GetUITaskRunner()->RunsTasksOnCurrentThread());
747+
748+
fml::AutoResetWaitableEvent latch;
749+
fml::TaskRunner::RunNowOrPostTask(
750+
task_runners_.GetPlatformTaskRunner(),
751+
[view = platform_view_->GetWeakPtr(), &latch]() {
752+
if (view) {
753+
view->OnPreEngineRestart();
754+
}
755+
latch.Signal();
756+
});
757+
// This is blocking as any embedded platform views has to be flushed before
758+
// we re-run the Dart code.
759+
latch.Wait();
760+
}
761+
743762
// |blink::ServiceProtocol::Handler|
744763
fml::RefPtr<fml::TaskRunner> Shell::GetServiceProtocolHandlerTaskRunner(
745764
fml::StringView method) const {

shell/common/shell.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,9 @@ class Shell final : public PlatformView::Delegate,
195195
const Engine& engine,
196196
fml::RefPtr<blink::PlatformMessage> message) override;
197197

198+
// |shell::Engine::Delegate|
199+
void OnPreEngineRestart() override;
200+
198201
// |blink::ServiceProtocol::Handler|
199202
fml::RefPtr<fml::TaskRunner> GetServiceProtocolHandlerTaskRunner(
200203
fml::StringView method) const override;

shell/platform/android/io/flutter/app/FlutterPluginRegistry.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ public void detach() {
8282
mActivity = null;
8383
}
8484

85+
public void onPreEngineRestart() {
86+
mPlatformViewsController.onPreEngineRestart();
87+
}
88+
8589
private class FlutterRegistrar implements Registrar {
8690
private final String pluginKey;
8791

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,11 @@ public PlatformViewRegistry getRegistry() {
6969
}
7070

7171
public void onFlutterViewDestroyed() {
72-
for (VirtualDisplayController controller : vdControllers.values()) {
73-
controller.dispose();
74-
}
75-
vdControllers.clear();
72+
flushAllViews();
73+
}
74+
75+
public void onPreEngineRestart() {
76+
flushAllViews();
7677
}
7778

7879
@Override
@@ -297,4 +298,10 @@ private int toPhysicalPixels(double logicalPixels) {
297298
return (int) Math.round(logicalPixels * density);
298299
}
299300

301+
private void flushAllViews() {
302+
for (VirtualDisplayController controller : vdControllers.values()) {
303+
controller.dispose();
304+
}
305+
vdControllers.clear();
306+
}
300307
}

shell/platform/android/io/flutter/view/FlutterNativeView.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,14 @@ private void onFirstFrame() {
198198
mFlutterView.onFirstFrame();
199199
}
200200

201+
// Called by native to notify when the engine is restarted (cold reload).
202+
@SuppressWarnings("unused")
203+
private void onPreEngineRestart() {
204+
if (mPluginRegistry == null)
205+
return;
206+
mPluginRegistry.onPreEngineRestart();
207+
}
208+
201209
private static native long nativeAttach(FlutterNativeView view);
202210
private static native void nativeDestroy(long nativePlatformViewAndroid);
203211
private static native void nativeDetach(long nativePlatformViewAndroid);

shell/platform/android/platform_view_android.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,17 @@ void PlatformViewAndroid::HandlePlatformMessage(
157157
}
158158
}
159159

160+
// |shell::PlatformView|
161+
void PlatformViewAndroid::OnPreEngineRestart() const {
162+
JNIEnv* env = fml::jni::AttachCurrentThread();
163+
fml::jni::ScopedJavaLocalRef<jobject> view = java_object_.get(env);
164+
if (view.is_null()) {
165+
// The Java object died.
166+
return;
167+
}
168+
FlutterViewOnPreEngineRestart(fml::jni::AttachCurrentThread(), view.obj());
169+
}
170+
160171
void PlatformViewAndroid::DispatchSemanticsAction(JNIEnv* env,
161172
jint id,
162173
jint action,

shell/platform/android/platform_view_android.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ class PlatformViewAndroid final : public PlatformView {
8383
void HandlePlatformMessage(
8484
fml::RefPtr<blink::PlatformMessage> message) override;
8585

86+
// |shell::PlatformView|
87+
void OnPreEngineRestart() const override;
88+
8689
// |shell::PlatformView|
8790
std::unique_ptr<VsyncWaiter> CreateVSyncWaiter() override;
8891

shell/platform/android/platform_view_android_jni.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ void FlutterViewOnFirstFrame(JNIEnv* env, jobject obj) {
9696
FML_CHECK(CheckException(env));
9797
}
9898

99+
static jmethodID g_on_engine_restart_method = nullptr;
100+
void FlutterViewOnPreEngineRestart(JNIEnv* env, jobject obj) {
101+
env->CallVoidMethod(obj, g_on_engine_restart_method);
102+
FML_CHECK(CheckException(env));
103+
}
104+
99105
static jmethodID g_attach_to_gl_context_method = nullptr;
100106
void SurfaceTextureAttachToGLContext(JNIEnv* env, jobject obj, jint textureId) {
101107
env->CallVoidMethod(obj, g_attach_to_gl_context_method, textureId);
@@ -698,6 +704,13 @@ bool PlatformViewAndroid::Register(JNIEnv* env) {
698704
return false;
699705
}
700706

707+
g_on_engine_restart_method = env->GetMethodID(
708+
g_flutter_native_view_class->obj(), "onPreEngineRestart", "()V");
709+
710+
if (g_on_engine_restart_method == nullptr) {
711+
return false;
712+
}
713+
701714
g_attach_to_gl_context_method = env->GetMethodID(
702715
g_surface_texture_class->obj(), "attachToGLContext", "(I)V");
703716

shell/platform/android/platform_view_android_jni.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ void FlutterViewUpdateCustomAccessibilityActions(JNIEnv* env,
3434

3535
void FlutterViewOnFirstFrame(JNIEnv* env, jobject obj);
3636

37+
void FlutterViewOnPreEngineRestart(JNIEnv* env, jobject obj);
38+
3739
void SurfaceTextureAttachToGLContext(JNIEnv* env, jobject obj, jint textureId);
3840

3941
void SurfaceTextureUpdateTexImage(JNIEnv* env, jobject obj);

0 commit comments

Comments
 (0)