未验证 提交 6bacf452 编写于 作者: A Alexander Aprelev 提交者: GitHub

This adds RPC call to set asset path. (#4323)

* This adds rpc call to simply set asset path.

This is needed when doing hot reload to pick up updated assets.

* Move asset_directory fetch for after view_id. Clean up return. Fix formatting.

* Add SetAssetBundlePath methods implementations for mac and ios

* Fix mac mm

* Fix formatting

* Merge and use nullptr
上级 194fb812
......@@ -387,6 +387,11 @@ void Engine::RunFromSource(const std::string& main,
RunBundleAndSource(bundle_path, main, packages);
}
void Engine::SetAssetBundlePath(const std::string& bundle_path) {
TRACE_EVENT0("flutter", "Engine::SetAssetBundlePath");
ConfigureAssetBundle(bundle_path);
}
Dart_Port Engine::GetUIIsolateMainPort() {
if (!runtime_)
return ILLEGAL_PORT;
......
......@@ -60,6 +60,7 @@ class Engine : public blink::RuntimeDelegate {
void RunFromSource(const std::string& main,
const std::string& packages,
const std::string& bundle);
void SetAssetBundlePath(const std::string& bundle_path);
Dart_Port GetUIIsolateMainPort();
std::string GetUIIsolateName();
......
......@@ -31,4 +31,7 @@ void NullPlatformView::RunFromSource(const std::string& assets_directory,
const std::string& main,
const std::string& packages) {}
void NullPlatformView::SetAssetBundlePath(const std::string& assets_directory) {
}
} // namespace shell
......@@ -26,6 +26,7 @@ class NullPlatformView : public PlatformView {
void RunFromSource(const std::string& assets_directory,
const std::string& main,
const std::string& packages) override;
void SetAssetBundlePath(const std::string& assets_directory) override;
private:
fxl::WeakPtrFactory<NullPlatformView> weak_factory_;
......
......@@ -82,6 +82,8 @@ class PlatformView : public std::enable_shared_from_this<PlatformView> {
const std::string& main,
const std::string& packages) = 0;
virtual void SetAssetBundlePath(const std::string& assets_directory) = 0;
protected:
explicit PlatformView(std::unique_ptr<Rasterizer> rasterizer);
......
......@@ -133,6 +133,8 @@ void PlatformViewServiceProtocol::RegisterHook(bool running_precompiled_code) {
}
Dart_RegisterRootServiceRequestCallback(kRunInViewExtensionName, &RunInView,
nullptr);
Dart_RegisterRootServiceRequestCallback(kSetAssetBundlePathExtensionName,
&SetAssetBundlePath, nullptr);
// [benchmark helper] Wait for the UI Thread to idle.
Dart_RegisterRootServiceRequestCallback(kFlushUIThreadTasksExtensionName,
&FlushUIThreadTasks, nullptr);
......@@ -188,16 +190,15 @@ bool PlatformViewServiceProtocol::RunInView(const char* method,
if (!view_existed) {
// If the view did not exist this request has definitely failed.
return ErrorUnknownView(json_object, view_id);
} else {
// The view existed and the isolate was created. Success.
std::stringstream response;
response << "{\"type\":\"Success\","
<< "\"view\":";
AppendFlutterView(&response, view_id_as_num, main_port, isolate_name);
response << "}";
*json_object = strdup(response.str().c_str());
return true;
}
// The view existed and the isolate was created. Success.
std::stringstream response;
response << "{\"type\":\"Success\","
<< "\"view\":";
AppendFlutterView(&response, view_id_as_num, main_port, isolate_name);
response << "}";
*json_object = strdup(response.str().c_str());
return true;
}
......@@ -391,4 +392,56 @@ bool PlatformViewServiceProtocol::FlushUIThreadTasks(const char* method,
return true;
}
const char* PlatformViewServiceProtocol::kSetAssetBundlePathExtensionName =
"_flutter.setAssetBundlePath";
bool PlatformViewServiceProtocol::SetAssetBundlePath(const char* method,
const char** param_keys,
const char** param_values,
intptr_t num_params,
void* user_data,
const char** json_object) {
const char* view_id =
ValueForKey(param_keys, param_values, num_params, "viewId");
if (view_id == nullptr) {
return ErrorMissingParameter(json_object, "viewId");
}
if (strncmp(view_id, kViewIdPrefx, kViewIdPrefxLength) != 0) {
return ErrorBadParameter(json_object, "viewId", view_id);
}
const char* asset_directory =
ValueForKey(param_keys, param_values, num_params, "assetDirectory");
if (asset_directory == nullptr) {
return ErrorMissingParameter(json_object, "assetDirectory");
}
// Convert the actual flutter view hex id into a number.
uintptr_t view_id_as_num =
std::stoull((view_id + kViewIdPrefxLength), nullptr, 16);
// Ask the Shell to update asset bundle path in the specified view.
// This will run a task on the UI thread before returning.
Shell& shell = Shell::Shared();
bool view_existed = false;
Dart_Port main_port = ILLEGAL_PORT;
std::string isolate_name;
shell.SetAssetBundlePathInPlatformView(view_id_as_num, asset_directory,
&view_existed, &main_port,
&isolate_name);
if (!view_existed) {
// If the view did not exist this request has definitely failed.
return ErrorUnknownView(json_object, view_id);
}
// The view existed and the isolate was created. Success.
std::stringstream response;
response << "{\"type\":\"Success\","
<< "\"view\":";
AppendFlutterView(&response, view_id_as_num, main_port, isolate_name);
response << "}";
*json_object = strdup(response.str().c_str());
return true;
}
} // namespace shell
......@@ -70,6 +70,14 @@ class PlatformViewServiceProtocol {
intptr_t num_params,
void* user_data,
const char** json_object);
static const char* kSetAssetBundlePathExtensionName;
static bool SetAssetBundlePath(const char* method,
const char** param_keys,
const char** param_values,
intptr_t num_params,
void* user_data,
const char** json_object);
};
} // namespace shell
......
......@@ -300,4 +300,60 @@ void Shell::RunInPlatformViewUIThread(uintptr_t view_id,
latch->Signal();
}
void Shell::SetAssetBundlePathInPlatformView(uintptr_t view_id,
const char* asset_directory,
bool* view_existed,
int64_t* dart_isolate_id,
std::string* isolate_name) {
fxl::AutoResetWaitableEvent latch;
FXL_DCHECK(view_id != 0);
FXL_DCHECK(asset_directory);
FXL_DCHECK(view_existed);
blink::Threads::UI()->PostTask([this, view_id, asset_directory, view_existed,
dart_isolate_id, isolate_name, &latch]() {
SetAssetBundlePathInPlatformViewUIThread(view_id, asset_directory,
view_existed, dart_isolate_id,
isolate_name, &latch);
});
latch.Wait();
}
void Shell::SetAssetBundlePathInPlatformViewUIThread(
uintptr_t view_id,
const std::string& assets_directory,
bool* view_existed,
int64_t* dart_isolate_id,
std::string* isolate_name,
fxl::AutoResetWaitableEvent* latch) {
FXL_DCHECK(ui_thread_checker_ &&
ui_thread_checker_->IsCreationThreadCurrent());
*view_existed = false;
IteratePlatformViews([
view_id, // argument
assets_directory = std::move(assets_directory), // argument
&view_existed, // out
&dart_isolate_id, // out
&isolate_name // out
](PlatformView * view)
->bool {
if (reinterpret_cast<uintptr_t>(view) != view_id) {
// Keep looking.
return true;
}
*view_existed = true;
view->SetAssetBundlePath(assets_directory);
*dart_isolate_id =
view->engine().GetUIIsolateMainPort();
*isolate_name = view->engine().GetUIIsolateName();
// We found the requested view. Stop iterating over
// platform views.
return false;
});
latch->Signal();
}
} // namespace shell
......@@ -54,6 +54,12 @@ class Shell {
int64_t* dart_isolate_id,
std::string* isolate_name);
void SetAssetBundlePathInPlatformView(uintptr_t view_id,
const char* asset_directory,
bool* view_existed,
int64_t* dart_isolate_id,
std::string* isolate_name);
private:
fxl::CommandLine command_line_;
std::unique_ptr<fml::Thread> gpu_thread_;
......@@ -84,6 +90,14 @@ class Shell {
std::string* isolate_name,
fxl::AutoResetWaitableEvent* latch);
void SetAssetBundlePathInPlatformViewUIThread(
uintptr_t view_id,
const std::string& main,
bool* view_existed,
int64_t* dart_isolate_id,
std::string* isolate_name,
fxl::AutoResetWaitableEvent* latch);
FXL_DISALLOW_COPY_AND_ASSIGN(Shell);
};
......
......@@ -76,6 +76,11 @@ public class FlutterNativeView implements BinaryMessenger {
nativeRunBundleAndSource(mNativePlatformView, assetsDirectory, main, packages);
}
public void setAssetBundlePathOnUI(final String assetsDirectory) {
assertAttached();
nativeSetAssetBundlePathOnUI(mNativePlatformView, assetsDirectory);
}
public static String getObservatoryUri() {
return nativeGetObservatoryUri();
}
......@@ -196,6 +201,9 @@ public class FlutterNativeView implements BinaryMessenger {
String main,
String packages);
private static native void nativeSetAssetBundlePathOnUI(long nativePlatformViewAndroid,
String bundlePath);
private static native String nativeGetObservatoryUri();
// Send an empty platform message to Dart.
......
......@@ -647,6 +647,30 @@ public class FlutterView extends SurfaceView
}
}
private void setAssetBundlePath(final String assetsDirectory) {
Runnable runnable = new Runnable() {
public void run() {
assertAttached();
mNativeView.setAssetBundlePathOnUI(assetsDirectory);
synchronized (this) {
notify();
}
}
};
try {
synchronized (runnable) {
// Post to the Android UI thread and wait for the response.
post(runnable);
runnable.wait();
}
} catch (InterruptedException e) {
Log.e(TAG, "Thread got interrupted waiting for " +
"setAssetBundlePath to finish", e);
}
}
/**
* Return the most recent frame as a bitmap.
*
......
......@@ -237,6 +237,14 @@ void PlatformViewAndroid::RunBundleAndSource(std::string bundle_path,
});
}
void PlatformViewAndroid::SetAssetBundlePathOnUI(std::string bundle_path) {
blink::Threads::UI()->PostTask(
[ engine = engine_->GetWeakPtr(), bundle_path = std::move(bundle_path) ] {
if (engine)
engine->SetAssetBundlePath(std::move(bundle_path));
});
}
void PlatformViewAndroid::SetViewportMetrics(jfloat device_pixel_ratio,
jint physical_width,
jint physical_height,
......@@ -570,6 +578,40 @@ void PlatformViewAndroid::RunFromSource(const std::string& assets_directory,
fml::jni::DetachFromVM();
}
void PlatformViewAndroid::SetAssetBundlePath(
const std::string& assets_directory) {
JNIEnv* env = fml::jni::AttachCurrentThread();
FXL_CHECK(env);
{
fml::jni::ScopedJavaLocalRef<jobject> local_flutter_view =
flutter_view_.get(env);
if (local_flutter_view.is_null()) {
// Collected.
return;
}
// Grab the class of the flutter view.
jclass flutter_view_class = env->GetObjectClass(local_flutter_view.obj());
FXL_CHECK(flutter_view_class);
// Grab the setAssetBundlePath method id.
jmethodID method_id = env->GetMethodID(
flutter_view_class, "setAssetBundlePathOnUI", "(Ljava/lang/String;)V");
FXL_CHECK(method_id);
// Invoke setAssetBundlePath on the Android UI thread.
jstring java_assets_directory = env->NewStringUTF(assets_directory.c_str());
FXL_CHECK(java_assets_directory);
env->CallVoidMethod(local_flutter_view.obj(), method_id,
java_assets_directory);
}
// Detaching from the VM deletes any stray local references.
fml::jni::DetachFromVM();
}
void PlatformViewAndroid::RegisterExternalTexture(
int64_t texture_id,
const fml::jni::JavaObjectWeakGlobalRef& surface_texture) {
......
......@@ -107,6 +107,10 @@ class PlatformViewAndroid : public PlatformView {
const std::string& main,
const std::string& packages) override;
void SetAssetBundlePathOnUI(std::string bundle_path);
void SetAssetBundlePath(const std::string& assets_directory) override;
void RegisterExternalTexture(
int64_t texture_id,
const fml::jni::JavaObjectWeakGlobalRef& surface_texture);
......
......@@ -181,6 +181,14 @@ void RunBundleAndSource(JNIEnv* env,
fml::jni::JavaStringToString(env, packages));
}
void SetAssetBundlePathOnUI(JNIEnv* env,
jobject jcaller,
jlong platform_view,
jstring bundlePath) {
return PLATFORM_VIEW->SetAssetBundlePathOnUI(
fml::jni::JavaStringToString(env, bundlePath));
}
static void SetViewportMetrics(JNIEnv* env,
jobject jcaller,
jlong platform_view,
......@@ -352,6 +360,11 @@ bool PlatformViewAndroid::Register(JNIEnv* env) {
"(JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
.fnPtr = reinterpret_cast<void*>(&shell::RunBundleAndSource),
},
{
.name = "nativeSetAssetBundlePathOnUI",
.signature = "(JLjava/lang/String;)V",
.fnPtr = reinterpret_cast<void*>(&shell::SetAssetBundlePathOnUI),
},
{
.name = "nativeDetach",
.signature = "(J)V",
......
......@@ -41,6 +41,8 @@ class PlatformViewMac : public PlatformView, public GPUSurfaceGLDelegate {
const std::string& main,
const std::string& packages) override;
void SetAssetBundlePath(const std::string& assets_directory) override;
private:
fml::scoped_nsobject<NSOpenGLView> opengl_view_;
fml::scoped_nsobject<NSOpenGLContext> resource_loading_context_;
......@@ -51,6 +53,8 @@ class PlatformViewMac : public PlatformView, public GPUSurfaceGLDelegate {
const std::string& main,
const std::string& packages);
void SetAssetBundlePathOnUI(const std::string& assets_directory);
FXL_DISALLOW_COPY_AND_ASSIGN(PlatformViewMac);
};
......
......@@ -73,6 +73,13 @@ void PlatformViewMac::SetupAndLoadFromSource(const std::string& assets_directory
});
}
void PlatformViewMac::SetAssetBundlePathOnUI(const std::string& assets_directory) {
blink::Threads::UI()->PostTask([ engine = engine().GetWeakPtr(), assets_directory ] {
if (engine)
engine->SetAssetBundlePath(assets_directory);
});
}
intptr_t PlatformViewMac::GLContextFBO() const {
// Default window bound framebuffer FBO 0.
return 0;
......@@ -153,4 +160,16 @@ void PlatformViewMac::RunFromSource(const std::string& assets_directory,
delete latch;
}
void PlatformViewMac::SetAssetBundlePath(const std::string& assets_directory) {
auto latch = new fxl::ManualResetWaitableEvent();
dispatch_async(dispatch_get_main_queue(), ^{
SetAssetBundlePathOnUI(assets_directory);
latch->Signal();
});
latch->Wait();
delete latch;
}
} // namespace shell
......@@ -59,6 +59,8 @@ class PlatformViewIOS : public PlatformView {
const std::string& main,
const std::string& packages) override;
void SetAssetBundlePath(const std::string& assets_directory) override;
NSObject<FlutterBinaryMessenger>* binary_messenger() const {
return binary_messenger_;
}
......@@ -75,6 +77,8 @@ class PlatformViewIOS : public PlatformView {
const std::string& main,
const std::string& packages);
void SetAssetBundlePathOnUI(const std::string& assets_directory);
FXL_DISALLOW_COPY_AND_ASSIGN(PlatformViewIOS);
};
......
......@@ -69,6 +69,13 @@ void PlatformViewIOS::SetupAndLoadFromSource(const std::string& assets_directory
});
}
void PlatformViewIOS::SetAssetBundlePathOnUI(const std::string& assets_directory) {
blink::Threads::UI()->PostTask([ engine = engine().GetWeakPtr(), assets_directory ] {
if (engine)
engine->SetAssetBundlePath(assets_directory);
});
}
fml::WeakPtr<PlatformViewIOS> PlatformViewIOS::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
......@@ -120,4 +127,16 @@ void PlatformViewIOS::RunFromSource(const std::string& assets_directory,
delete latch;
}
void PlatformViewIOS::SetAssetBundlePath(const std::string& assets_directory) {
auto latch = new fxl::ManualResetWaitableEvent();
dispatch_async(dispatch_get_main_queue(), ^{
SetAssetBundlePathOnUI(assets_directory);
latch->Signal();
});
latch->Wait();
delete latch;
}
} // namespace shell
......@@ -47,6 +47,11 @@ void PlatformViewEmbedder::RunFromSource(const std::string& assets_directory,
FXL_LOG(INFO) << "Hot reloading is unsupported on this platform.";
}
void PlatformViewEmbedder::SetAssetBundlePath(
const std::string& assets_directory) {
FXL_LOG(INFO) << "Set asset bundle path is unsupported on this platform.";
}
void PlatformViewEmbedder::HandlePlatformMessage(
fxl::RefPtr<blink::PlatformMessage> message) {
if (!message) {
......
......@@ -52,6 +52,9 @@ class PlatformViewEmbedder : public PlatformView, public GPUSurfaceGLDelegate {
const std::string& main,
const std::string& packages) override;
// |shell::PlatformView|
void SetAssetBundlePath(const std::string& assets_directory) override;
// |shell::PlatformView|
void HandlePlatformMessage(
fxl::RefPtr<blink::PlatformMessage> message) override;
......
......@@ -26,4 +26,7 @@ void PlatformViewTest::RunFromSource(const std::string& assets_directory,
const std::string& main,
const std::string& packages) {}
void PlatformViewTest::SetAssetBundlePath(const std::string& assets_directory) {
}
} // namespace shell
......@@ -27,6 +27,8 @@ class PlatformViewTest : public PlatformView {
const std::string& main,
const std::string& packages) override;
void SetAssetBundlePath(const std::string& assets_directory) override;
private:
FXL_DISALLOW_COPY_AND_ASSIGN(PlatformViewTest);
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册