Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit e12d15c

Browse files
authored
[fuchsia] [ffi] Basic support for Channels and Handles (#27849)
1 parent ae0401d commit e12d15c

File tree

20 files changed

+994
-5
lines changed

20 files changed

+994
-5
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,6 +1335,8 @@ FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/lib/src/handle_dis
13351335
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/lib/src/handle_waiter.dart
13361336
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/lib/src/init.dart
13371337
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/lib/src/system.dart
1338+
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/lib/src/zd_channel.dart
1339+
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/lib/src/zd_handle.dart
13381340
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/lib/zircon.dart
13391341
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/handle.cc
13401342
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/handle.h
@@ -1346,9 +1348,18 @@ FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/natives.cc
13461348
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/natives.h
13471349
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/system.cc
13481350
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/system.h
1351+
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/basic_types.cc
1352+
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/basic_types.h
1353+
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/channel.cc
1354+
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/channel.h
13491355
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/clock.cc
13501356
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/clock.h
1357+
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/dart_dl.cc
1358+
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/dart_dl.h
1359+
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/handle.cc
1360+
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/handle.h
13511361
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/lib/zircon_ffi.dart
1362+
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/macros.h
13521363
FILE: ../../../flutter/shell/platform/fuchsia/dart/compiler.dart
13531364
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/builtin_libraries.cc
13541365
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/builtin_libraries.h

shell/platform/fuchsia/dart-pkg/zircon/lib/src/init.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ class _Bindings {
2121
final _dylib = DynamicLibrary.open(_kZirconFFILibName);
2222
_bindings = ZirconFFIBindings(_dylib);
2323
}
24+
25+
final initializer = _bindings!.zircon_dart_dl_initialize;
26+
if (initializer(NativeApi.initializeApiDLData) != 1) {
27+
throw UnsupportedError('Unable to initialize dart:zircon_ffi.');
28+
}
29+
2430
return _bindings;
2531
}
2632
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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+
part of zircon;
6+
7+
@pragma('vm:entry-point')
8+
class ZDChannel {
9+
static ZDChannel? create([int options = 0]) {
10+
final Pointer<zircon_dart_handle_pair_t>? channelPtr =
11+
zirconFFIBindings?.zircon_dart_channel_create(options);
12+
if (channelPtr == null || channelPtr.address == 0) {
13+
throw Exception('Unable to create a channel');
14+
}
15+
return ZDChannel._(ZDHandlePair._(channelPtr));
16+
}
17+
18+
static int _write(ZDHandle channel, ByteData data, List<ZDHandle> handles) {
19+
final Pointer<zircon_dart_handle_list_t> handleList =
20+
zirconFFIBindings!.zircon_dart_handle_list_create();
21+
handles.forEach((ZDHandle handle) {
22+
zirconFFIBindings!
23+
.zircon_dart_handle_list_append(handleList, handle._ptr);
24+
});
25+
26+
final Uint8List dataAsBytes = data.buffer.asUint8List();
27+
final Pointer<zircon_dart_byte_array_t> byteArray =
28+
zirconFFIBindings!.zircon_dart_byte_array_create(dataAsBytes.length);
29+
for (int i = 0; i < dataAsBytes.length; i++) {
30+
zirconFFIBindings!.zircon_dart_byte_array_set_value(
31+
byteArray, i, dataAsBytes.elementAt(i));
32+
}
33+
int ret = zirconFFIBindings!
34+
.zircon_dart_channel_write(channel._ptr, byteArray, handleList);
35+
36+
zirconFFIBindings!.zircon_dart_byte_array_free(byteArray);
37+
zirconFFIBindings!.zircon_dart_handle_list_free(handleList);
38+
return ret;
39+
}
40+
41+
int writeLeft(ByteData data, List<ZDHandle> handles) {
42+
return _write(handlePair.left, data, handles);
43+
}
44+
45+
int writeRight(ByteData data, List<ZDHandle> handles) {
46+
return _write(handlePair.right, data, handles);
47+
}
48+
49+
@pragma('vm:entry-point')
50+
ZDChannel._(this.handlePair);
51+
52+
final ZDHandlePair handlePair;
53+
54+
@override
55+
String toString() => 'Channel(handlePair=$handlePair)';
56+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
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+
part of zircon;
6+
7+
@pragma('vm:entry-point')
8+
class ZDHandle {
9+
@pragma('vm:entry-point')
10+
ZDHandle._(this._ptr) {
11+
_attachFinalizer();
12+
}
13+
14+
void _attachFinalizer() {
15+
// TODO (kaushikiska): fix external allocation size.
16+
final int? ret = zirconFFIBindings?.zircon_dart_handle_attach_finalizer(
17+
this, _ptr.cast(), 128);
18+
if (ret != 1) {
19+
throw Exception('Unable to attach finalizer to handle');
20+
}
21+
}
22+
23+
int get handle => _ptr.ref.handle;
24+
25+
final Pointer<zircon_dart_handle_t> _ptr;
26+
27+
bool isValid() {
28+
int? ret = zirconFFIBindings?.zircon_dart_handle_is_valid(_ptr);
29+
return ret == 1;
30+
}
31+
32+
bool close() {
33+
assert(isValid());
34+
if (isValid()) {
35+
int? ret = zirconFFIBindings?.zircon_dart_handle_close(_ptr);
36+
return ret == 1;
37+
}
38+
return false;
39+
}
40+
41+
@override
42+
bool operator ==(Object other) {
43+
return other is ZDHandle && other.handle == handle;
44+
}
45+
46+
@override
47+
int get hashCode => handle.hashCode;
48+
49+
@override
50+
String toString() => 'ZDHandle(handle=$handle)';
51+
}
52+
53+
@pragma('vm:entry-point')
54+
class ZDHandlePair {
55+
@pragma('vm:entry-point')
56+
ZDHandlePair._(this._ptr)
57+
: left = ZDHandle._(_ptr.ref.left),
58+
right = ZDHandle._(_ptr.ref.right) {
59+
_attachFinalizer();
60+
}
61+
62+
void _attachFinalizer() {
63+
// TODO (kaushikiska): fix external allocation size.
64+
final int? ret = zirconFFIBindings
65+
?.zircon_dart_handle_pair_attach_finalizer(this, _ptr.cast(), 128);
66+
if (ret != 1) {
67+
throw Exception('Unable to attach finalizer to handle');
68+
}
69+
}
70+
71+
final Pointer<zircon_dart_handle_pair_t> _ptr;
72+
final ZDHandle left;
73+
final ZDHandle right;
74+
75+
@override
76+
String toString() => 'ZDHandlePair(left=$left, right=$right)';
77+
}

shell/platform/fuchsia/dart-pkg/zircon/lib/zircon.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
library zircon;
66

7+
// uncomment the next line for local testing.
8+
// import 'package:zircon_ffi/zircon_ffi.dart';
9+
710
import 'dart:convert' show utf8;
811
import 'dart:ffi';
912
import 'dart:io';
@@ -16,3 +19,5 @@ part 'src/handle_disposition.dart';
1619
part 'src/handle_waiter.dart';
1720
part 'src/init.dart';
1821
part 'src/system.dart';
22+
part 'src/zd_channel.dart';
23+
part 'src/zd_handle.dart';

shell/platform/fuchsia/dart-pkg/zircon/pubspec.yaml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,19 @@
22
# Use of this source code is governed by a BSD-style license that can be
33
# found in the LICENSE file.
44

5+
name: zircon
6+
57
environment:
6-
sdk: '>=2.11.0 <3.0.0'
8+
sdk: '>=2.12.0 <3.0.0'
9+
10+
11+
# Uncomment block for local testing
12+
13+
# dependencies:
14+
# zircon_ffi:
15+
# path: ../zircon_ffi
16+
17+
# dev_dependencies:
18+
# test: ^1.17.10
19+
20+
# block end

shell/platform/fuchsia/dart-pkg/zircon/test/channel_test.dart

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ void main() {
2323
expect(pair.second.isValid, isTrue);
2424
});
2525

