提交 dedab3e6 编写于 作者: J John McCutchan 提交者: GitHub

Add an association between FlutterViews and Dart Isolates to the PlatformView...

Add an association between FlutterViews and Dart Isolates to the PlatformView service protocol support (#2886)
上级 13af58bf
......@@ -26,7 +26,7 @@ vars = {
# Note: When updating the Dart revision, ensure that all entries that are
# dependencies of dart are also updated
'dart_revision': 'a83edeee956c31d50c99be03668802aa548b7661',
'dart_revision': '5a2193ecc4f5672a61169cba93197dc3aa46e1d1',
'dart_boringssl_revision': '8d343b44bbab829d1a28fdef650ca95f7db4412e',
'dart_observatory_packages_revision': 'a01235b5b71df27b602dae4676d0bf771cbe7fa2',
'dart_root_certificates_revision': 'aed07942ce98507d2be28cbd29e879525410c7fc',
......
......@@ -19,13 +19,14 @@ IsolateClient::~IsolateClient() {}
FlutterDartState::FlutterDartState(IsolateClient* isolate_client,
const std::string& url)
: isolate_client_(isolate_client), url_(url) {
: isolate_client_(isolate_client), url_(url), main_port_(ILLEGAL_PORT) {
#ifdef OS_ANDROID
jni_data_.reset(new DartJniIsolateData());
#endif
}
FlutterDartState::~FlutterDartState() {
main_port_ = ILLEGAL_PORT;
// We've already destroyed the isolate. Revoke any weak ptrs held by
// DartPersistentValues so they don't try to enter the destroyed isolate to
// clean themselves up.
......@@ -40,7 +41,9 @@ FlutterDartState* FlutterDartState::Current() {
return static_cast<FlutterDartState*>(DartState::Current());
}
void FlutterDartState::DidSetIsolate() {}
void FlutterDartState::DidSetIsolate() {
main_port_ = Dart_GetMainPortId();
}
void FlutterDartState::set_mojo_services(
std::unique_ptr<MojoServices> mojo_services) {
......
......@@ -37,6 +37,10 @@ class FlutterDartState : public DartState {
static FlutterDartState* Current();
Dart_Port main_port() const {
return main_port_;
}
void set_mojo_services(std::unique_ptr<MojoServices> mojo_services);
MojoServices* mojo_services();
......@@ -51,6 +55,8 @@ class FlutterDartState : public DartState {
IsolateClient* isolate_client_;
std::string url_;
Dart_Port main_port_;
std::unique_ptr<MojoServices> mojo_services_;
#ifdef OS_ANDROID
......
......@@ -170,6 +170,7 @@ void DartController::CreateIsolateFor(std::unique_ptr<UIDartState> state) {
ftl::RefPtr<ftl::TaskRunner>(Platform::current()->GetUITaskRunner()));
Dart_SetShouldPauseOnStart(SkySettings::Get().start_paused);
ui_dart_state_->SetIsolate(isolate);
FTL_CHECK(!LogIfError(Dart_SetLibraryTagHandler(DartLibraryTagHandler)));
......
......@@ -113,4 +113,15 @@ void SkyView::OnAppLifecycleStateChanged(sky::AppLifecycleState state) {
GetWindow()->OnAppLifecycleStateChanged(state);
}
Dart_Port SkyView::GetMainPort() {
if (!dart_controller_) {
return ILLEGAL_PORT;
}
if (!dart_controller_->dart_state()) {
return ILLEGAL_PORT;
}
return dart_controller_->dart_state()->main_port();
}
} // namespace blink
......@@ -53,6 +53,8 @@ class SkyView : public WindowClient, public IsolateClient {
void OnAppLifecycleStateChanged(sky::AppLifecycleState state);
Dart_Port GetMainPort();
private:
explicit SkyView(SkyViewClient* client);
......
......@@ -74,6 +74,18 @@ static bool ErrorUnknownView(const char** json_object,
return false;
}
static bool ErrorIsolateSpawn(const char** json_object,
const char* view_id) {
const intptr_t kInvalidParams = -32602;
std::stringstream response;
response << "{\"code\":" << std::to_string(kInvalidParams) << ",";
response << "\"message\":\"Invalid params\",";
response << "\"data\": {\"details\": \"view " << view_id;
response << " did not spawn an isolate\"}}";
*json_object = strdup(response.str().c_str());
return false;
}
} // namespace
......@@ -130,19 +142,30 @@ bool PlatformViewServiceProtocol::RunInView(const char* method,
// task on the UI thread before returning.
Shell& shell = Shell::Shared();
bool view_existed = false;
Dart_Port main_port = ILLEGAL_PORT;
shell.RunInPlatformView(view_id_as_num,
main_script,
packages_file,
asset_directory,
&view_existed);
&view_existed,
&main_port);
if (!view_existed) {
// If the view did not exist this request has definitely failed.
return ErrorUnknownView(json_object, view_id);
} else if (main_port == ILLEGAL_PORT) {
// We did not create an isolate.
return ErrorIsolateSpawn(json_object, view_id);
} else {
// The view existed and the run was requested. Success.
// TODO(johnmccutchan): Can we send back any launch errors here?
*json_object = strdup("{\"type\": \"Success\"}");
// The view existed and the isolate was created. Success.
std::stringstream response;
response << "{\"type\":\"Success\",";
response << "\"viewId\": \"_flutterView/";
response << "0x" << std::hex << view_id;
response << "\",";
response << "\"isolateId\": \"isolates/" << std::dec << main_port << "\"";
response << "}";
*json_object = strdup(response.str().c_str());
return true;
}
return true;
......@@ -160,7 +183,7 @@ bool PlatformViewServiceProtocol::ListViews(const char* method,
// Ask the Shell for the list of platform views. This will run a task on
// the UI thread before returning.
Shell& shell = Shell::Shared();
std::vector<uintptr_t> platform_views;
std::vector<Shell::PlatformViewInfo> platform_views;
shell.WaitForPlatformViewIds(&platform_views);
std::stringstream response;
......@@ -168,7 +191,8 @@ bool PlatformViewServiceProtocol::ListViews(const char* method,
response << "{\"type\":\"FlutterViewList\",\"views\":[";
bool prefix_comma = false;
for (auto it = platform_views.begin(); it != platform_views.end(); it++) {
uintptr_t view_id = *it;
uintptr_t view_id = it->view_id;
int64_t isolate_id = it->isolate_id;
if (!view_id) {
continue;
}
......@@ -179,7 +203,9 @@ bool PlatformViewServiceProtocol::ListViews(const char* method,
}
response << "{\"type\":\"FlutterView\", \"id\": \"_flutterView/";
response << "0x" << std::hex << view_id;
response << "\"}";
response << "\",";
response << "\"isolateId\": \"isolates/" << std::dec << isolate_id << "\"";
response << "}";
}
response << "]}";
// Copy the response.
......
......@@ -233,7 +233,7 @@ void Shell::GetPlatformViews(
}
void Shell::WaitForPlatformViewIds(
std::vector<uintptr_t>* platform_view_ids) {
std::vector<PlatformViewInfo>* platform_view_ids) {
base::WaitableEvent latch(false, false);
......@@ -248,7 +248,7 @@ void Shell::WaitForPlatformViewIds(
}
void Shell::WaitForPlatformViewsIdsUIThread(
std::vector<uintptr_t>* platform_view_ids,
std::vector<PlatformViewInfo>* platform_view_ids,
base::WaitableEvent* latch) {
std::vector<base::WeakPtr<PlatformView>> platform_views;
GetPlatformViews(&platform_views);
......@@ -258,7 +258,10 @@ void Shell::WaitForPlatformViewsIdsUIThread(
// Skip dead views.
continue;
}
platform_view_ids->push_back(reinterpret_cast<uintptr_t>(view));
PlatformViewInfo info;
info.view_id = reinterpret_cast<uintptr_t>(view);
info.isolate_id = view->engine().GetUIIsolateMainPort();
platform_view_ids->push_back(info);
}
latch->Signal();
}
......@@ -267,7 +270,8 @@ void Shell::RunInPlatformView(uintptr_t view_id,
const char* main_script,
const char* packages_file,
const char* asset_directory,
bool* view_existed) {
bool* view_existed,
int64_t* dart_isolate_id) {
base::WaitableEvent latch(false, false);
DCHECK(view_id != 0);
DCHECK(main_script);
......@@ -284,6 +288,7 @@ void Shell::RunInPlatformView(uintptr_t view_id,
std::string(packages_file),
std::string(asset_directory),
base::Unretained(view_existed),
base::Unretained(dart_isolate_id),
base::Unretained(&latch)));
latch.Wait();
......@@ -294,6 +299,7 @@ void Shell::RunInPlatformViewUIThread(uintptr_t view_id,
const std::string& packages,
const std::string& assets_directory,
bool* view_existed,
int64_t* dart_isolate_id,
base::WaitableEvent* latch) {
DCHECK(ui_thread_checker_ && ui_thread_checker_->CalledOnValidThread());
......@@ -304,6 +310,7 @@ void Shell::RunInPlatformViewUIThread(uintptr_t view_id,
if (reinterpret_cast<uintptr_t>(view) == view_id) {
*view_existed = true;
view->engine().RunFromSource(main, packages, assets_directory);
*dart_isolate_id = view->engine().GetUIIsolateMainPort();
break;
}
}
......
......@@ -73,16 +73,23 @@ class Shell {
void GetPlatformViews(
std::vector<base::WeakPtr<PlatformView>>* platform_views);
struct PlatformViewInfo {
uintptr_t view_id;
int64_t isolate_id;
};
// These APIs can be called from any thread.
// Return the list of platform view ids at the time of this call.
void WaitForPlatformViewIds(std::vector<uintptr_t>* platform_view_ids);
void WaitForPlatformViewIds(std::vector<PlatformViewInfo>* platform_view_ids);
// Attempt to run a script inside a flutter view indicated by |view_id|.
// Will set |view_existed| to true if the view was found and false otherwise.
void RunInPlatformView(uintptr_t view_id,
const char* main_script,
const char* packages_file,
const char* asset_directory,
bool* view_existed);
bool* view_existed,
int64_t* dart_isolate_id);
private:
Shell();
......@@ -90,14 +97,16 @@ class Shell {
void InitGpuThread();
void InitUIThread();
void WaitForPlatformViewsIdsUIThread(std::vector<uintptr_t>* platform_views,
base::WaitableEvent* latch);
void WaitForPlatformViewsIdsUIThread(
std::vector<PlatformViewInfo>* platform_views,
base::WaitableEvent* latch);
void RunInPlatformViewUIThread(uintptr_t view_id,
const std::string& main,
const std::string& packages,
const std::string& assets_directory,
bool* view_existed,
int64_t* dart_isolate_id,
base::WaitableEvent* latch);
std::unique_ptr<base::Thread> gpu_thread_;
......
......@@ -90,6 +90,13 @@ void Engine::RunFromSource(const std::string& main,
RunFromLibrary(main);
}
Dart_Port Engine::GetUIIsolateMainPort() {
if (!sky_view_) {
return ILLEGAL_PORT;
}
return sky_view_->GetMainPort();
}
void Engine::ConnectToEngine(mojo::InterfaceRequest<SkyEngine> request) {
binding_.Bind(request.Pass());
}
......
......@@ -54,6 +54,8 @@ class Engine : public UIDelegate,
const std::string& packages,
const std::string& assets_directory);
Dart_Port GetUIIsolateMainPort();
private:
// UIDelegate implementation:
void ConnectToEngine(mojo::InterfaceRequest<SkyEngine> request) override;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册