diff --git a/engine/src/flutter/runtime/dart_service_isolate.cc b/engine/src/flutter/runtime/dart_service_isolate.cc index 5d498fc5dd..2a143de372 100644 --- a/engine/src/flutter/runtime/dart_service_isolate.cc +++ b/engine/src/flutter/runtime/dart_service_isolate.cc @@ -32,7 +32,7 @@ namespace { static Dart_LibraryTagHandler g_embedder_tag_handler; static tonic::DartLibraryNatives* g_natives; -static std::string observatory_uri_; +static std::string g_observatory_uri; Dart_NativeFunction GetNativeFunction(Dart_Handle name, int argument_count, @@ -63,7 +63,7 @@ void DartServiceIsolate::NotifyServerState(Dart_NativeArguments args) { return; } - observatory_uri_ = uri; + g_observatory_uri = uri; // Collect callbacks to fire in a separate collection and invoke them outside // the lock. @@ -81,10 +81,6 @@ void DartServiceIsolate::NotifyServerState(Dart_NativeArguments args) { } } -std::string DartServiceIsolate::GetObservatoryUri() { - return observatory_uri_; -} - DartServiceIsolate::CallbackHandle DartServiceIsolate::AddServerStatusCallback( DartServiceIsolate::ObservatoryServerStateCallback callback) { if (!callback) { @@ -102,8 +98,8 @@ DartServiceIsolate::CallbackHandle DartServiceIsolate::AddServerStatusCallback( callbacks_.insert(std::move(callback_pointer)); } - if (!observatory_uri_.empty()) { - callback(observatory_uri_); + if (!g_observatory_uri.empty()) { + callback(g_observatory_uri); } return handle; diff --git a/engine/src/flutter/runtime/dart_service_isolate.h b/engine/src/flutter/runtime/dart_service_isolate.h index c042a07715..10ff16192e 100644 --- a/engine/src/flutter/runtime/dart_service_isolate.h +++ b/engine/src/flutter/runtime/dart_service_isolate.h @@ -29,8 +29,6 @@ class DartServiceIsolate { bool disable_service_auth_codes, char** error); - static std::string GetObservatoryUri(); - using CallbackHandle = ptrdiff_t; // Returns a handle for the callback that can be used in diff --git a/engine/src/flutter/shell/platform/android/flutter_main.cc b/engine/src/flutter/shell/platform/android/flutter_main.cc index bae67459e0..b12fad5750 100644 --- a/engine/src/flutter/shell/platform/android/flutter_main.cc +++ b/engine/src/flutter/shell/platform/android/flutter_main.cc @@ -33,10 +33,20 @@ extern const intptr_t kPlatformStrongDillSize; #endif } -FlutterMain::FlutterMain(flutter::Settings settings) - : settings_(std::move(settings)) {} +namespace { -FlutterMain::~FlutterMain() = default; +fml::jni::ScopedJavaGlobalRef* g_flutter_jni_class = nullptr; + +} // anonymous namespace + +FlutterMain::FlutterMain(flutter::Settings settings) + : settings_(std::move(settings)), observatory_uri_callback_() {} + +FlutterMain::~FlutterMain() { + if (observatory_uri_callback_) { + DartServiceIsolate::RemoveServerStatusCallback(observatory_uri_callback_); + } +} static std::unique_ptr g_flutter_main; @@ -114,6 +124,37 @@ void FlutterMain::Init(JNIEnv* env, // Not thread safe. Will be removed when FlutterMain is refactored to no // longer be a singleton. g_flutter_main.reset(new FlutterMain(std::move(settings))); + + g_flutter_main->SetupObservatoryUriCallback(env); +} + +void FlutterMain::SetupObservatoryUriCallback(JNIEnv* env) { + g_flutter_jni_class = new fml::jni::ScopedJavaGlobalRef( + env, env->FindClass("io/flutter/embedding/engine/FlutterJNI")); + if (g_flutter_jni_class->is_null()) { + return; + } + jfieldID uri_field = env->GetStaticFieldID( + g_flutter_jni_class->obj(), "observatoryUri", "Ljava/lang/String;"); + if (uri_field == nullptr) { + return; + } + + auto set_uri = [env, uri_field](std::string uri) { + fml::jni::ScopedJavaLocalRef java_uri = + fml::jni::StringToJavaString(env, uri); + env->SetStaticObjectField(g_flutter_jni_class->obj(), uri_field, + java_uri.obj()); + }; + + fml::MessageLoop::EnsureInitializedForCurrentThread(); + fml::RefPtr platform_runner = + fml::MessageLoop::GetCurrent().GetTaskRunner(); + + observatory_uri_callback_ = DartServiceIsolate::AddServerStatusCallback( + [platform_runner, set_uri](std::string uri) { + platform_runner->PostTask([uri, set_uri] { set_uri(uri); }); + }); } static void RecordStartTimestamp(JNIEnv* env, diff --git a/engine/src/flutter/shell/platform/android/flutter_main.h b/engine/src/flutter/shell/platform/android/flutter_main.h index 5f6b3eb075..d0d9da9c4a 100644 --- a/engine/src/flutter/shell/platform/android/flutter_main.h +++ b/engine/src/flutter/shell/platform/android/flutter_main.h @@ -9,6 +9,7 @@ #include "flutter/common/settings.h" #include "flutter/fml/macros.h" +#include "flutter/runtime/dart_service_isolate.h" namespace flutter { @@ -24,6 +25,7 @@ class FlutterMain { private: const flutter::Settings settings_; + DartServiceIsolate::CallbackHandle observatory_uri_callback_; FlutterMain(flutter::Settings settings); @@ -35,6 +37,8 @@ class FlutterMain { jstring appRootPath, jstring engineCachesPath); + void SetupObservatoryUriCallback(JNIEnv* env); + FML_DISALLOW_COPY_AND_ASSIGN(FlutterMain); }; diff --git a/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java b/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java index df4d53b305..ae4ffab22b 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java @@ -86,17 +86,21 @@ import io.flutter.view.AccessibilityBridge; * To invoke a native method that is not associated with a platform view, invoke it statically: * * {@code - * String uri = FlutterJNI.nativeGetObservatoryUri(); + * bool enabled = FlutterJNI.nativeGetIsSoftwareRenderingEnabled(); * } */ public class FlutterJNI { private static final String TAG = "FlutterJNI"; + // This is set from native code via JNI. + private static String observatoryUri; + @UiThread public static native boolean nativeGetIsSoftwareRenderingEnabled(); - @UiThread - public static native String nativeGetObservatoryUri(); + public static String getObservatoryUri() { + return observatoryUri; + } private Long nativePlatformViewId; private FlutterRenderer.RenderSurface renderSurface; diff --git a/engine/src/flutter/shell/platform/android/io/flutter/view/FlutterNativeView.java b/engine/src/flutter/shell/platform/android/io/flutter/view/FlutterNativeView.java index 8e227bbef7..3c22da83ce 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/view/FlutterNativeView.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/view/FlutterNativeView.java @@ -135,7 +135,7 @@ public class FlutterNativeView implements BinaryMessenger { } public static String getObservatoryUri() { - return FlutterJNI.nativeGetObservatoryUri(); + return FlutterJNI.getObservatoryUri(); } @Override diff --git a/engine/src/flutter/shell/platform/android/platform_view_android_jni.cc b/engine/src/flutter/shell/platform/android/platform_view_android_jni.cc index 4a40f605f5..b2e9e6be3e 100644 --- a/engine/src/flutter/shell/platform/android/platform_view_android_jni.cc +++ b/engine/src/flutter/shell/platform/android/platform_view_android_jni.cc @@ -164,11 +164,6 @@ static void DestroyJNI(JNIEnv* env, jobject jcaller, jlong shell_holder) { delete ANDROID_SHELL_HOLDER; } -static jstring GetObservatoryUri(JNIEnv* env, jclass clazz) { - return env->NewStringUTF( - flutter::DartServiceIsolate::GetObservatoryUri().c_str()); -} - static void SurfaceCreated(JNIEnv* env, jobject jcaller, jlong shell_holder, @@ -553,11 +548,6 @@ bool RegisterApi(JNIEnv* env) { "Ljava/lang/String;Landroid/content/res/AssetManager;)V", .fnPtr = reinterpret_cast(&RunBundleAndSnapshotFromLibrary), }, - { - .name = "nativeGetObservatoryUri", - .signature = "()Ljava/lang/String;", - .fnPtr = reinterpret_cast(&GetObservatoryUri), - }, { .name = "nativeDispatchEmptyPlatformMessage", .signature = "(JLjava/lang/String;I)V",