9#include <fuchsia/io/cpp/fidl.h>
10#include <lib/fdio/directory.h>
11#include <lib/fdio/fd.h>
12#include <lib/fdio/io.h>
13#include <lib/fdio/namespace.h>
14#include <lib/zx/channel.h>
17#include <zircon/process.h>
18#include <zircon/processargs.h>
31constexpr char kGetSizeResult[] =
"GetSizeResult";
32constexpr char kHandlePairResult[] =
"HandlePairResult";
33constexpr char kHandleResult[] =
"HandleResult";
34constexpr char kReadResult[] =
"ReadResult";
35constexpr char kHandleInfo[] =
"HandleInfo";
36constexpr char kReadEtcResult[] =
"ReadEtcResult";
37constexpr char kWriteResult[] =
"WriteResult";
38constexpr char kFromFileResult[] =
"FromFileResult";
39constexpr char kMapResult[] =
"MapResult";
43 explicit ByteDataScope(Dart_Handle dart_handle) : dart_handle_(dart_handle) {
47 explicit ByteDataScope(
size_t size) {
48 dart_handle_ = Dart_NewTypedData(Dart_TypedData_kByteData, size);
60 void*
data()
const {
return data_; }
61 size_t size()
const {
return size_; }
62 Dart_Handle dart_handle()
const {
return dart_handle_; }
63 bool is_valid()
const {
return is_valid_; }
67 Dart_Handle result = Dart_TypedDataReleaseData(dart_handle_);
80 Dart_TypedData_Type
type;
83 Dart_TypedDataAcquireData(dart_handle_, &
type, &data_, &size);
85 type == Dart_TypedData_kByteData && data_;
93 Dart_Handle dart_handle_;
94 bool is_valid_ =
false;
96 void* data_ =
nullptr;
99Dart_Handle MakeHandleList(
const std::vector<zx_handle_t>& in_handles) {
102 Dart_Handle handle_type = class_library.
GetClass(
"zircon",
"Handle");
103 Dart_Handle list = Dart_NewListOfTypeFilled(
105 if (Dart_IsError(list))
107 for (
size_t i = 0;
i < in_handles.size();
i++) {
110 if (Dart_IsError(result))
116template <
class... Args>
117Dart_Handle ConstructDartObject(
const char* class_name, Args&&...
args) {
121 Dart_HandleFromPersistent(class_library.
GetClass(
"zircon", class_name));
125 Dart_StringToCString(Dart_ToString(
type), &cstr);
127 std::array<Dart_Handle,
sizeof...(Args)> args_array{
128 {std::forward<Args>(
args)...}};
130 Dart_New(
type, Dart_EmptyString(),
sizeof...(Args), args_array.data());
135Dart_Handle MakeHandleInfoList(
136 const std::vector<zx_handle_info_t>& in_handles) {
139 Dart_Handle handle_info_type = class_library.
GetClass(
"zircon", kHandleInfo);
140 Dart_Handle empty_handle_info = ConstructDartObject(
142 Dart_Handle list = Dart_NewListOfTypeFilled(
143 handle_info_type, empty_handle_info, in_handles.size());
144 if (Dart_IsError(list))
146 for (
size_t i = 0;
i < in_handles.size();
i++) {
148 Dart_Handle result = Dart_ListSetAt(
150 ConstructDartObject(kHandleInfo, handle,
ToDart(in_handles[
i].
type),
151 ToDart(in_handles[
i].rights)));
152 if (Dart_IsError(result))
158fdio_ns_t* GetNamespace() {
160 Dart_Handle zircon_lib = Dart_LookupLibrary(
ToDart(
"dart:zircon"));
162 Dart_Handle namespace_type =
163 Dart_GetNonNullableType(zircon_lib,
ToDart(
"_Namespace"), 0,
nullptr);
165 Dart_Handle namespace_field =
166 Dart_GetField(namespace_type,
ToDart(
"_namespace"));
168 uint64_t fdio_ns_ptr;
169 Dart_Handle result = Dart_IntegerToUint64(namespace_field, &fdio_ns_ptr);
172 return reinterpret_cast<fdio_ns_t*
>(fdio_ns_ptr);
177 if (!dir_fd.is_valid()) {
181 if (path !=
nullptr && *path ==
'/') {
185 if (zx_status_t status = fdio_open3_fd_at(
186 dir_fd.get(), path, uint64_t{fuchsia::io::PERM_READABLE}, &raw_fd);
199 zx_handle_t out0 = 0, out1 = 0;
200 zx_status_t status = zx_channel_create(options, &out0, &out1);
201 if (status != ZX_OK) {
202 return ConstructDartObject(kHandlePairResult, ToDart(status));
204 return ConstructDartObject(kHandlePairResult, ToDart(status),
212 return fdio_ns_service_connect(GetNamespace(), path.c_str(),
218 if (zx_status_t status = FdFromPath(path.c_str(), fd); status != ZX_OK) {
219 return ConstructDartObject(kHandleResult, ToDart(status));
223 if (zx_status_t status =
224 fdio_fd_transfer(fd.
release(), handle.reset_and_get_address());
226 return ConstructDartObject(kHandleResult, ToDart(status));
228 zx_info_handle_basic_t info;
229 if (zx_status_t status = handle.get_info(ZX_INFO_HANDLE_BASIC, &info,
230 sizeof(info),
nullptr,
nullptr);
232 return ConstructDartObject(kHandleResult, ToDart(status));
234 if (info.type != ZX_OBJ_TYPE_CHANNEL) {
235 return ConstructDartObject(kHandleResult, ToDart(ZX_ERR_WRONG_TYPE));
238 return ConstructDartObject(kHandleResult, ToDart(ZX_OK),
244 std::vector<Handle*> handles) {
247 return ZX_ERR_BAD_HANDLE;
250 std::vector<zx_handle_t> zx_handles;
251 for (
Handle* handle : handles) {
252 zx_handles.push_back(handle->handle());
255 zx_status_t status = zx_channel_write(
channel->handle(), 0,
data.data(),
256 data.length_in_bytes(),
257 zx_handles.data(), zx_handles.size());
259 for (
Handle* handle : handles) {
260 handle->ReleaseHandle();
270 std::vector<HandleDisposition*> handle_dispositions) {
273 return ZX_ERR_BAD_HANDLE;
276 std::vector<zx_handle_disposition_t> zx_handle_dispositions;
279 zx_handle_dispositions.push_back({.operation = handle->operation(),
280 .handle = handle->handle()->handle(),
281 .type = handle->type(),
282 .rights = handle->rights(),
286 zx_status_t status = zx_channel_write_etc(
288 zx_handle_dispositions.data(), zx_handle_dispositions.size());
290 for (
size_t i = 0;
i < handle_dispositions.size(); ++
i) {
291 handle_dispositions[
i]->set_result(zx_handle_dispositions[
i].result);
294 if (handle_dispositions[
i]->operation() != ZX_HANDLE_OP_DUPLICATE) {
295 handle_dispositions[
i]->handle()->ReleaseHandle();
305 return ConstructDartObject(kReadResult, ToDart(ZX_ERR_BAD_HANDLE));
308 uint32_t actual_bytes = 0;
309 uint32_t actual_handles = 0;
312 zx_status_t status = zx_channel_read(
channel->handle(), 0,
nullptr,
nullptr,
313 0, 0, &actual_bytes, &actual_handles);
314 if (status != ZX_ERR_BUFFER_TOO_SMALL) {
316 return ConstructDartObject(kReadResult, ToDart(status));
320 ByteDataScope bytes(actual_bytes);
322 std::vector<zx_handle_t> handles(actual_handles);
325 status = zx_channel_read(
channel->handle(), 0, bytes.data(), handles.data(),
326 bytes.size(), handles.size(), &actual_bytes,
328 FML_DCHECK(status != ZX_OK || bytes.size() == actual_bytes);
332 if (status == ZX_OK) {
336 return ConstructDartObject(kReadResult, ToDart(status), bytes.dart_handle(),
337 ToDart(actual_bytes), MakeHandleList(handles));
339 return ConstructDartObject(kReadResult, ToDart(status));
345 return ConstructDartObject(kReadEtcResult, ToDart(ZX_ERR_BAD_HANDLE));
348 uint32_t actual_bytes = 0;
349 uint32_t actual_handles = 0;
352 zx_status_t status = zx_channel_read(
channel->handle(), 0,
nullptr,
nullptr,
353 0, 0, &actual_bytes, &actual_handles);
354 if (status != ZX_ERR_BUFFER_TOO_SMALL) {
356 return ConstructDartObject(kReadEtcResult, ToDart(status));
360 ByteDataScope bytes(actual_bytes);
362 std::vector<zx_handle_info_t> handles(actual_handles);
365 status = zx_channel_read_etc(
channel->handle(), 0, bytes.data(),
366 handles.data(), bytes.size(), handles.size(),
367 &actual_bytes, &actual_handles);
368 FML_DCHECK(status != ZX_OK || bytes.size() == actual_bytes);
372 if (status == ZX_OK) {
376 return ConstructDartObject(kReadEtcResult, ToDart(status),
377 bytes.dart_handle(), ToDart(actual_bytes),
378 MakeHandleInfoList(handles));
380 return ConstructDartObject(kReadEtcResult, ToDart(status));
385 zx_handle_t out0 = 0, out1 = 0;
386 zx_status_t status = zx_eventpair_create(0, &out0, &out1);
387 if (status != ZX_OK) {
388 return ConstructDartObject(kHandlePairResult, ToDart(status));
390 return ConstructDartObject(kHandlePairResult, ToDart(status),
397 zx_handle_t out0 = 0, out1 = 0;
398 zx_status_t status = zx_socket_create(options, &out0, &out1);
399 if (status != ZX_OK) {
400 return ConstructDartObject(kHandlePairResult, ToDart(status));
402 return ConstructDartObject(kHandlePairResult, ToDart(status),
411 if (!socket || !socket->is_valid()) {
413 return ConstructDartObject(kWriteResult, ToDart(ZX_ERR_BAD_HANDLE));
417 zx_status_t status = zx_socket_write(socket->handle(), options,
data.data(),
418 data.length_in_bytes(), &actual);
420 return ConstructDartObject(kWriteResult, ToDart(status), ToDart(actual));
424 if (!socket || !socket->is_valid()) {
425 return ConstructDartObject(kReadResult, ToDart(ZX_ERR_BAD_HANDLE));
428 ByteDataScope bytes(size);
431 zx_socket_read(socket->handle(), 0, bytes.data(), size, &actual);
433 if (status == ZX_OK) {
435 return ConstructDartObject(kReadResult, ToDart(status), bytes.dart_handle(),
439 return ConstructDartObject(kReadResult, ToDart(status));
443 zx_handle_t vmo = ZX_HANDLE_INVALID;
444 zx_status_t status = zx_vmo_create(size, options, &vmo);
445 if (status != ZX_OK) {
446 return ConstructDartObject(kHandleResult, ToDart(status));
448 return ConstructDartObject(kHandleResult, ToDart(status),
455 if (zx_status_t status = FdFromPath(path.c_str(), fd); status != ZX_OK) {
456 return ConstructDartObject(kHandleResult, ToDart(status));
459 struct stat stat_struct;
460 if (fstat(fd.
get(), &stat_struct) != 0) {
462 return ConstructDartObject(kFromFileResult, ToDart(ZX_ERR_IO));
465 if (zx_status_t status =
466 fdio_get_vmo_clone(fd.
get(), vmo.reset_and_get_address());
468 return ConstructDartObject(kFromFileResult, ToDart(status));
471 return ConstructDartObject(kFromFileResult, ToDart(ZX_OK),
473 ToDart(stat_struct.st_size));
477 if (!vmo || !vmo->is_valid()) {
478 return ConstructDartObject(kGetSizeResult, ToDart(ZX_ERR_BAD_HANDLE));
482 zx_status_t status = zx_vmo_get_size(vmo->handle(), &size);
484 return ConstructDartObject(kGetSizeResult, ToDart(status), ToDart(size));
488 if (!vmo || !vmo->is_valid()) {
489 return ZX_ERR_BAD_HANDLE;
491 return zx_vmo_set_size(vmo->handle(), size);
497 if (!vmo || !vmo->is_valid()) {
499 return ZX_ERR_BAD_HANDLE;
503 zx_vmo_write(vmo->handle(),
data.data(), offset,
data.length_in_bytes());
512 if (!vmo || !vmo->is_valid()) {
513 return ConstructDartObject(kReadResult, ToDart(ZX_ERR_BAD_HANDLE));
517 ByteDataScope bytes(size);
518 zx_status_t status = zx_vmo_read(vmo->handle(), bytes.data(), offset, size);
520 if (status == ZX_OK) {
521 return ConstructDartObject(kReadResult, ToDart(status), bytes.dart_handle(),
524 return ConstructDartObject(kReadResult, ToDart(status));
533void System::VmoMapFinalizer(
void* isolate_callback_data,
void* peer) {
535 zx_vmar_unmap(zx_vmar_root_self(),
reinterpret_cast<uintptr_t
>(r->
region),
541 if (!vmo || !vmo->is_valid())
542 return ConstructDartObject(kMapResult, ToDart(ZX_ERR_BAD_HANDLE));
545 zx_status_t status = zx_vmo_get_size(vmo->handle(), &size);
547 return ConstructDartObject(kMapResult, ToDart(status));
549 uintptr_t mapped_addr;
550 status = zx_vmar_map(zx_vmar_root_self(), ZX_VM_PERM_READ, 0, vmo->handle(),
551 0, size, &mapped_addr);
553 return ConstructDartObject(kMapResult, ToDart(status));
555 void*
data =
reinterpret_cast<void*
>(mapped_addr);
556 Dart_Handle
object = Dart_NewExternalTypedData(Dart_TypedData_kUint8,
data,
557 static_cast<intptr_t
>(size));
561 Dart_NewFinalizableHandle(
object,
reinterpret_cast<void*
>(r),
562 static_cast<intptr_t
>(size) +
sizeof(*r),
563 System::VmoMapFinalizer);
565 return ConstructDartObject(kMapResult, ToDart(ZX_OK),
object);
569 return zx_clock_get_monotonic();
574#define FOR_EACH_STATIC_BINDING(V) \
575 V(System, ChannelCreate) \
576 V(System, ChannelFromFile) \
577 V(System, ChannelWrite) \
578 V(System, ChannelWriteEtc) \
579 V(System, ChannelQueryAndRead) \
580 V(System, ChannelQueryAndReadEtc) \
581 V(System, EventpairCreate) \
582 V(System, ConnectToService) \
583 V(System, SocketCreate) \
584 V(System, SocketWrite) \
585 V(System, SocketRead) \
586 V(System, VmoCreate) \
587 V(System, VmoFromFile) \
588 V(System, VmoGetSize) \
589 V(System, VmoSetSize) \
591 V(System, VmoWrite) \
593 V(System, ClockGetMonotonic)
598#define DART_REGISTER_NATIVE_STATIC_(CLASS, METHOD) \
599 DART_REGISTER_NATIVE_STATIC(CLASS, METHOD),
void reset(const T &value=Traits::InvalidValue())
Dart_PersistentHandle GetClass(const DartWrapperInfo &info)
static DartState * Current()
DartClassLibrary & class_library()
static Dart_Handle CreateInvalid()
static fml::RefPtr< Handle > Create(zx_handle_t handle)
static Dart_Handle ChannelCreate(uint32_t options)
static Dart_Handle SocketCreate(uint32_t options)
static Dart_Handle VmoCreate(uint64_t size, uint32_t options)
static Dart_Handle VmoMap(fml::RefPtr< Handle > vmo)
static zx_status_t VmoWrite(fml::RefPtr< Handle > vmo, uint64_t offset, const tonic::DartByteData &data)
static Dart_Handle SocketWrite(fml::RefPtr< Handle > socket, const tonic::DartByteData &data, int options)
static Dart_Handle VmoRead(fml::RefPtr< Handle > vmo, uint64_t offset, size_t size)
static uint64_t ClockGetMonotonic()
static Dart_Handle VmoFromFile(std::string path)
static zx_status_t ChannelWriteEtc(fml::RefPtr< Handle > channel, const tonic::DartByteData &data, std::vector< HandleDisposition * > handle_dispositions)
static zx_status_t ConnectToService(std::string path, fml::RefPtr< Handle > channel)
static Dart_Handle ChannelQueryAndReadEtc(fml::RefPtr< Handle > channel)
static Dart_Handle EventpairCreate(uint32_t options)
static Dart_Handle ChannelFromFile(std::string path)
static zx_status_t ChannelWrite(fml::RefPtr< Handle > channel, const tonic::DartByteData &data, std::vector< Handle * > handles)
static Dart_Handle VmoGetSize(fml::RefPtr< Handle > vmo)
static Dart_Handle ChannelQueryAndRead(fml::RefPtr< Handle > channel)
static zx_status_t VmoSetSize(fml::RefPtr< Handle > vmo, uint64_t size)
static Dart_Handle SocketRead(fml::RefPtr< Handle > socket, size_t size)
#define DART_NATIVE_CALLBACK_STATIC(CLASS, METHOD)
#define IMPLEMENT_WRAPPERTYPEINFO(LibraryName, ClassName)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
#define FML_DCHECK(condition)
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via dart
Dart_Handle ToDart(const T &object)
bool CheckAndHandleError(Dart_Handle handle)
#define FOR_EACH_STATIC_BINDING(V)
#define DART_REGISTER_NATIVE_STATIC_(CLASS, METHOD)
SizedRegion(void *r, size_t s)
std::shared_ptr< const fml::Mapping > data