Skip to content

Commit

Permalink
Flush all embedded Android views on hot restart. (flutter#5929)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
amirh authored Aug 3, 2018
1 parent 9fe6a57 commit ffbafc8
Show file tree
Hide file tree
Showing 13 changed files with 81 additions and 4 deletions.
1 change: 1 addition & 0 deletions shell/common/engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ bool Engine::Restart(RunConfiguration configuration) {
FML_LOG(ERROR) << "Engine run configuration was invalid.";
return false;
}
delegate_.OnPreEngineRestart();
runtime_controller_ = runtime_controller_->Clone();
UpdateAssetManager(nullptr);
return Run(std::move(configuration));
Expand Down
2 changes: 2 additions & 0 deletions shell/common/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ class Engine final : public blink::RuntimeDelegate {
virtual void OnEngineHandlePlatformMessage(
const Engine& engine,
fml::RefPtr<blink::PlatformMessage> message) = 0;

virtual void OnPreEngineRestart() = 0;
};

Engine(Delegate& delegate,
Expand Down
2 changes: 2 additions & 0 deletions shell/common/platform_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ void PlatformView::HandlePlatformMessage(
response->CompleteEmpty();
}

void PlatformView::OnPreEngineRestart() const {}

void PlatformView::RegisterTexture(std::shared_ptr<flow::Texture> texture) {
delegate_.OnPlatformViewRegisterTexture(*this, std::move(texture));
}
Expand Down
2 changes: 2 additions & 0 deletions shell/common/platform_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ class PlatformView {
virtual void HandlePlatformMessage(
fml::RefPtr<blink::PlatformMessage> message);

virtual void OnPreEngineRestart() const;

void SetNextFrameCallback(fml::closure closure);

void DispatchPointerDataPacket(
Expand Down
19 changes: 19 additions & 0 deletions shell/common/shell.cc
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,25 @@ void Shell::OnEngineHandlePlatformMessage(
});
}

// |shell::Engine::Delegate|
void Shell::OnPreEngineRestart() {
FML_DCHECK(is_setup_);
FML_DCHECK(task_runners_.GetUITaskRunner()->RunsTasksOnCurrentThread());

fml::AutoResetWaitableEvent latch;
fml::TaskRunner::RunNowOrPostTask(
task_runners_.GetPlatformTaskRunner(),
[view = platform_view_->GetWeakPtr(), &latch]() {
if (view) {
view->OnPreEngineRestart();
}
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<fml::TaskRunner> Shell::GetServiceProtocolHandlerTaskRunner(
fml::StringView method) const {
Expand Down
3 changes: 3 additions & 0 deletions shell/common/shell.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@ class Shell final : public PlatformView::Delegate,
const Engine& engine,
fml::RefPtr<blink::PlatformMessage> message) override;

// |shell::Engine::Delegate|
void OnPreEngineRestart() override;

// |blink::ServiceProtocol::Handler|
fml::RefPtr<fml::TaskRunner> GetServiceProtocolHandlerTaskRunner(
fml::StringView method) const override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ public void detach() {
mActivity = null;
}

public void onPreEngineRestart() {
mPlatformViewsController.onPreEngineRestart();
}

private class FlutterRegistrar implements Registrar {
private final String pluginKey;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,11 @@ public PlatformViewRegistry getRegistry() {
}

public void onFlutterViewDestroyed() {
for (VirtualDisplayController controller : vdControllers.values()) {
controller.dispose();
}
vdControllers.clear();
flushAllViews();
}

public void onPreEngineRestart() {
flushAllViews();
}

@Override
Expand Down Expand Up @@ -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();
}
}
8 changes: 8 additions & 0 deletions shell/platform/android/io/flutter/view/FlutterNativeView.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 onPreEngineRestart() {
if (mPluginRegistry == null)
return;
mPluginRegistry.onPreEngineRestart();
}

private static native long nativeAttach(FlutterNativeView view);
private static native void nativeDestroy(long nativePlatformViewAndroid);
private static native void nativeDetach(long nativePlatformViewAndroid);
Expand Down
11 changes: 11 additions & 0 deletions shell/platform/android/platform_view_android.cc
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,17 @@ void PlatformViewAndroid::HandlePlatformMessage(
}
}

// |shell::PlatformView|
void PlatformViewAndroid::OnPreEngineRestart() const {
JNIEnv* env = fml::jni::AttachCurrentThread();
fml::jni::ScopedJavaLocalRef<jobject> view = java_object_.get(env);
if (view.is_null()) {
// The Java object died.
return;
}
FlutterViewOnPreEngineRestart(fml::jni::AttachCurrentThread(), view.obj());
}

void PlatformViewAndroid::DispatchSemanticsAction(JNIEnv* env,
jint id,
jint action,
Expand Down
3 changes: 3 additions & 0 deletions shell/platform/android/platform_view_android.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ class PlatformViewAndroid final : public PlatformView {
void HandlePlatformMessage(
fml::RefPtr<blink::PlatformMessage> message) override;

// |shell::PlatformView|
void OnPreEngineRestart() const override;

// |shell::PlatformView|
std::unique_ptr<VsyncWaiter> CreateVSyncWaiter() override;

Expand Down
13 changes: 13 additions & 0 deletions shell/platform/android/platform_view_android_jni.cc
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ void FlutterViewOnFirstFrame(JNIEnv* env, jobject obj) {
FML_CHECK(CheckException(env));
}

static jmethodID g_on_engine_restart_method = nullptr;
void FlutterViewOnPreEngineRestart(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);
Expand Down Expand Up @@ -698,6 +704,13 @@ bool PlatformViewAndroid::Register(JNIEnv* env) {
return false;
}

g_on_engine_restart_method = env->GetMethodID(
g_flutter_native_view_class->obj(), "onPreEngineRestart", "()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");

Expand Down
2 changes: 2 additions & 0 deletions shell/platform/android/platform_view_android_jni.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ void FlutterViewUpdateCustomAccessibilityActions(JNIEnv* env,

void FlutterViewOnFirstFrame(JNIEnv* env, jobject obj);

void FlutterViewOnPreEngineRestart(JNIEnv* env, jobject obj);

void SurfaceTextureAttachToGLContext(JNIEnv* env, jobject obj, jint textureId);

void SurfaceTextureUpdateTexImage(JNIEnv* env, jobject obj);
Expand Down

0 comments on commit ffbafc8

Please sign in to comment.