Flutter Engine
 
Loading...
Searching...
No Matches
system.cc
Go to the documentation of this file.
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 "system.h"
6
7#include <array>
8
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>
15#include <sys/stat.h>
16#include <unistd.h>
17#include <zircon/process.h>
18#include <zircon/processargs.h>
19
23
24using tonic::ToDart;
25
26namespace zircon {
27namespace dart {
28
29namespace {
30
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";
40
41class ByteDataScope {
42 public:
43 explicit ByteDataScope(Dart_Handle dart_handle) : dart_handle_(dart_handle) {
44 Acquire();
45 }
46
47 explicit ByteDataScope(size_t size) {
48 dart_handle_ = Dart_NewTypedData(Dart_TypedData_kByteData, size);
50 Acquire();
51 FML_DCHECK(size == size_);
52 }
53
54 ~ByteDataScope() {
55 if (is_valid_) {
56 Release();
57 }
58 }
59
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_; }
64
65 void Release() {
66 FML_DCHECK(is_valid_);
67 Dart_Handle result = Dart_TypedDataReleaseData(dart_handle_);
69 is_valid_ = false;
70 data_ = nullptr;
71 size_ = 0;
72 }
73
74 private:
75 void Acquire() {
76 FML_DCHECK(size_ == 0);
77 FML_DCHECK(data_ == nullptr);
78 FML_DCHECK(!is_valid_);
79
80 Dart_TypedData_Type type;
81 intptr_t size;
82 Dart_Handle result =
83 Dart_TypedDataAcquireData(dart_handle_, &type, &data_, &size);
84 is_valid_ = !tonic::CheckAndHandleError(result) &&
85 type == Dart_TypedData_kByteData && data_;
86 if (is_valid_) {
87 size_ = size;
88 } else {
89 size_ = 0;
90 }
91 }
92
93 Dart_Handle dart_handle_;
94 bool is_valid_ = false;
95 size_t size_ = 0;
96 void* data_ = nullptr;
97};
98
99Dart_Handle MakeHandleList(const std::vector<zx_handle_t>& in_handles) {
100 tonic::DartClassLibrary& class_library =
102 Dart_Handle handle_type = class_library.GetClass("zircon", "Handle");
103 Dart_Handle list = Dart_NewListOfTypeFilled(
104 handle_type, Handle::CreateInvalid(), in_handles.size());
105 if (Dart_IsError(list))
106 return list;
107 for (size_t i = 0; i < in_handles.size(); i++) {
108 Dart_Handle result =
109 Dart_ListSetAt(list, i, ToDart(Handle::Create(in_handles[i])));
110 if (Dart_IsError(result))
111 return result;
112 }
113 return list;
114}
115
116template <class... Args>
117Dart_Handle ConstructDartObject(const char* class_name, Args&&... args) {
118 tonic::DartClassLibrary& class_library =
120 Dart_Handle type =
121 Dart_HandleFromPersistent(class_library.GetClass("zircon", class_name));
123
124 const char* cstr;
125 Dart_StringToCString(Dart_ToString(type), &cstr);
126
127 std::array<Dart_Handle, sizeof...(Args)> args_array{
128 {std::forward<Args>(args)...}};
129 Dart_Handle object =
130 Dart_New(type, Dart_EmptyString(), sizeof...(Args), args_array.data());
132 return object;
133}
134
135Dart_Handle MakeHandleInfoList(
136 const std::vector<zx_handle_info_t>& in_handles) {
137 tonic::DartClassLibrary& class_library =
139 Dart_Handle handle_info_type = class_library.GetClass("zircon", kHandleInfo);
140 Dart_Handle empty_handle_info = ConstructDartObject(
141 kHandleInfo, ToDart(Handle::CreateInvalid()), ToDart(-1), ToDart(-1));
142 Dart_Handle list = Dart_NewListOfTypeFilled(
143 handle_info_type, empty_handle_info, in_handles.size());
144 if (Dart_IsError(list))
145 return list;
146 for (size_t i = 0; i < in_handles.size(); i++) {
147 Dart_Handle handle = ToDart(Handle::Create(in_handles[i].handle));
148 Dart_Handle result = Dart_ListSetAt(
149 list, i,
150 ConstructDartObject(kHandleInfo, handle, ToDart(in_handles[i].type),
151 ToDart(in_handles[i].rights)));
152 if (Dart_IsError(result))
153 return result;
154 }
155 return list;
156}
157
158fdio_ns_t* GetNamespace() {
159 // Grab the fdio_ns_t* out of the isolate.
160 Dart_Handle zircon_lib = Dart_LookupLibrary(ToDart("dart:zircon"));
162 Dart_Handle namespace_type =
163 Dart_GetNonNullableType(zircon_lib, ToDart("_Namespace"), 0, nullptr);
164 FML_DCHECK(!tonic::CheckAndHandleError(namespace_type));
165 Dart_Handle namespace_field =
166 Dart_GetField(namespace_type, ToDart("_namespace"));
167 FML_DCHECK(!tonic::CheckAndHandleError(namespace_field));
168 uint64_t fdio_ns_ptr;
169 Dart_Handle result = Dart_IntegerToUint64(namespace_field, &fdio_ns_ptr);
171
172 return reinterpret_cast<fdio_ns_t*>(fdio_ns_ptr);
173}
174
175zx_status_t FdFromPath(const char* path, fml::UniqueFD& fd) {
176 fml::UniqueFD dir_fd(fdio_ns_opendir(GetNamespace()));
177 if (!dir_fd.is_valid()) {
178 // TODO: can we return errno?
179 return ZX_ERR_IO;
180 }
181 if (path != nullptr && *path == '/') {
182 path++;
183 }
184 int raw_fd;
185 if (zx_status_t status = fdio_open3_fd_at(
186 dir_fd.get(), path, uint64_t{fuchsia::io::PERM_READABLE}, &raw_fd);
187 status != ZX_OK) {
188 return status;
189 }
190 fd.reset(raw_fd);
191 return ZX_OK;
192}
193
194} // namespace
195
197
198Dart_Handle System::ChannelCreate(uint32_t options) {
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));
203 } else {
204 return ConstructDartObject(kHandlePairResult, ToDart(status),
205 ToDart(Handle::Create(out0)),
206 ToDart(Handle::Create(out1)));
207 }
208}
209
210zx_status_t System::ConnectToService(std::string path,
212 return fdio_ns_service_connect(GetNamespace(), path.c_str(),
213 channel->ReleaseHandle());
214}
215
216Dart_Handle System::ChannelFromFile(std::string path) {
217 fml::UniqueFD fd;
218 if (zx_status_t status = FdFromPath(path.c_str(), fd); status != ZX_OK) {
219 return ConstructDartObject(kHandleResult, ToDart(status));
220 }
221
222 zx::handle handle;
223 if (zx_status_t status =
224 fdio_fd_transfer(fd.release(), handle.reset_and_get_address());
225 status != ZX_OK) {
226 return ConstructDartObject(kHandleResult, ToDart(status));
227 }
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);
231 status != ZX_OK) {
232 return ConstructDartObject(kHandleResult, ToDart(status));
233 }
234 if (info.type != ZX_OBJ_TYPE_CHANNEL) {
235 return ConstructDartObject(kHandleResult, ToDart(ZX_ERR_WRONG_TYPE));
236 }
237
238 return ConstructDartObject(kHandleResult, ToDart(ZX_OK),
239 ToDart(Handle::Create(handle.release())));
240}
241
244 std::vector<Handle*> handles) {
245 if (!channel || !channel->is_valid()) {
246 data.Release();
247 return ZX_ERR_BAD_HANDLE;
248 }
249
250 std::vector<zx_handle_t> zx_handles;
251 for (Handle* handle : handles) {
252 zx_handles.push_back(handle->handle());
253 }
254
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());
258 // Handles are always consumed.
259 for (Handle* handle : handles) {
260 handle->ReleaseHandle();
261 }
262
263 data.Release();
264 return status;
265}
266
270 std::vector<HandleDisposition*> handle_dispositions) {
271 if (!channel || !channel->is_valid()) {
272 data.Release();
273 return ZX_ERR_BAD_HANDLE;
274 }
275
276 std::vector<zx_handle_disposition_t> zx_handle_dispositions;
277 for (HandleDisposition* handle : handle_dispositions) {
278 FML_DCHECK(handle->result() == ZX_OK);
279 zx_handle_dispositions.push_back({.operation = handle->operation(),
280 .handle = handle->handle()->handle(),
281 .type = handle->type(),
282 .rights = handle->rights(),
283 .result = ZX_OK});
284 }
285
286 zx_status_t status = zx_channel_write_etc(
287 channel->handle(), 0, data.data(), data.length_in_bytes(),
288 zx_handle_dispositions.data(), zx_handle_dispositions.size());
289
290 for (size_t i = 0; i < handle_dispositions.size(); ++i) {
291 handle_dispositions[i]->set_result(zx_handle_dispositions[i].result);
292
293 // Handles that are not copied (i.e. moved) are always consumed.
294 if (handle_dispositions[i]->operation() != ZX_HANDLE_OP_DUPLICATE) {
295 handle_dispositions[i]->handle()->ReleaseHandle();
296 }
297 }
298
299 data.Release();
300 return status;
301}
302
304 if (!channel || !channel->is_valid()) {
305 return ConstructDartObject(kReadResult, ToDart(ZX_ERR_BAD_HANDLE));
306 }
307
308 uint32_t actual_bytes = 0;
309 uint32_t actual_handles = 0;
310
311 // Query the size of the next message.
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) {
315 // An empty message or an error.
316 return ConstructDartObject(kReadResult, ToDart(status));
317 }
318
319 // Allocate space for the bytes and handles.
320 ByteDataScope bytes(actual_bytes);
321 FML_DCHECK(bytes.is_valid());
322 std::vector<zx_handle_t> handles(actual_handles);
323
324 // Make the call to actually get the message.
325 status = zx_channel_read(channel->handle(), 0, bytes.data(), handles.data(),
326 bytes.size(), handles.size(), &actual_bytes,
327 &actual_handles);
328 FML_DCHECK(status != ZX_OK || bytes.size() == actual_bytes);
329
330 bytes.Release();
331
332 if (status == ZX_OK) {
333 FML_DCHECK(handles.size() == actual_handles);
334
335 // return a ReadResult object.
336 return ConstructDartObject(kReadResult, ToDart(status), bytes.dart_handle(),
337 ToDart(actual_bytes), MakeHandleList(handles));
338 } else {
339 return ConstructDartObject(kReadResult, ToDart(status));
340 }
341}
342
344 if (!channel || !channel->is_valid()) {
345 return ConstructDartObject(kReadEtcResult, ToDart(ZX_ERR_BAD_HANDLE));
346 }
347
348 uint32_t actual_bytes = 0;
349 uint32_t actual_handles = 0;
350
351 // Query the size of the next message.
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) {
355 // An empty message or an error.
356 return ConstructDartObject(kReadEtcResult, ToDart(status));
357 }
358
359 // Allocate space for the bytes and handles.
360 ByteDataScope bytes(actual_bytes);
361 FML_DCHECK(bytes.is_valid());
362 std::vector<zx_handle_info_t> handles(actual_handles);
363
364 // Make the call to actually get the message.
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);
369
370 bytes.Release();
371
372 if (status == ZX_OK) {
373 FML_DCHECK(handles.size() == actual_handles);
374
375 // return a ReadResult object.
376 return ConstructDartObject(kReadEtcResult, ToDart(status),
377 bytes.dart_handle(), ToDart(actual_bytes),
378 MakeHandleInfoList(handles));
379 } else {
380 return ConstructDartObject(kReadEtcResult, ToDart(status));
381 }
382}
383
384Dart_Handle System::EventpairCreate(uint32_t options) {
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));
389 } else {
390 return ConstructDartObject(kHandlePairResult, ToDart(status),
391 ToDart(Handle::Create(out0)),
392 ToDart(Handle::Create(out1)));
393 }
394}
395
396Dart_Handle System::SocketCreate(uint32_t options) {
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));
401 } else {
402 return ConstructDartObject(kHandlePairResult, ToDart(status),
403 ToDart(Handle::Create(out0)),
404 ToDart(Handle::Create(out1)));
405 }
406}
407
410 int options) {
411 if (!socket || !socket->is_valid()) {
412 data.Release();
413 return ConstructDartObject(kWriteResult, ToDart(ZX_ERR_BAD_HANDLE));
414 }
415
416 size_t actual;
417 zx_status_t status = zx_socket_write(socket->handle(), options, data.data(),
418 data.length_in_bytes(), &actual);
419 data.Release();
420 return ConstructDartObject(kWriteResult, ToDart(status), ToDart(actual));
421}
422
423Dart_Handle System::SocketRead(fml::RefPtr<Handle> socket, size_t size) {
424 if (!socket || !socket->is_valid()) {
425 return ConstructDartObject(kReadResult, ToDart(ZX_ERR_BAD_HANDLE));
426 }
427
428 ByteDataScope bytes(size);
429 size_t actual;
430 zx_status_t status =
431 zx_socket_read(socket->handle(), 0, bytes.data(), size, &actual);
432 bytes.Release();
433 if (status == ZX_OK) {
434 FML_DCHECK(actual <= size);
435 return ConstructDartObject(kReadResult, ToDart(status), bytes.dart_handle(),
436 ToDart(actual));
437 }
438
439 return ConstructDartObject(kReadResult, ToDart(status));
440}
441
442Dart_Handle System::VmoCreate(uint64_t size, uint32_t options) {
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));
447 } else {
448 return ConstructDartObject(kHandleResult, ToDart(status),
449 ToDart(Handle::Create(vmo)));
450 }
451}
452
453Dart_Handle System::VmoFromFile(std::string path) {
454 fml::UniqueFD fd;
455 if (zx_status_t status = FdFromPath(path.c_str(), fd); status != ZX_OK) {
456 return ConstructDartObject(kHandleResult, ToDart(status));
457 }
458
459 struct stat stat_struct;
460 if (fstat(fd.get(), &stat_struct) != 0) {
461 // TODO: can we return errno?
462 return ConstructDartObject(kFromFileResult, ToDart(ZX_ERR_IO));
463 }
464 zx::vmo vmo;
465 if (zx_status_t status =
466 fdio_get_vmo_clone(fd.get(), vmo.reset_and_get_address());
467 status != ZX_OK) {
468 return ConstructDartObject(kFromFileResult, ToDart(status));
469 }
470
471 return ConstructDartObject(kFromFileResult, ToDart(ZX_OK),
472 ToDart(Handle::Create(vmo.release())),
473 ToDart(stat_struct.st_size));
474}
475
477 if (!vmo || !vmo->is_valid()) {
478 return ConstructDartObject(kGetSizeResult, ToDart(ZX_ERR_BAD_HANDLE));
479 }
480
481 uint64_t size;
482 zx_status_t status = zx_vmo_get_size(vmo->handle(), &size);
483
484 return ConstructDartObject(kGetSizeResult, ToDart(status), ToDart(size));
485}
486
487zx_status_t System::VmoSetSize(fml::RefPtr<Handle> vmo, uint64_t size) {
488 if (!vmo || !vmo->is_valid()) {
489 return ZX_ERR_BAD_HANDLE;
490 }
491 return zx_vmo_set_size(vmo->handle(), size);
492}
493
495 uint64_t offset,
496 const tonic::DartByteData& data) {
497 if (!vmo || !vmo->is_valid()) {
498 data.Release();
499 return ZX_ERR_BAD_HANDLE;
500 }
501
502 zx_status_t status =
503 zx_vmo_write(vmo->handle(), data.data(), offset, data.length_in_bytes());
504
505 data.Release();
506 return status;
507}
508
510 uint64_t offset,
511 size_t size) {
512 if (!vmo || !vmo->is_valid()) {
513 return ConstructDartObject(kReadResult, ToDart(ZX_ERR_BAD_HANDLE));
514 }
515
516 // TODO: constrain size?
517 ByteDataScope bytes(size);
518 zx_status_t status = zx_vmo_read(vmo->handle(), bytes.data(), offset, size);
519 bytes.Release();
520 if (status == ZX_OK) {
521 return ConstructDartObject(kReadResult, ToDart(status), bytes.dart_handle(),
522 ToDart(size));
523 }
524 return ConstructDartObject(kReadResult, ToDart(status));
525}
526
528 SizedRegion(void* r, size_t s) : region(r), size(s) {}
529 void* region;
530 size_t size;
531};
532
533void System::VmoMapFinalizer(void* isolate_callback_data, void* peer) {
534 SizedRegion* r = reinterpret_cast<SizedRegion*>(peer);
535 zx_vmar_unmap(zx_vmar_root_self(), reinterpret_cast<uintptr_t>(r->region),
536 r->size);
537 delete r;
538}
539
541 if (!vmo || !vmo->is_valid())
542 return ConstructDartObject(kMapResult, ToDart(ZX_ERR_BAD_HANDLE));
543
544 uint64_t size;
545 zx_status_t status = zx_vmo_get_size(vmo->handle(), &size);
546 if (status != ZX_OK)
547 return ConstructDartObject(kMapResult, ToDart(status));
548
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);
552 if (status != ZX_OK)
553 return ConstructDartObject(kMapResult, ToDart(status));
554
555 void* data = reinterpret_cast<void*>(mapped_addr);
556 Dart_Handle object = Dart_NewExternalTypedData(Dart_TypedData_kUint8, data,
557 static_cast<intptr_t>(size));
559
560 SizedRegion* r = new SizedRegion(data, size);
561 Dart_NewFinalizableHandle(object, reinterpret_cast<void*>(r),
562 static_cast<intptr_t>(size) + sizeof(*r),
563 System::VmoMapFinalizer);
564
565 return ConstructDartObject(kMapResult, ToDart(ZX_OK), object);
566}
567
569 return zx_clock_get_monotonic();
570}
571
572// clang-format: off
573
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) \
590 V(System, VmoRead) \
591 V(System, VmoWrite) \
592 V(System, VmoMap) \
593 V(System, ClockGetMonotonic)
594
595// clang-format: on
596
597// Tonic is missing a comma.
598#define DART_REGISTER_NATIVE_STATIC_(CLASS, METHOD) \
599 DART_REGISTER_NATIVE_STATIC(CLASS, METHOD),
600
602
603void System::RegisterNatives(tonic::DartLibraryNatives* natives) {
605}
606
607} // namespace dart
608} // namespace zircon
GLenum type
void reset(const T &value=Traits::InvalidValue())
const T & get() const
Dart_PersistentHandle GetClass(const DartWrapperInfo &info)
static DartState * Current()
Definition dart_state.cc:56
DartClassLibrary & class_library()
Definition dart_state.h:60
static Dart_Handle CreateInvalid()
Definition handle.cc:32
static fml::RefPtr< Handle > Create(zx_handle_t handle)
Definition handle.cc:28
static Dart_Handle ChannelCreate(uint32_t options)
Definition system.cc:198
static Dart_Handle SocketCreate(uint32_t options)
Definition system.cc:396
static Dart_Handle VmoCreate(uint64_t size, uint32_t options)
Definition system.cc:442
static Dart_Handle VmoMap(fml::RefPtr< Handle > vmo)
Definition system.cc:540
static zx_status_t VmoWrite(fml::RefPtr< Handle > vmo, uint64_t offset, const tonic::DartByteData &data)
Definition system.cc:494
static Dart_Handle SocketWrite(fml::RefPtr< Handle > socket, const tonic::DartByteData &data, int options)
Definition system.cc:408
static Dart_Handle VmoRead(fml::RefPtr< Handle > vmo, uint64_t offset, size_t size)
Definition system.cc:509
static uint64_t ClockGetMonotonic()
Definition system.cc:568
static Dart_Handle VmoFromFile(std::string path)
Definition system.cc:453
static zx_status_t ChannelWriteEtc(fml::RefPtr< Handle > channel, const tonic::DartByteData &data, std::vector< HandleDisposition * > handle_dispositions)
Definition system.cc:267
static zx_status_t ConnectToService(std::string path, fml::RefPtr< Handle > channel)
Definition system.cc:210
static Dart_Handle ChannelQueryAndReadEtc(fml::RefPtr< Handle > channel)
Definition system.cc:343
static Dart_Handle EventpairCreate(uint32_t options)
Definition system.cc:384
static Dart_Handle ChannelFromFile(std::string path)
Definition system.cc:216
static zx_status_t ChannelWrite(fml::RefPtr< Handle > channel, const tonic::DartByteData &data, std::vector< Handle * > handles)
Definition system.cc:242
static Dart_Handle VmoGetSize(fml::RefPtr< Handle > vmo)
Definition system.cc:476
static Dart_Handle ChannelQueryAndRead(fml::RefPtr< Handle > channel)
Definition system.cc:303
static zx_status_t VmoSetSize(fml::RefPtr< Handle > vmo, uint64_t size)
Definition system.cc:487
static Dart_Handle SocketRead(fml::RefPtr< Handle > socket, size_t size)
Definition system.cc:423
#define DART_NATIVE_CALLBACK_STATIC(CLASS, METHOD)
#define IMPLEMENT_WRAPPERTYPEINFO(LibraryName, ClassName)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
const gchar * channel
#define FML_DCHECK(condition)
Definition logging.h:122
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
Definition switch_defs.h:52
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)
Definition dart_error.cc:33
#define FOR_EACH_STATIC_BINDING(V)
Definition handle.cc:112
#define DART_REGISTER_NATIVE_STATIC_(CLASS, METHOD)
Definition handle.cc:126
SizedRegion(void *r, size_t s)
Definition system.cc:528
std::shared_ptr< const fml::Mapping > data