26+
test('[ffi] create channel', () {
27+
final ZDChannel? channel = ZDChannel.create();
28+
expect(channel, isNotNull);
29+
final ZDHandlePair pair = channel!.handlePair;
30+
expect(pair.left.isValid(), isTrue);
31+
expect(pair.right.isValid(), isTrue);
32+
});
33+
2634
test('close channel', () {
2735
final HandlePairResult pair = System.channelCreate();
2836
expect(pair.first.close(), equals(0));
@@ -34,6 +42,18 @@ void main() {
3442
equals(ZX.ERR_PEER_CLOSED));
3543
});
3644

45+
test('[ffi] close channel', () {
46+
final ZDChannel? channel = ZDChannel.create();
47+
final ZDHandlePair pair = channel!.handlePair;
48+
expect(pair.left.close(), isTrue);
49+
expect(pair.left.isValid, isFalse);
50+
expect(pair.right.isValid, isTrue);
51+
expect(channel.writeLeft(ByteData(1), <ZDHandle>[]),
52+
equals(ZX.ERR_BAD_HANDLE));
53+
expect(channel.writeRight(ByteData(1), <ZDHandle>[]),
54+
equals(ZX.ERR_PEER_CLOSED));
55+
});
56+
3757
test('channel bytes', () {
3858
final HandlePairResult pair = System.channelCreate();
3959

shell/platform/fuchsia/dart-pkg/zircon_ffi/BUILD.gn

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,22 @@ shared_library("zircon_ffi") {
1313
public_configs = [ ":zircon_ffi_config" ]
1414

1515
sources = [
16+
"basic_types.cc",
17+
"basic_types.h",
18+
"channel.cc",
19+
"channel.h",
1620
"clock.cc",
1721
"clock.h",
22+
"dart_dl.cc",
23+
"dart_dl.h",
24+
"handle.cc",
25+
"handle.h",
26+
"macros.h",
1827
]
1928

2029
deps = [
2130
"$fuchsia_sdk_root/pkg:zx",
31+
"//flutter/fml",
2232
"//third_party/dart/runtime:dart_api",
2333
]
2434
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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 "basic_types.h"
6+
7+
#include <cstdint>
8+
#include <cstdlib>
9+
10+
#include "flutter/fml/logging.h"
11+
12+
zircon_dart_byte_array_t* zircon_dart_byte_array_create(uint32_t size) {
13+
zircon_dart_byte_array_t* arr = static_cast<zircon_dart_byte_array_t*>(
14+
malloc(sizeof(zircon_dart_byte_array_t)));
15+
arr->length = size;
16+
arr->data = static_cast<uint8_t*>(malloc(size * sizeof(uint8_t)));
17+
return arr;
18+
}
19+
20+
void zircon_dart_byte_array_set_value(zircon_dart_byte_array_t* arr,
21+
uint32_t index,
22+
uint8_t value) {
23+
FML_CHECK(arr);
24+
FML_CHECK(arr->length > index);
25+
arr->data[index] = value;
26+
}
27+
28+
void zircon_dart_byte_array_free(zircon_dart_byte_array_t* arr) {
29+
FML_CHECK(arr);
30+
free(arr->data);
31+
free(arr);
32+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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+
#ifndef FLUTTER_SHELL_PLATFORM_FUCHSIA_DART_PKG_ZIRCON_FFI_BASIC_TYPES_H_
6+
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_DART_PKG_ZIRCON_FFI_BASIC_TYPES_H_
7+
8+
#include "macros.h"
9+
10+
#include <stdint.h>
11+
12+
#ifdef __cplusplus
13+
extern "C" {
14+
#endif
15+
16+
typedef struct zircon_dart_byte_array_t {
17+
uint8_t* data;
18+
uint32_t length;
19+
} zircon_dart_byte_array_t;
20+
21+
ZIRCON_FFI_EXPORT zircon_dart_byte_array_t* zircon_dart_byte_array_create(
22+
uint32_t size);
23+
24+
ZIRCON_FFI_EXPORT void zircon_dart_byte_array_set_value(
25+
zircon_dart_byte_array_t* arr,
26+
uint32_t index,
27+
uint8_t value);
28+
29+
ZIRCON_FFI_EXPORT void zircon_dart_byte_array_free(
30+
zircon_dart_byte_array_t* arr);
31+
32+
#ifdef __cplusplus
33+
} // extern "C"
34+
#endif
35+
36+
#endif // FLUTTER_SHELL_PLATFORM_FUCHSIA_DART_PKG_ZIRCON_FFI_BASIC_TYPES_H_

0 commit comments

Comments
 (0)