1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "isolate_configurator.h"
6
7 #include "dart-pkg/fuchsia/sdk_ext/fuchsia.h"
8 #include "dart-pkg/zircon/sdk_ext/handle.h"
9 #include "third_party/dart/runtime/include/dart_api.h"
10 #include "third_party/tonic/converter/dart_converter.h"
11 #include "third_party/tonic/dart_state.h"
12 #include "third_party/tonic/logging/dart_error.h"
13
14 namespace flutter_runner {
15
IsolateConfigurator(UniqueFDIONS fdio_ns,fidl::InterfaceHandle<fuchsia::sys::Environment> environment,zx::channel directory_request)16 IsolateConfigurator::IsolateConfigurator(
17 UniqueFDIONS fdio_ns,
18 fidl::InterfaceHandle<fuchsia::sys::Environment> environment,
19 zx::channel directory_request)
20 : fdio_ns_(std::move(fdio_ns)),
21 environment_(std::move(environment)),
22 directory_request_(std::move(directory_request)) {}
23
24 IsolateConfigurator::~IsolateConfigurator() = default;
25
ConfigureCurrentIsolate()26 bool IsolateConfigurator::ConfigureCurrentIsolate() {
27 if (used_) {
28 return false;
29 }
30 used_ = true;
31
32 BindFuchsia();
33 BindZircon();
34 BindDartIO();
35
36 // This is now owned by the Dart bindings. So relinquish our ownership of the
37 // handle.
38 (void)fdio_ns_.release();
39
40 return true;
41 }
42
BindFuchsia()43 void IsolateConfigurator::BindFuchsia() {
44 fuchsia::dart::Initialize(std::move(environment_),
45 std::move(directory_request_));
46 }
47
BindZircon()48 void IsolateConfigurator::BindZircon() {
49 // Tell dart:zircon about the FDIO namespace configured for this instance.
50 Dart_Handle zircon_lib = Dart_LookupLibrary(tonic::ToDart("dart:zircon"));
51 FML_CHECK(!tonic::LogIfError(zircon_lib));
52
53 Dart_Handle namespace_type =
54 Dart_GetType(zircon_lib, tonic::ToDart("_Namespace"), 0, nullptr);
55 FML_CHECK(!tonic::LogIfError(namespace_type));
56
57 Dart_Handle result =
58 Dart_SetField(namespace_type, //
59 tonic::ToDart("_namespace"), //
60 tonic::ToDart(reinterpret_cast<intptr_t>(fdio_ns_.get())));
61 FML_CHECK(!tonic::LogIfError(result));
62 }
63
BindDartIO()64 void IsolateConfigurator::BindDartIO() {
65 // Grab the dart:io lib.
66 Dart_Handle io_lib = Dart_LookupLibrary(tonic::ToDart("dart:io"));
67 FML_CHECK(!tonic::LogIfError(io_lib));
68
69 // Disable dart:io exit()
70 Dart_Handle embedder_config_type =
71 Dart_GetType(io_lib, tonic::ToDart("_EmbedderConfig"), 0, nullptr);
72 FML_CHECK(!tonic::LogIfError(embedder_config_type));
73
74 Dart_Handle result = Dart_SetField(embedder_config_type,
75 tonic::ToDart("_mayExit"), Dart_False());
76 FML_CHECK(!tonic::LogIfError(result));
77
78 // Tell dart:io about the FDIO namespace configured for this instance.
79 Dart_Handle namespace_type =
80 Dart_GetType(io_lib, tonic::ToDart("_Namespace"), 0, nullptr);
81 FML_CHECK(!tonic::LogIfError(namespace_type));
82
83 Dart_Handle namespace_args[] = {
84 Dart_NewInteger(reinterpret_cast<intptr_t>(fdio_ns_.get())), //
85 };
86 result = Dart_Invoke(namespace_type, tonic::ToDart("_setupNamespace"), 1,
87 namespace_args);
88 FML_CHECK(!tonic::LogIfError(result));
89 }
90
91 } // namespace flutter_runner
92