forked from firka/flutter
Use the DartServiceIsolate status callback to publish the observatory URI to the Android embedder (flutter/engine#9337)
The Android embedder had been using a JNI call to get the observatory URI from DartServiceIsolate. This call was not thread safe and was redundant with the server status callback mechanism used on iOS.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<jclass>* 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<FlutterMain> 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<jclass>(
|
||||
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<jstring> java_uri =
|
||||
fml::jni::StringToJavaString(env, uri);
|
||||
env->SetStaticObjectField(g_flutter_jni_class->obj(), uri_field,
|
||||
java_uri.obj());
|
||||
};
|
||||
|
||||
fml::MessageLoop::EnsureInitializedForCurrentThread();
|
||||
fml::RefPtr<fml::TaskRunner> 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,
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -135,7 +135,7 @@ public class FlutterNativeView implements BinaryMessenger {
|
||||
}
|
||||
|
||||
public static String getObservatoryUri() {
|
||||
return FlutterJNI.nativeGetObservatoryUri();
|
||||
return FlutterJNI.getObservatoryUri();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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<void*>(&RunBundleAndSnapshotFromLibrary),
|
||||
},
|
||||
{
|
||||
.name = "nativeGetObservatoryUri",
|
||||
.signature = "()Ljava/lang/String;",
|
||||
.fnPtr = reinterpret_cast<void*>(&GetObservatoryUri),
|
||||
},
|
||||
{
|
||||
.name = "nativeDispatchEmptyPlatformMessage",
|
||||
.signature = "(JLjava/lang/String;I)V",
|
||||
|
||||
Reference in New Issue
Block a user