8#include <fuchsia/mem/cpp/fidl.h>
9#include <lib/async/cpp/task.h>
10#include <lib/async/default.h>
11#include <lib/inspect/cpp/inspect.h>
12#include <lib/sys/cpp/component_context.h>
13#include <lib/trace-engine/instrumentation.h>
14#include <lib/vfs/cpp/pseudo_dir.h>
15#include <zircon/status.h>
16#include <zircon/types.h>
22#include "flutter/fml/make_copyable.h"
23#include "flutter/lib/ui/text/font_collection.h"
24#include "flutter/runtime/dart_vm.h"
29#include "third_party/icu/source/common/unicode/udata.h"
36static constexpr char kIcuDataPath[] =
"/pkg/data/icudtl.dat";
40static constexpr char kICUTZEnv[] =
"ICU_TIMEZONE_FILES_DIR";
43static constexpr char kICUTZDataDir[] =
"/config/data/tzdata/icu/44/le";
46uintptr_t GetICUData(
const fuchsia::mem::Buffer& icu_data) {
47 uint64_t data_size = icu_data.size;
53 zx::vmar::root_self()->map(ZX_VM_PERM_READ, 0, icu_data.vmo, 0,
54 static_cast<size_t>(data_size), &
data);
55 if (status == ZX_OK) {
66bool InitializeTZData() {
69 setenv(kICUTZEnv, kICUTZDataDir, 0 );
71 const std::string tzdata_dir =
getenv(kICUTZEnv);
75 int fd = openat(AT_FDCWD, tzdata_dir.c_str(), O_RDONLY);
77 FML_LOG(INFO) <<
"Could not open: '" << tzdata_dir
78 <<
"', proceeding without loading the timezone database: "
83 FML_LOG(WARNING) <<
"Could not close: " << tzdata_dir <<
": "
91 const char* data_path = kIcuDataPath;
93 fuchsia::mem::Buffer icu_data;
98 uintptr_t
data = GetICUData(icu_data);
108 UErrorCode err = U_ZERO_ERROR;
109 udata_setCommonData(
reinterpret_cast<const char*
>(
data), &err);
110 if (err != U_ZERO_ERROR) {
121#if defined(DART_PRODUCT)
122 stream <<
"io.flutter.product_runner.";
124 stream <<
"io.flutter.runner.";
140#if !defined(DART_PRODUCT)
143 const char* dso_name) {
144 std::string*
symbols =
new std::string();
155 : task_runner_(task_runner), context_(context) {
156#if !defined(DART_PRODUCT)
160 context_->outgoing()->debug_dir()->AddEntry(
162 std::make_unique<dart_utils::VMServiceObject>());
165 inspector->GetRoot().CreateLazyValues(
168 inspect::Inspector inspector;
169 dart_utils::VMServiceObject::LazyEntryVector
out;
171 std::string
name =
"";
175 inspector.GetRoot().CreateString(
"vm_service_port",
name, &inspector);
176 return fpromise::make_ok_promise(inspector);
180 SetupTraceObserver();
192 ->AddPublicService<fuchsia::component::runner::ComponentRunner>(
193 std::bind(&Runner::RegisterComponentV2,
this, std::placeholders::_1));
195#if !defined(DART_PRODUCT)
208 ->RemovePublicService<fuchsia::component::runner::ComponentRunner>();
210#if !defined(DART_PRODUCT)
211 trace_observer_->Stop();
217void Runner::RegisterComponentV2(
218 fidl::InterfaceRequest<fuchsia::component::runner::ComponentRunner>
220 active_components_v2_bindings_.AddBinding(
this, std::move(request));
224 fuchsia::component::runner::ComponentStartInfo start_info,
225 fidl::InterfaceRequest<fuchsia::component::runner::ComponentController>
233 const std::string url_copy = start_info.resolved_url();
234 TRACE_EVENT1(
"flutter",
"Start",
"url", url_copy.c_str());
244 [component_runner =
this](
const ComponentV2* component) {
245 component_runner->task_runner_->PostTask(
246 [component_runner, component]() {
247 component_runner->OnComponentV2Terminate(component);
252 std::move(termination_callback), std::move(start_info),
253 context_->svc() , std::move(controller));
255 auto key = active_component.component.get();
256 active_components_v2_[
key] = std::move(active_component);
259void Runner::OnComponentV2Terminate(
const ComponentV2* component) {
260 auto active_component_it = active_components_v2_.find(component);
261 if (active_component_it == active_components_v2_.end()) {
263 <<
"The remote end of the component runner tried to terminate an "
264 "component that has already been terminated, possibly because we "
265 "initiated the termination";
268 ActiveComponentV2& active_component = active_component_it->second;
272 std::unique_ptr<ComponentV2> component_to_destroy =
273 std::move(active_component.component);
274 std::unique_ptr<fml::Thread> component_thread =
275 std::move(active_component.platform_thread);
278 active_components_v2_.erase(component);
282 [
instance = std::move(component_to_destroy),
283 thread = component_thread.get()]()
mutable { instance.reset(); }));
286 component_thread->Join();
289void Runner::SetupICU() {
291 Runner::SetupTZDataInternal();
292 if (!Runner::SetupICUInternal()) {
298bool Runner::SetupICUInternal() {
303bool Runner::SetupTZDataInternal() {
304 return InitializeTZData();
307#if !defined(DART_PRODUCT)
308void Runner::SetupTraceObserver() {
314 trace_observer_ = std::make_unique<trace::TraceObserver>();
315 trace_observer_->Start(async_get_default_dispatcher(), [runner =
this]() {
316 if (!trace_is_category_enabled(
"dart:profiler")) {
319 if (trace_state() == TRACE_STARTED) {
320 runner->prolonged_context_ = trace_acquire_prolonged_context();
322 }
else if (trace_state() == TRACE_STOPPING) {
323 auto write_profile_trace_for_components = [](
auto& components) {
324 for (
auto& it : components) {
327 it.second.platform_thread->GetTaskRunner(), [&]() {
328 it.second.component->WriteProfileToTrace();
334 write_profile_trace_for_components(runner->active_components_v2_);
337 trace_release_prolonged_context(runner->prolonged_context_);
static inspect::Inspector * GetInspector()
void GetContents(LazyEntryVector *out_vector) const override
static constexpr const char * kPortDirName
static bool IsRunningPrecompiledCode()
Checks if VM instances in the process can run precompiled code. This call can be made at any time and...
static ActiveComponentV2 Create(TerminationCallback termination_callback, fuchsia::component::runner::ComponentStartInfo start_info, std::shared_ptr< sys::ServiceDirectory > runner_incoming_services, fidl::InterfaceRequest< fuchsia::component::runner::ComponentController > controller)
fit::function< void(const ComponentV2 *)> TerminationCallback
Runner(fml::RefPtr< fml::TaskRunner > task_runner, sys::ComponentContext *context)
static void RunNowOrPostTask(const fml::RefPtr< fml::TaskRunner > &runner, const fml::closure &task)
DART_EXPORT void Dart_StartProfiling(void)
DART_EXPORT void Dart_StopProfiling(void)
DART_EXPORT bool Dart_IsPrecompiledRuntime(void)
DART_EXPORT void Dart_AddSymbols(const char *dso_name, void *buffer, intptr_t buffer_size)
#define FML_LOG(severity)
static float max(float r, float g, float b)
bool ReadFileToString(const std::string &path, std::string *result)
bool VmoFromFilename(const std::string &filename, bool executable, fuchsia::mem::Buffer *buffer)
sys::ComponentContext * ComponentContext()
static void SetThreadName(const std::string &thread_name)
static void RegisterProfilerSymbols(const char *symbols_path, const char *dso_name)
static void SetProcessName()
DEF_SWITCHES_START aot vmservice shared library name
void InitializeICU(const std::string &icu_data_path)
internal::CopyableLambda< T > MakeCopyable(T lambda)
std::shared_ptr< const fml::Mapping > data
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)