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 83 of file dart_component_controller.cc.

References LOG_TAG.

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

◆ ~DartComponentController()

dart_runner::DartComponentController::~DartComponentController ( )
override

Definition at line 123 of file dart_component_controller.cc.

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

Member Function Documentation

◆ Main()

bool dart_runner::DartComponentController::Main ( )

Definition at line 355 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().

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

References SendReturnCode().

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

◆ SendReturnCode()

void dart_runner::DartComponentController::SendReturnCode ( )

Definition at line 460 of file dart_component_controller.cc.

Referenced by Run().

460  {
461  binding_.events().OnTerminated(return_code_,
462  fuchsia::sys::TerminationReason::EXITED);
463 }

◆ Setup()

bool dart_runner::DartComponentController::Setup ( )

Definition at line 132 of file dart_component_controller.cc.

References LOG_TAG.

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

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