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

Add collection of PlatformViews to the Shell and allow them to be queried over...

Add collection of PlatformViews to the Shell and allow them to be queried over the service protocol (#2861)
上级 1e250cfc
......@@ -129,6 +129,8 @@ const char kDartFlags[] = "dart-flags";
bool g_service_isolate_initialized = false;
ServiceIsolateHook g_service_isolate_hook = nullptr;
RegisterNativeServiceProtocolExtensionHook
g_register_native_service_protocol_extensions_hook = nullptr;
void IsolateShutdownCallback(void* callback_data) {
DartState* dart_state = static_cast<DartState*>(callback_data);
......@@ -211,6 +213,11 @@ Dart_Isolate ServiceIsolateCreateCallback(const char* script_uri,
Dart_ExitIsolate();
g_service_isolate_initialized = true;
// Register any native service protocol extensions.
if (g_register_native_service_protocol_extensions_hook) {
g_register_native_service_protocol_extensions_hook(
IsRunningPrecompiledCode());
}
return isolate;
}
......@@ -496,6 +503,12 @@ void SetServiceIsolateHook(ServiceIsolateHook hook) {
g_service_isolate_hook = hook;
}
void SetRegisterNativeServiceProtocolExtensionHook(
RegisterNativeServiceProtocolExtensionHook hook) {
CHECK(!g_service_isolate_initialized);
g_register_native_service_protocol_extensions_hook = hook;
}
static bool ShouldEnableCheckedMode() {
if (IsRunningPrecompiledCode()) {
// Checked mode is never enabled during precompilation. Even snapshot
......
......@@ -42,6 +42,7 @@ bool IsRunningPrecompiledCode();
using EmbedderTracingCallback = base::Callback<void(void)>;
typedef void (*ServiceIsolateHook)(bool);
typedef void (*RegisterNativeServiceProtocolExtensionHook)(bool);
struct EmbedderTracingCallbacks {
EmbedderTracingCallback start_tracing_callback;
......@@ -60,6 +61,11 @@ void SetEmbedderTracingCallbacks(
// service isolate.
void SetServiceIsolateHook(ServiceIsolateHook hook);
// Provide a function that will be called to register native service protocol
// extensions.
void SetRegisterNativeServiceProtocolExtensionHook(
RegisterNativeServiceProtocolExtensionHook hook);
Dart_Handle DartLibraryTagHandler(Dart_LibraryTag tag,
Dart_Handle library,
Dart_Handle url);
......
......@@ -23,6 +23,8 @@ source_set("common") {
"gpu/picture_serializer.h",
"platform_view.cc",
"platform_view.h",
"platform_view_service_protocol.cc",
"platform_view_service_protocol.h",
"rasterizer.cc",
"rasterizer.h",
"shell.cc",
......
......@@ -50,6 +50,10 @@ PlatformView::PlatformView()
PlatformView::~PlatformView() {
Shell& shell = Shell::Shared();
// Purge dead PlatformViews.
shell.ui_task_runner()->PostTask(
FROM_HERE,
base::Bind(&Shell::PurgePlatformViews, base::Unretained(&shell)));
shell.gpu_task_runner()->DeleteSoon(FROM_HERE, rasterizer_.release());
shell.ui_task_runner()->DeleteSoon(FROM_HERE, engine_.release());
}
......@@ -58,6 +62,12 @@ void PlatformView::ConnectToEngine(mojo::InterfaceRequest<SkyEngine> request) {
config_.ui_task_runner->PostTask(
FROM_HERE, base::Bind(&UIDelegate::ConnectToEngine, config_.ui_delegate,
base::Passed(&request)));
Shell& shell = Shell::Shared();
shell.ui_task_runner()->PostTask(
FROM_HERE,
base::Bind(&Shell::AddPlatformView,
base::Unretained(&shell),
GetWeakViewPtr()));
}
void PlatformView::NotifyCreated() {
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "sky/shell/platform_view_service_protocol.h"
#include "sky/shell/shell.h"
namespace sky {
namespace shell {
void PlatformViewServiceProtocol::RegisterHook(bool running_precompiled_code) {
if (running_precompiled_code) {
return;
}
Dart_RegisterRootServiceRequestCallback(kRunInViewExtensionName,
&RunInView,
nullptr);
Dart_RegisterRootServiceRequestCallback(kListViewsExtensionName,
&ListViews,
nullptr);
}
const char* PlatformViewServiceProtocol::kRunInViewExtensionName =
"_flutter.runInView";
bool PlatformViewServiceProtocol::RunInView(const char* method,
const char** param_keys,
const char** param_values,
intptr_t num_params,
void* user_data,
const char** json_object) {
// TODO(johnmccutchan): Implement this.
*json_object = strdup("{\"type\": \"Success\"}");
return true;
}
const char* PlatformViewServiceProtocol::kListViewsExtensionName =
"_flutter.listViews";
bool PlatformViewServiceProtocol::ListViews(const char* method,
const char** param_keys,
const char** param_values,
intptr_t num_params,
void* user_data,
const char** json_object) {
// 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<base::WeakPtr<PlatformView>> platform_views;
shell.WaitForPlatformViews(&platform_views);
std::stringstream response;
response << "{\"type\":\"FlutterViewList\",\"views\":[";
bool prefix_comma = false;
for (auto it = platform_views.begin(); it != platform_views.end(); it++) {
PlatformView* view = it->get();
if (!view) {
// Skip any platform views which have been deleted.
continue;
}
if (prefix_comma) {
response << ',';
} else {
prefix_comma = true;
}
response << "{\"type\":\"FlutterView\", \"id\": \"_flutterView/";
response << "0x" << std::hex << reinterpret_cast<uintptr_t>(view);
response << "\"}";
}
response << "]}";
// Copy the response.
*json_object = strdup(response.str().c_str());
return true;
}
} // namespace shell
} // namespace sky
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SKY_SHELL_PLATFORM_VIEW_SERVICE_PROTOCOL_H_
#define SKY_SHELL_PLATFORM_VIEW_SERVICE_PROTOCOL_H_
#include <memory>
#include "sky/shell/platform_view.h"
#include "dart/runtime/include/dart_tools_api.h"
namespace sky {
namespace shell {
class PlatformViewServiceProtocol {
public:
static void RegisterHook(bool running_precompiled_code);
private:
static const char* kRunInViewExtensionName;
static bool RunInView(const char* method,
const char** param_keys,
const char** param_values,
intptr_t num_params,
void* user_data,
const char** json_object);
static const char* kListViewsExtensionName;
static bool ListViews(const char* method,
const char** param_keys,
const char** param_values,
intptr_t num_params,
void* user_data,
const char** json_object);
};
} // namespace shell
} // namespace sky
#endif // SKY_SHELL_PLATFORM_VIEW_SERVICE_PROTOCOL_H_
......@@ -17,11 +17,13 @@
#include "base/posix/eintr_wrapper.h"
#include "base/single_thread_task_runner.h"
#include "base/trace_event/trace_event.h"
#include "dart/runtime/include/dart_tools_api.h"
#include "mojo/message_pump/message_pump_mojo.h"
#include "skia/ext/event_tracer_impl.h"
#include "sky/engine/core/script/dart_init.h"
#include "sky/engine/public/platform/sky_settings.h"
#include "sky/shell/diagnostic/diagnostic_server.h"
#include "sky/shell/platform_view_service_protocol.h"
#include "sky/shell/switches.h"
#include "sky/shell/ui/engine.h"
......@@ -39,6 +41,10 @@ bool IsInvalid(const base::WeakPtr<Rasterizer>& rasterizer) {
return !rasterizer;
}
bool IsViewInvalid(const base::WeakPtr<PlatformView>& platform_view) {
return !platform_view;
}
class NonDiscardableMemory : public base::DiscardableMemory {
public:
explicit NonDiscardableMemory(size_t size) : data_(new uint8_t[size]) {}
......@@ -85,12 +91,16 @@ Shell::Shell() {
ui_thread_.reset(new base::Thread("ui_thread"));
ui_thread_->StartWithOptions(options);
ui_task_runner_ = ui_thread_->message_loop()->task_runner();
ui_task_runner_->PostTask(
FROM_HERE, base::Bind(&Shell::InitUIThread, base::Unretained(this)));
io_thread_.reset(new base::Thread("io_thread"));
io_thread_->StartWithOptions(options);
io_task_runner_ = io_thread_->message_loop()->task_runner();
blink::SetServiceIsolateHook(ServiceIsolateHook);
blink::SetRegisterNativeServiceProtocolExtensionHook(
PlatformViewServiceProtocol::RegisterHook);
}
Shell::~Shell() {}
......@@ -172,6 +182,12 @@ void Shell::InitGpuThread() {
gpu_thread_checker_.reset(new base::ThreadChecker());
}
void Shell::InitUIThread() {
ui_thread_checker_.reset(new base::ThreadChecker());
}
void Shell::AddRasterizer(const base::WeakPtr<Rasterizer>& rasterizer) {
DCHECK(gpu_thread_checker_ && gpu_thread_checker_->CalledOnValidThread());
rasterizers_.push_back(rasterizer);
......@@ -190,5 +206,48 @@ void Shell::GetRasterizers(
*rasterizers = rasterizers_;
}
void Shell::AddPlatformView(const base::WeakPtr<PlatformView>& platform_view) {
DCHECK(ui_thread_checker_ && ui_thread_checker_->CalledOnValidThread());
if (platform_view) {
platform_views_.push_back(platform_view);
}
}
void Shell::PurgePlatformViews() {
DCHECK(ui_thread_checker_ && ui_thread_checker_->CalledOnValidThread());
platform_views_.erase(std::remove_if(platform_views_.begin(),
platform_views_.end(),
IsViewInvalid),
platform_views_.end());
}
void Shell::GetPlatformViews(
std::vector<base::WeakPtr<PlatformView>>* platform_views) {
DCHECK(ui_thread_checker_ && ui_thread_checker_->CalledOnValidThread());
*platform_views = platform_views_;
}
void Shell::WaitForPlatformViews(
std::vector<base::WeakPtr<PlatformView>>* platform_views) {
base::WaitableEvent latch(false, false);
ui_task_runner()->PostTask(
FROM_HERE,
base::Bind(&Shell::WaitForPlatformViewsUIThread,
base::Unretained(this),
base::Unretained(platform_views),
base::Unretained(&latch)));
latch.Wait();
}
void Shell::WaitForPlatformViewsUIThread(
std::vector<base::WeakPtr<PlatformView>>* platform_views,
base::WaitableEvent* latch) {
GetPlatformViews(platform_views);
latch->Signal();
}
} // namespace shell
} // namespace sky
......@@ -9,12 +9,14 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "sky/shell/tracing_controller.h"
namespace sky {
namespace shell {
class PlatformView;
class Rasterizer;
class Shell {
......@@ -49,10 +51,27 @@ class Shell {
void PurgeRasterizers();
void GetRasterizers(std::vector<base::WeakPtr<Rasterizer>>* rasterizer);
// List of PlatformViews.
// These APIs must only be accessed on UI thread.
void AddPlatformView(const base::WeakPtr<PlatformView>& platform_view);
void PurgePlatformViews();
void GetPlatformViews(std::vector<base::WeakPtr<PlatformView>>*
platform_views);
// These APIs can be called from any thread.
void WaitForPlatformViews(
std::vector<base::WeakPtr<PlatformView>>* platform_views);
private:
Shell();
void InitGpuThread();
void InitUIThread();
void WaitForPlatformViewsUIThread(
std::vector<base::WeakPtr<PlatformView>>* platform_views,
base::WaitableEvent* latch);
std::unique_ptr<base::Thread> gpu_thread_;
std::unique_ptr<base::Thread> ui_thread_;
......@@ -63,10 +82,12 @@ class Shell {
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
std::unique_ptr<base::ThreadChecker> gpu_thread_checker_;
std::unique_ptr<base::ThreadChecker> ui_thread_checker_;
TracingController tracing_controller_;
std::vector<base::WeakPtr<Rasterizer>> rasterizers_;
std::vector<base::WeakPtr<PlatformView>> platform_views_;
DISALLOW_COPY_AND_ASSIGN(Shell);
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册