Flutter Engine
dart_runner::DartComponentController Class Reference

#include <dart_component_controller.h>

Inheritance diagram for dart_runner::DartComponentController:

Public Member Functions

 DartComponentController (fuchsia::sys::Package package, fuchsia::sys::StartupInfo startup_info, std::shared_ptr< sys::ServiceDirectory > runner_incoming_services, fidl::InterfaceRequest< fuchsia::sys::ComponentController > controller)
 
 ~DartComponentController () override
 
bool Setup ()
 
void Run ()
 
bool Main ()
 
void SendReturnCode ()
 

Detailed Description

Definition at line 24 of file dart_component_controller.h.

Constructor & Destructor Documentation

◆ DartComponentController()

dart_runner::DartComponentController::DartComponentController ( fuchsia::sys::Package  package,
fuchsia::sys::StartupInfo  startup_info,
std::shared_ptr< sys::ServiceDirectory >  runner_incoming_services,
fidl::InterfaceRequest< fuchsia::sys::ComponentController >  controller 
)

Definition at line 82 of file dart_component_controller.cc.

References LOG_TAG.

87  : loop_(new async::Loop(&kLoopConfig)),
88  label_(GetLabelFromURL(package.resolved_url)),
89  url_(std::move(package.resolved_url)),
90  package_(std::move(package)),
91  startup_info_(std::move(startup_info)),
92  runner_incoming_services_(runner_incoming_services),
93  binding_(this) {
94  for (size_t i = 0; i < startup_info_.program_metadata->size(); ++i) {
95  auto pg = startup_info_.program_metadata->at(i);
96  if (pg.key.compare(kDataKey) == 0) {
97  data_path_ = "pkg/" + pg.value;
98  }
99  }
100  if (data_path_.empty()) {
101  FX_LOGF(ERROR, LOG_TAG, "Could not find a /pkg/data directory for %s",
102  url_.c_str());
103  return;
104  }
105  if (controller.is_valid()) {
106  binding_.Bind(std::move(controller));
107  binding_.set_error_handler([this](zx_status_t status) { Kill(); });
108  }
109 
110  zx_status_t status =
111  zx::timer::create(ZX_TIMER_SLACK_LATE, ZX_CLOCK_MONOTONIC, &idle_timer_);
112  if (status != ZX_OK) {
113  FX_LOGF(INFO, LOG_TAG, "Idle timer creation failed: %s",
114  zx_status_get_string(status));
115  } else {
116  idle_wait_.set_object(idle_timer_.get());
117  idle_wait_.set_trigger(ZX_TIMER_SIGNALED);
118  idle_wait_.Begin(async_get_default_dispatcher());
119  }
120 }
#define LOG_TAG
Definition: logging.h:11
constexpr char kDataKey[]

◆ ~DartComponentController()

dart_runner::DartComponentController::~DartComponentController ( )
override

Definition at line 122 of file dart_component_controller.cc.

122  {
123  if (namespace_) {
124  fdio_ns_destroy(namespace_);
125  namespace_ = nullptr;
126  }
127  close(stdoutfd_);
128  close(stderrfd_);
129 }

Member Function Documentation

◆ Main()

bool dart_runner::DartComponentController::Main ( )

Definition at line 354 of file dart_component_controller.cc.

References dart_utils::ArraySize(), tonic::DartState::Current(), tonic::DartMicrotaskQueue::Destroy(), error, tonic::GetErrorExitCode(), tonic::DartMicrotaskQueue::GetForCurrentThread(), dart_utils::HandleIfException(), dart_runner::InitBuiltinLibrariesForIsolate(), dart_runner::kServiceRootPath, LOG_TAG, tonic::LogIfError(), tonic::DartMicrotaskQueue::StartForCurrentThread(), and tonic::ToDart().

