7#include <lib/async-loop/loop.h>
8#include <lib/async/default.h>
9#include <lib/vfs/cpp/pseudo_dir.h>
11#include <zircon/status.h>
12#include <zircon/syscalls.h>
26#include "third_party/dart/runtime/include/bin/dart_io_api.h"
34const char* kDartVMArgs[] = {
37 "--timeline_recorder=systrace",
38 "--timeline_streams=Compiler,Dart,Debugger,Embedder,GC,Isolate,VM",
40#if defined(AOT_RUNTIME)
43 "--enable_mirrors=false",
49#if !defined(DART_PRODUCT) && (!defined(FLUTTER_PROFILE) || !defined(NDEBUG))
54Dart_Isolate IsolateGroupCreateCallback(
const char* uri,
56 const char* package_root,
57 const char* package_config,
58 Dart_IsolateFlags* flags,
61 if (std::string(uri) == DART_VM_SERVICE_ISOLATE_NAME) {
62#if defined(DART_PRODUCT)
63 *
error =
strdup(
"The service isolate is not implemented in product mode");
70 *
error =
strdup(
"Isolate spawning is not implemented in dart_runner");
74void IsolateShutdownCallback(
void* isolate_group_data,
void* isolate_data) {
77 auto dispatcher = async_get_default_dispatcher();
78 auto loop = async_loop_from_dispatcher(dispatcher);
86 async_loop_quit(loop);
90 static_cast<std::shared_ptr<tonic::DartState>*
>(isolate_group_data);
91 state->get()->SetIsShuttingDown();
94void IsolateGroupCleanupCallback(
void* isolate_group_data) {
95 delete static_cast<std::shared_ptr<tonic::DartState>*
>(isolate_group_data);
101 fuchsia::component::runner::ComponentStartInfo start_info,
102 std::shared_ptr<sys::ServiceDirectory> runner_incoming_services,
103 fidl::InterfaceRequest<fuchsia::component::runner::ComponentController>
105 const int64_t
start = Dart_TimelineGetMicros();
107 DartComponentController app(std::move(start_info), runner_incoming_services,
108 std::move(controller));
109 const bool success = app.SetUp();
111 const int64_t
end = Dart_TimelineGetMicros();
112 Dart_RecordTimelineEvent(
113 "DartComponentController::SetUp", start,
end, 0,
nullptr,
114 Dart_Timeline_Event_Duration, 0, NULL, NULL);
119 if (Dart_CurrentIsolate()) {
120 Dart_ShutdownIsolate();
124void RunTestApplication(
126 fuchsia::component::runner::ComponentStartInfo start_info,
127 std::shared_ptr<sys::ServiceDirectory> runner_incoming_services,
128 fidl::InterfaceRequest<fuchsia::component::runner::ComponentController>
130 fit::function<
void(std::shared_ptr<DartTestComponentController>)>
131 component_created_callback,
132 fit::function<
void(DartTestComponentController*)> done_callback) {
133 const int64_t
start = Dart_TimelineGetMicros();
135 auto test_component = std::make_shared<DartTestComponentController>(
136 std::move(start_info), runner_incoming_services, std::move(controller),
137 std::move(done_callback));
139 component_created_callback(test_component);
142 test_component->SetUp();
144 const int64_t
end = Dart_TimelineGetMicros();
145 Dart_RecordTimelineEvent(
146 "DartTestComponentController::SetUp", start,
end, 0,
nullptr,
147 Dart_Timeline_Event_Duration, 0, NULL, NULL);
150bool EntropySource(uint8_t* buffer, intptr_t count) {
151 zx_cprng_draw(buffer, count);
163 for (
const auto& entry : program_metadata.entries()) {
164 if (entry.key.compare(
kArgsKey) != 0 || entry.value ==
nullptr) {
167 auto args = entry.value->str_vec();
172 std::vector<std::string> command_line_args = {
""};
173 command_line_args.insert(command_line_args.end(),
args.begin(),
args.end());
175 command_line_args.begin(), command_line_args.end());
177 std::string is_test_str;
179 is_test_str ==
"true";
186 ->AddPublicService<fuchsia::component::runner::ComponentRunner>(
187 [
this](fidl::InterfaceRequest<
188 fuchsia::component::runner::ComponentRunner> request) {
189 component_runner_bindings_.AddBinding(
this, std::move(request));
192#if !defined(DART_PRODUCT)
196 context_->outgoing()->debug_dir()->AddEntry(
198 std::make_unique<dart_utils::VMServiceObject>());
202 dart::bin::BootstrapDartIo();
210 Dart_InitializeParams
params = {};
211 params.version = DART_INITIALIZE_PARAMS_CURRENT_VERSION;
212 params.create_group = IsolateGroupCreateCallback;
213 params.shutdown_isolate = IsolateShutdownCallback;
214 params.cleanup_group = IsolateGroupCleanupCallback;
215 params.entropy_source = EntropySource;
222 char*
error = Dart_Cleanup();
227void DartRunner::Start(
228 fuchsia::component::runner::ComponentStartInfo start_info,
229 fidl::InterfaceRequest<fuchsia::component::runner::ComponentController>
235 std::string url_copy = start_info.resolved_url();
238 RunTestApplication,
this, std::move(start_info), context_->svc(),
239 std::move(controller),
241 [
this](std::shared_ptr<DartTestComponentController> ptr) {
242 test_components_.emplace(ptr.get(), std::move(ptr));
246 auto it = test_components_.find(ptr);
247 if (it != test_components_.end()) {
248 test_components_.erase(it);
253 std::string url_copy = start_info.resolved_url();
255 std::thread thread(RunApplication,
this, std::move(start_info),
256 context_->svc(), std::move(controller));
261void DartRunner::handle_unknown_method(uint64_t ordinal,
262 bool method_has_response) {
263 FML_LOG(ERROR) <<
"Unknown method called on DartRunner. Ordinal: "
DartRunner(sys::ComponentContext *context)
static constexpr const char * kPortDirName
bool GetOptionValue(std::string_view name, std::string *value) const
static DartMicrotaskQueue * GetForCurrentThread()
const EmbeddedViewParams * params
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
const uint8_t uint32_t uint32_t GError ** error
#define FML_LOG(severity)
constexpr char kArgsKey[]
bool IsTestProgram(const fuchsia::data::Dictionary &program_metadata)
Dart_Isolate CreateServiceIsolate(const char *uri, Dart_IsolateFlags *flags_unused, char **error)
size_t ArraySize(T(&array)[SIZE])
char * strdup(const char *str1)
CommandLine CommandLineFromIterators(InputIterator first, InputIterator last)
std::shared_ptr< ContextGLES > context
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)