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>
19#include <zircon/syscalls/iob.h>
32constexpr char kGetSizeResult[] =
"GetSizeResult";
33constexpr char kHandlePairResult[] =
"HandlePairResult";
34constexpr char kHandleResult[] =
"HandleResult";
35constexpr char kReadResult[] =
"ReadResult";
36constexpr char kHandleInfo[] =
"HandleInfo";
37constexpr char kReadEtcResult[] =
"ReadEtcResult";
38constexpr char kWriteResult[] =
"WriteResult";
39constexpr char kFromFileResult[] =
"FromFileResult";
40constexpr char kMapResult[] =
"MapResult";
44 explicit ByteDataScope(Dart_Handle dart_handle) : dart_handle_(dart_handle) {
48 explicit ByteDataScope(
size_t size) {
49 dart_handle_ = Dart_NewTypedData(Dart_TypedData_kByteData, size);
61 void*
data()
const {
return data_; }
62 size_t size()
const {
return size_; }
63 Dart_Handle dart_handle()
const {
return dart_handle_; }
64 bool is_valid()
const {
return is_valid_; }
68 Dart_Handle result = Dart_TypedDataReleaseData(dart_handle_);
81 Dart_TypedData_Type
type;
84 Dart_TypedDataAcquireData(dart_handle_, &
type, &data_, &size);
86 type == Dart_TypedData_kByteData && data_;
94 Dart_Handle dart_handle_;
95 bool is_valid_ =
false;
97 void* data_ =
nullptr;
100Dart_Handle MakeHandleList(
const std::vector<zx_handle_t>& in_handles) {
103 Dart_Handle handle_type = class_library.
GetClass(
"zircon",
"Handle");
104 Dart_Handle list = Dart_NewListOfTypeFilled(
106 if (Dart_IsError(list))
108 for (
size_t i = 0;
i < in_handles.size();
i++) {
111 if (Dart_IsError(result))
117template <
class... Args>
118Dart_Handle ConstructDartObject(
const char* class_name, Args&&...
args) {
122 Dart_HandleFromPersistent(class_library.
GetClass(
"zircon", class_name));
126 Dart_StringToCString(Dart_ToString(
type), &cstr);
128 std::array<Dart_Handle,
sizeof...(Args)> args_array{
129 {std::forward<Args>(
args)...}};
131 Dart_New(
type, Dart_EmptyString(),
sizeof...(Args), args_array.data());
136Dart_Handle MakeHandleInfoList(
137 const std::vector<zx_handle_info_t>& in_handles) {
140 Dart_Handle handle_info_type = class_library.
GetClass(
"zircon", kHandleInfo);
141 Dart_Handle empty_handle_info = ConstructDartObject(
143 Dart_Handle list = Dart_NewListOfTypeFilled(
144 handle_info_type, empty_handle_info, in_handles.size());
145 if (Dart_IsError(list))
147 for (
size_t i = 0;
i < in_handles.size();
i++) {
149 Dart_Handle result = Dart_ListSetAt(
151 ConstructDartObject(kHandleInfo, handle,
ToDart(in_handles[
i].
type),
152 ToDart(in_handles[
i].rights)));
153 if (Dart_IsError(result))
159fdio_ns_t* GetNamespace() {
161 Dart_Handle zircon_lib = Dart_LookupLibrary(
ToDart(
"dart:zircon"));
163 Dart_Handle namespace_type =
164 Dart_GetNonNullableType(zircon_lib,
ToDart(
"_Namespace"), 0,
nullptr);
166 Dart_Handle namespace_field =
167 Dart_GetField(namespace_type,
ToDart(
"_namespace"));
169 uint64_t fdio_ns_ptr;
170 Dart_Handle result = Dart_IntegerToUint64(namespace_field, &fdio_ns_ptr);
173 return reinterpret_cast<fdio_ns_t*
>(fdio_ns_ptr);
178 if (!dir_fd.is_valid()) {
182 if (path !=
nullptr && *path ==
'/') {
186 if (zx_status_t status = fdio_open3_fd_at(
187 dir_fd.get(), path, uint64_t{fuchsia::io::PERM_READABLE}, &raw_fd);
200 zx_handle_t out0 = 0, out1 = 0;
201 zx_status_t status = zx_channel_create(options, &out0, &out1);
202 if (status != ZX_OK) {
203 return ConstructDartObject(kHandlePairResult, ToDart(status));
205 return ConstructDartObject(kHandlePairResult, ToDart(status),
213 return fdio_ns_service_connect(GetNamespace(), path.c_str(),
219 if (zx_status_t status = FdFromPath(path.c_str(), fd); status != ZX_OK) {
220 return ConstructDartObject(kHandleResult, ToDart(status));
224 if (zx_status_t status =
225 fdio_fd_transfer(fd.
release(), handle.reset_and_get_address());
227 return ConstructDartObject(kHandleResult, ToDart(status));
229 zx_info_handle_basic_t info;
230 if (zx_status_t status = handle.get_info(ZX_INFO_HANDLE_BASIC, &info,
231 sizeof(info),
nullptr,
nullptr);
233 return ConstructDartObject(kHandleResult, ToDart(status));
235 if (info.type != ZX_OBJ_TYPE_CHANNEL) {
236 return ConstructDartObject(kHandleResult, ToDart(ZX_ERR_WRONG_TYPE));
239 return ConstructDartObject(kHandleResult, ToDart(ZX_OK),
245 std::vector<Handle*> handles) {
248 return ZX_ERR_BAD_HANDLE;
251 std::vector<zx_handle_t> zx_handles;
252 for (
Handle* handle : handles) {
253 zx_handles.push_back(handle->handle());
256 zx_status_t status = zx_channel_write(
channel->handle(), 0,
data.data(),
257 data.length_in_bytes(),
258 zx_handles.data(), zx_handles.size());
260 for (
Handle* handle : handles) {
261 handle->ReleaseHandle();
271 std::vector<HandleDisposition*> handle_dispositions) {
274 return ZX_ERR_BAD_HANDLE;
277 std::vector<zx_handle_disposition_t> zx_handle_dispositions;
280 zx_handle_dispositions.push_back({.operation = handle->operation(),
281 .handle = handle->handle()->handle(),
282 .type = handle->type(),
283 .rights = handle->rights(),
287 zx_status_t status = zx_channel_write_etc(
289 zx_handle_dispositions.data(), zx_handle_dispositions.size());
291 for (
size_t i = 0;
i < handle_dispositions.size(); ++
i) {
292 handle_dispositions[
i]->set_result(zx_handle_dispositions[
i].result);
295 if (handle_dispositions[
i]->operation() != ZX_HANDLE_OP_DUPLICATE) {
296 handle_dispositions[
i]->handle()->ReleaseHandle();
306 return ConstructDartObject(kReadResult, ToDart(ZX_ERR_BAD_HANDLE));
309 uint32_t actual_bytes = 0;
310 uint32_t actual_handles = 0;
313 zx_status_t status = zx_channel_read(
channel->handle(), 0,
nullptr,
nullptr,
314 0, 0, &actual_bytes, &actual_handles);
315 if (status != ZX_ERR_BUFFER_TOO_SMALL) {
317 return ConstructDartObject(kReadResult, ToDart(status));
321 ByteDataScope bytes(actual_bytes);
323 std::vector<zx_handle_t> handles(actual_handles);
326 status = zx_channel_read(
channel->handle(), 0, bytes.data(), handles.data(),
327 bytes.size(), handles.size(), &actual_bytes,
329 FML_DCHECK(status != ZX_OK || bytes.size() == actual_bytes);
333 if (status == ZX_OK) {
337 return ConstructDartObject(kReadResult, ToDart(status), bytes.dart_handle(),
338 ToDart(actual_bytes), MakeHandleList(handles));
340 return ConstructDartObject(kReadResult, ToDart(status));
346 return ConstructDartObject(kReadEtcResult, ToDart(ZX_ERR_BAD_HANDLE));
349 uint32_t actual_bytes = 0;
350 uint32_t actual_handles = 0;
353 zx_status_t status = zx_channel_read(
channel->handle(), 0,
nullptr,
nullptr,
354 0, 0, &actual_bytes, &actual_handles);
355 if (status != ZX_ERR_BUFFER_TOO_SMALL) {
357 return ConstructDartObject(kReadEtcResult, ToDart(status));
361 ByteDataScope bytes(actual_bytes);
363 std::vector<zx_handle_info_t> handles(actual_handles);
366 status = zx_channel_read_etc(
channel->handle(), 0, bytes.data(),
367 handles.data(), bytes.size(), handles.size(),
368 &actual_bytes, &actual_handles);
369 FML_DCHECK(status != ZX_OK || bytes.size() == actual_bytes);
373 if (status == ZX_OK) {
377 return ConstructDartObject(kReadEtcResult, ToDart(status),
378 bytes.dart_handle(), ToDart(actual_bytes),
379 MakeHandleInfoList(handles));
381 return ConstructDartObject(kReadEtcResult, ToDart(status));
386 zx_handle_t out0 = 0, out1 = 0;
387 zx_status_t status = zx_eventpair_create(0, &out0, &out1);
388 if (status != ZX_OK) {
389 return ConstructDartObject(kHandlePairResult, ToDart(status));
391 return ConstructDartObject(kHandlePairResult, ToDart(status),
398 zx_handle_t out0 = 0, out1 = 0;
399 zx_status_t status = zx_socket_create(options, &out0, &out1);
400 if (status != ZX_OK) {
401 return ConstructDartObject(kHandlePairResult, ToDart(status));
403 return ConstructDartObject(kHandlePairResult, ToDart(status),
412 if (!socket || !socket->is_valid()) {
414 return ConstructDartObject(kWriteResult, ToDart(ZX_ERR_BAD_HANDLE));
418 zx_status_t status = zx_socket_write(socket->handle(), options,
data.data(),
419 data.length_in_bytes(), &actual);
421 return ConstructDartObject(kWriteResult, ToDart(status), ToDart(actual));
425 if (!socket || !socket->is_valid()) {
426 return ConstructDartObject(kReadResult, ToDart(ZX_ERR_BAD_HANDLE));
429 ByteDataScope bytes(size);
432 zx_socket_read(socket->handle(), 0, bytes.data(), size, &actual);
434 if (status == ZX_OK) {
436 return ConstructDartObject(kReadResult, ToDart(status), bytes.dart_handle(),
440 return ConstructDartObject(kReadResult, ToDart(status));
444 zx_handle_t vmo = ZX_HANDLE_INVALID;
445 zx_status_t status = zx_vmo_create(size, options, &vmo);
446 if (status != ZX_OK) {
447 return ConstructDartObject(kHandleResult, ToDart(status));
449 return ConstructDartObject(kHandleResult, ToDart(status),
456 if (zx_status_t status = FdFromPath(path.c_str(), fd); status != ZX_OK) {
457 return ConstructDartObject(kHandleResult, ToDart(status));
460 struct stat stat_struct;
461 if (fstat(fd.
get(), &stat_struct) != 0) {
463 return ConstructDartObject(kFromFileResult, ToDart(ZX_ERR_IO));
466 if (zx_status_t status =
467 fdio_get_vmo_clone(fd.
get(), vmo.reset_and_get_address());
469 return ConstructDartObject(kFromFileResult, ToDart(status));
472 return ConstructDartObject(kFromFileResult, ToDart(ZX_OK),
474 ToDart(stat_struct.st_size));
478 if (!vmo || !vmo->is_valid()) {
479 return ConstructDartObject(kGetSizeResult, ToDart(ZX_ERR_BAD_HANDLE));
483 zx_status_t status = zx_vmo_get_size(vmo->handle(), &size);
485 return ConstructDartObject(kGetSizeResult, ToDart(status), ToDart(size));
489 if (!vmo || !vmo->is_valid()) {
490 return ZX_ERR_BAD_HANDLE;
492 return zx_vmo_set_size(vmo->handle(), size);
498 if (!vmo || !vmo->is_valid()) {
500 return ZX_ERR_BAD_HANDLE;
504 zx_vmo_write(vmo->handle(),
data.data(), offset,
data.length_in_bytes());
513 if (!vmo || !vmo->is_valid()) {
514 return ConstructDartObject(kReadResult, ToDart(ZX_ERR_BAD_HANDLE));
518 ByteDataScope bytes(size);
519 zx_status_t status = zx_vmo_read(vmo->handle(), bytes.data(), offset, size);
521 if (status == ZX_OK) {
522 return ConstructDartObject(kReadResult, ToDart(status), bytes.dart_handle(),
525 return ConstructDartObject(kReadResult, ToDart(status));
534void System::VmoMapFinalizer(
void* isolate_callback_data,
void* peer) {
536 zx_vmar_unmap(zx_vmar_root_self(),
reinterpret_cast<uintptr_t
>(r->
region),
542 if (!vmo || !vmo->is_valid())
543 return ConstructDartObject(kMapResult, ToDart(ZX_ERR_BAD_HANDLE));
546 zx_status_t status = zx_vmo_get_size(vmo->handle(), &size);
548 return ConstructDartObject(kMapResult, ToDart(status));
550 uintptr_t mapped_addr;
551 status = zx_vmar_map(zx_vmar_root_self(), ZX_VM_PERM_READ, 0, vmo->handle(),
552 0, size, &mapped_addr);
554 return ConstructDartObject(kMapResult, ToDart(status));
556 void*
data =
reinterpret_cast<void*
>(mapped_addr);
557 Dart_Handle
object = Dart_NewExternalTypedData(Dart_TypedData_kUint8,
data,
558 static_cast<intptr_t
>(size));
562 Dart_NewFinalizableHandle(
object,
reinterpret_cast<void*
>(r),
563 static_cast<intptr_t
>(size) +
sizeof(*r),
564 System::VmoMapFinalizer);
566 return ConstructDartObject(kMapResult, ToDart(ZX_OK),
object);
570 uint32_t region_index,
572 if (!iob || !iob->is_valid()) {
574 return ZX_ERR_BAD_HANDLE;
577 zx_iovec_t vector = {.buffer =
const_cast<void*
>(
data.data()),
578 .capacity =
data.length_in_bytes()};
580 zx_iob_writev(iob->handle(), 0, region_index, &vector, 1);
587 return zx_clock_get_monotonic();
592#define FOR_EACH_STATIC_BINDING(V) \
593 V(System, ChannelCreate) \
594 V(System, ChannelFromFile) \
595 V(System, ChannelQueryAndRead) \
596 V(System, ChannelQueryAndReadEtc) \
597 V(System, ChannelWrite) \
598 V(System, ChannelWriteEtc) \
599 V(System, ClockGetMonotonic) \
600 V(System, ConnectToService) \
601 V(System, EventpairCreate) \
602 V(System, IobWrite) \
603 V(System, SocketCreate) \
604 V(System, SocketRead) \
605 V(System, SocketWrite) \
606 V(System, VmoCreate) \
607 V(System, VmoFromFile) \
608 V(System, VmoGetSize) \
611 V(System, VmoSetSize) \
617#define DART_REGISTER_NATIVE_STATIC_(CLASS, METHOD) \
618 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 zx_status_t IobWrite(fml::RefPtr< Handle > iob, uint32_t region_index, const tonic::DartByteData &data)
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