354  {
355  Dart_EnterScope();
356 
358 
359  std::vector<std::string> arguments =
360  startup_info_.launch_info.arguments.value_or(std::vector<std::string>());
361 
362  stdoutfd_ = SetupFileDescriptor(std::move(startup_info_.launch_info.out));
363  stderrfd_ = SetupFileDescriptor(std::move(startup_info_.launch_info.err));
364  auto directory_request =
365  std::move(startup_info_.launch_info.directory_request);
366 
367  auto* flat = &startup_info_.flat_namespace;
368  std::unique_ptr<sys::ServiceDirectory> svc;
369  for (size_t i = 0; i < flat->paths.size(); ++i) {
370  zx::channel dir;
371  if (flat->paths.at(i) == kServiceRootPath) {
372  svc = std::make_unique<sys::ServiceDirectory>(
373  std::move(flat->directories.at(i)));
374  break;
375  }
376  }
377  if (!svc) {
378  FX_LOG(ERROR, LOG_TAG, "Unable to get /svc for dart component");
379  return false;
380  }
381 
382  fidl::InterfaceHandle<fuchsia::sys::Environment> environment;
383  svc->Connect(environment.NewRequest());
384 
386  url_, namespace_, stdoutfd_, stderrfd_, std::move(environment),
387  std::move(directory_request), false /* service_isolate */);
388  namespace_ = nullptr;
389 
390  Dart_ExitScope();
391  Dart_ExitIsolate();
392  char* error = Dart_IsolateMakeRunnable(isolate_);
393  if (error != nullptr) {
394  Dart_EnterIsolate(isolate_);
395  Dart_ShutdownIsolate();
396  FX_LOGF(ERROR, LOG_TAG, "Unable to make isolate runnable: %s", error);
397  free(error);
398  return false;
399  }
400  Dart_EnterIsolate(isolate_);
401  Dart_EnterScope();
402 
403  Dart_Handle dart_arguments =
404  Dart_NewListOf(Dart_CoreType_String, arguments.size());
405  if (Dart_IsError(dart_arguments)) {
406  FX_LOGF(ERROR, LOG_TAG, "Failed to allocate Dart arguments list: %s",
407  Dart_GetError(dart_arguments));
408  Dart_ExitScope();
409  return false;
410  }
411  for (size_t i = 0; i < arguments.size(); i++) {
413  Dart_ListSetAt(dart_arguments, i, ToDart(arguments.at(i))));
414  }
415 
416  Dart_Handle argv[] = {
417  dart_arguments,
418  };
419 
420  Dart_Handle main_result = Dart_Invoke(Dart_RootLibrary(), ToDart("main"),
421  dart_utils::ArraySize(argv), argv);
422  if (Dart_IsError(main_result)) {
423  auto dart_state = tonic::DartState::Current();
424  if (!dart_state->has_set_return_code()) {
425  // The program hasn't set a return code meaning this exit is unexpected.
426  FX_LOG(ERROR, LOG_TAG, Dart_GetError(main_result));
427  return_code_ = tonic::GetErrorExitCode(main_result);
428 
429  dart_utils::HandleIfException(runner_incoming_services_, url_,
430  main_result);
431  }
432  Dart_ExitScope();
433  return false;
434  }
435 
436  Dart_ExitScope();
437  return true;
438 }
size_t ArraySize(T(&array)[SIZE])
Definition: inlines.h:26
const uint8_t uint32_t uint32_t GError ** error
static DartState * Current()
Definition: dart_state.cc:56
int GetErrorExitCode(Dart_Handle handle)
Definition: dart_error.cc:46
void HandleIfException(std::shared_ptr<::sys::ServiceDirectory > services, const std::string &component_url, Dart_Handle result)
void InitBuiltinLibrariesForIsolate(const std::string &script_uri, fdio_ns_t *namespc, int stdoutfd, int stderrfd, fidl::InterfaceHandle< fuchsia::sys::Environment > environment, zx::channel directory_request, bool service_isolate)
#define LOG_TAG
Definition: logging.h:11
Dart_Handle ToDart(const T &object)
bool LogIfError(Dart_Handle handle)
Definition: dart_error.cc:15
constexpr char kServiceRootPath[]

◆ Run()

void dart_runner::DartComponentController::Run ( )

Definition at line 344 of file dart_component_controller.cc.

References SendReturnCode().

344  {
345  async::PostTask(loop_->dispatcher(), [loop = loop_.get(), app = this] {
346  if (!app->Main()) {
347  loop->Quit();
348  }
349  });
350  loop_->Run();
351  SendReturnCode();
352 }

◆ SendReturnCode()

void dart_runner::DartComponentController::SendReturnCode ( )

Definition at line 463 of file dart_component_controller.cc.

Referenced by Run().

463  {
464  binding_.events().OnTerminated(return_code_,
465  fuchsia::sys::TerminationReason::EXITED);
466 }

◆ Setup()

bool dart_runner::DartComponentController::Setup ( )

Definition at line 131 of file dart_component_controller.cc.

References LOG_TAG.

131  {
132  // Name the thread after the url of the component being launched.
133  zx::thread::self()->set_property(ZX_PROP_NAME, label_.c_str(), label_.size());
134  Dart_SetThreadName(label_.c_str());
135 
136  if (!SetupNamespace()) {
137  return false;
138  }
139 
140  if (SetupFromAppSnapshot()) {
141  FX_LOGF(INFO, LOG_TAG, "%s is running from an app snapshot", url_.c_str());
142  } else if (SetupFromKernel()) {
143  FX_LOGF(INFO, LOG_TAG, "%s is running from kernel", url_.c_str());
144  } else {
145  FX_LOGF(ERROR, LOG_TAG,
146  "Could not find a program in %s. Was data specified"
147  " correctly in the component manifest?",
148  url_.c_str());
149  return false;
150  }
151 
152  return true;
153 }
#define LOG_TAG
Definition: logging.h:11

The documentation for this class was generated from the following files: