提交 65fcbf7c 编写于 作者: Z Zachary Anderson 提交者: GitHub

Add listViews service extension for the content handler (#3468)

上级 e0c702e3
......@@ -27,6 +27,8 @@ executable("content_handler") {
"rasterizer.h",
"runtime_holder.cc",
"runtime_holder.h",
"service_protocol_hooks.cc",
"service_protocol_hooks.h",
"software_rasterizer.cc",
"software_rasterizer.h",
]
......
......@@ -11,6 +11,8 @@
#include "apps/tracing/lib/trace/provider.h"
#include "flutter/common/settings.h"
#include "flutter/common/threads.h"
#include "flutter/content_handler/service_protocol_hooks.h"
#include "flutter/runtime/dart_init.h"
#include "flutter/runtime/runtime_init.h"
#include "flutter/sky/engine/platform/fonts/fuchsia/FontCacheFuchsia.h"
#include "lib/ftl/macros.h"
......@@ -20,6 +22,8 @@
namespace flutter_runner {
namespace {
static App* g_app = nullptr;
void QuitMessageLoop() {
mtl::MessageLoop::GetCurrent()->QuitNow();
}
......@@ -27,6 +31,7 @@ void QuitMessageLoop() {
} // namespace
App::App() {
g_app = this;
context_ = app::ApplicationContext::CreateFromStartupInfo();
tracing::InitializeTracer(context_.get(), {});
......@@ -57,6 +62,9 @@ App::App() {
blink::Settings::Set(settings);
blink::InitRuntime();
blink::SetRegisterNativeServiceProtocolExtensionHook(
ServiceProtocolHooks::RegisterHooks);
blink::SetFontProvider(
context_->ConnectToEnvironmentService<fonts::FontProvider>());
......@@ -70,6 +78,44 @@ App::~App() {
icu_data::Release();
blink::Threads::Gpu()->PostTask(QuitMessageLoop);
blink::Threads::IO()->PostTask(QuitMessageLoop);
g_app = nullptr;
}
App& App::Shared() {
FTL_DCHECK(g_app);
return *g_app;
}
void App::WaitForPlatformViewIds(
std::vector<PlatformViewInfo>* platform_view_ids) {
ftl::AutoResetWaitableEvent latch;
blink::Threads::UI()->PostTask([this, platform_view_ids, &latch]() {
WaitForPlatformViewsIdsUIThread(platform_view_ids, &latch);
});
latch.Wait();
}
void App::WaitForPlatformViewsIdsUIThread(
std::vector<PlatformViewInfo>* platform_view_ids,
ftl::AutoResetWaitableEvent* latch) {
for (auto it = controllers_.begin(); it != controllers_.end(); it++) {
ApplicationControllerImpl* controller = it->first;
if (!controller) {
continue;
}
PlatformViewInfo info;
// TODO(zra): We should create real IDs for these instead of relying on the
// address of the controller. Maybe just use the UI Isolate main port?
info.view_id = reinterpret_cast<uintptr_t>(controller);
info.isolate_id = controller->GetUIIsolateMainPort();
info.isolate_name = controller->GetUIIsolateName();
platform_view_ids->push_back(info);
}
latch->Signal();
}
void App::StartApplication(
......
......@@ -13,6 +13,7 @@
#include "flutter/content_handler/application_controller_impl.h"
#include "flutter/content_handler/content_handler_thread.h"
#include "lib/ftl/macros.h"
#include "lib/ftl/synchronization/waitable_event.h"
namespace flutter_runner {
......@@ -21,6 +22,8 @@ class App : public app::ApplicationRunner {
App();
~App();
static App& Shared();
// |app::ApplicationRunner| implementation:
void StartApplication(app::ApplicationPackagePtr application,
......@@ -30,7 +33,19 @@ class App : public app::ApplicationRunner {
void Destroy(ApplicationControllerImpl* controller);
struct PlatformViewInfo {
uintptr_t view_id;
int64_t isolate_id;
std::string isolate_name;
};
void WaitForPlatformViewIds(std::vector<PlatformViewInfo>* platform_view_ids);
private:
void WaitForPlatformViewsIdsUIThread(
std::vector<PlatformViewInfo>* platform_view_ids,
ftl::AutoResetWaitableEvent* latch);
std::unique_ptr<app::ApplicationContext> context_;
std::unique_ptr<Thread> gpu_thread_;
std::unique_ptr<Thread> io_thread_;
......
......@@ -79,4 +79,17 @@ void ApplicationControllerImpl::CreateView(
std::move(services));
}
Dart_Port ApplicationControllerImpl::GetUIIsolateMainPort() {
if (!runtime_holder_)
return ILLEGAL_PORT;
return runtime_holder_->GetUIIsolateMainPort();
}
std::string ApplicationControllerImpl::GetUIIsolateName() {
if (!runtime_holder_) {
return "";
}
return runtime_holder_->GetUIIsolateName();
}
} // namespace flutter_runner
......@@ -11,9 +11,11 @@
#include "application/services/application_runner.fidl.h"
#include "application/services/service_provider.fidl.h"
#include "apps/mozart/services/views/view_provider.fidl.h"
#include "dart/runtime/include/dart_api.h"
#include "lib/fidl/cpp/bindings/binding.h"
#include "lib/fidl/cpp/bindings/binding_set.h"
#include "lib/ftl/macros.h"
#include "lib/ftl/synchronization/waitable_event.h"
namespace flutter_runner {
class App;
......@@ -47,6 +49,9 @@ class ApplicationControllerImpl : public app::ApplicationController,
fidl::InterfaceRequest<mozart::ViewOwner> view_owner_request,
fidl::InterfaceRequest<app::ServiceProvider> services) override;
Dart_Port GetUIIsolateMainPort();
std::string GetUIIsolateName();
private:
void StartRuntimeIfReady();
......
......@@ -169,6 +169,19 @@ void RuntimeHolder::CreateView(
}
}
Dart_Port RuntimeHolder::GetUIIsolateMainPort() {
if (!runtime_)
return ILLEGAL_PORT;
return runtime_->GetMainPort();
}
std::string RuntimeHolder::GetUIIsolateName() {
if (!runtime_) {
return "";
}
return runtime_->GetIsolateName();
}
void RuntimeHolder::ScheduleFrame() {
if (pending_invalidation_ || deferred_invalidation_callback_)
return;
......
......@@ -45,6 +45,9 @@ class RuntimeHolder : public blink::RuntimeDelegate,
fidl::InterfaceRequest<mozart::ViewOwner> view_owner_request,
fidl::InterfaceRequest<app::ServiceProvider> services);
Dart_Port GetUIIsolateMainPort();
std::string GetUIIsolateName();
private:
// |blink::RuntimeDelegate| implementation:
void ScheduleFrame() override;
......
// Copyright 2017 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 "flutter/content_handler/service_protocol_hooks.h"
#include <string.h>
#include <string>
#include <vector>
#include "flutter/common/threads.h"
#include "flutter/content_handler/app.h"
#include "lib/ftl/memory/weak_ptr.h"
namespace flutter_runner {
namespace {
constexpr char kViewIdPrefx[] = "_flutterView/";
static void AppendIsolateRef(std::stringstream* stream,
int64_t main_port,
const std::string name) {
*stream << "{\"type\":\"@Isolate\",\"fixedId\":true,\"id\":\"isolates/";
*stream << main_port << "\",\"name\":\"" << name << "\",";
*stream << "\"number\":\"" << main_port << "\"}";
}
static void AppendFlutterView(std::stringstream* stream,
uintptr_t view_id,
int64_t isolate_id,
const std::string isolate_name) {
*stream << "{\"type\":\"FlutterView\", \"id\": \"" << kViewIdPrefx << "0x"
<< std::hex << view_id << std::dec << "\"";
if (isolate_id != ILLEGAL_PORT) {
// Append the isolate (if it exists).
*stream << ","
<< "\"isolate\":";
AppendIsolateRef(stream, isolate_id, isolate_name);
}
*stream << "}";
}
} // namespace
void ServiceProtocolHooks::RegisterHooks(bool running_precompiled_code) {
// Listing of FlutterViews.
Dart_RegisterRootServiceRequestCallback(kListViewsExtensionName, &ListViews,
nullptr);
}
const char* ServiceProtocolHooks::kListViewsExtensionName =
"_flutter.listViews";
bool ServiceProtocolHooks::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 App for the list of platform views. This will run a task on
// the UI thread before returning.
App& app = App::Shared();
std::vector<App::PlatformViewInfo> platform_views;
app.WaitForPlatformViewIds(&platform_views);
std::stringstream response;
response << "{\"type\":\"FlutterViewList\",\"views\":[";
bool prefix_comma = false;
for (auto it = platform_views.begin(); it != platform_views.end(); it++) {
uintptr_t view_id = it->view_id;
int64_t isolate_id = it->isolate_id;
const std::string& isolate_name = it->isolate_name;
if (!view_id) {
continue;
}
if (prefix_comma) {
response << ',';
} else {
prefix_comma = true;
}
AppendFlutterView(&response, view_id, isolate_id, isolate_name);
}
response << "]}";
// Copy the response.
*json_object = strdup(response.str().c_str());
return true;
}
} // namespace flutter_runner
// Copyright 2017 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 FLUTTER_CONTENT_HANDLER_SERVICE_PROTOCOL_HOOKS_H_
#define FLUTTER_CONTENT_HANDLER_SERVICE_PROTOCOL_HOOKS_H_
#include "dart/runtime/include/dart_tools_api.h"
#include "lib/ftl/synchronization/waitable_event.h"
namespace flutter_runner {
class ServiceProtocolHooks {
public:
static void RegisterHooks(bool running_precompiled_code);
private:
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 flutter_runner
#endif // FLUTTER_CONTENT_HANDLER_SERVICE_PROTOCOL_HOOKS_H_
......@@ -1904,6 +1904,8 @@ FILE: ../../../flutter/content_handler/content_handler_thread.cc
FILE: ../../../flutter/content_handler/content_handler_thread.h
FILE: ../../../flutter/content_handler/direct_input.cc
FILE: ../../../flutter/content_handler/direct_input.h
FILE: ../../../flutter/content_handler/service_protocol_hooks.cc
FILE: ../../../flutter/content_handler/service_protocol_hooks.h
FILE: ../../../flutter/content_handler/software_rasterizer.cc
FILE: ../../../flutter/content_handler/software_rasterizer.h
FILE: ../../../flutter/content_handler/vulkan_rasterizer.cc
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册