Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1335,6 +1335,8 @@ FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/lib/src/handle_dis
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/lib/src/handle_waiter.dart
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/lib/src/init.dart
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/lib/src/system.dart
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/lib/src/zd_channel.dart
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/lib/src/zd_handle.dart
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/lib/zircon.dart
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/handle.cc
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/handle.h
Expand All @@ -1346,9 +1348,18 @@ FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/natives.cc
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/natives.h
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/system.cc
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/system.h
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/basic_types.cc
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/basic_types.h
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/channel.cc
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/channel.h
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/clock.cc
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/clock.h
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/dart_dl.cc
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/dart_dl.h
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/handle.cc
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/handle.h
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/lib/zircon_ffi.dart
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon_ffi/macros.h
FILE: ../../../flutter/shell/platform/fuchsia/dart/compiler.dart
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/builtin_libraries.cc
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/builtin_libraries.h
Expand Down
6 changes: 6 additions & 0 deletions shell/platform/fuchsia/dart-pkg/zircon/lib/src/init.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ class _Bindings {
final _dylib = DynamicLibrary.open(_kZirconFFILibName);
_bindings = ZirconFFIBindings(_dylib);
}

final initializer = _bindings!.zircon_dart_dl_initialize;
if (initializer(NativeApi.initializeApiDLData) != 1) {
throw UnsupportedError('Unable to initialize dart:zircon_ffi.');
}

return _bindings;
}
}
Expand Down
56 changes: 56 additions & 0 deletions shell/platform/fuchsia/dart-pkg/zircon/lib/src/zd_channel.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

part of zircon;

@pragma('vm:entry-point')
class ZDChannel {
static ZDChannel? create([int options = 0]) {
final Pointer<zircon_dart_handle_pair_t>? channelPtr =
zirconFFIBindings?.zircon_dart_channel_create(options);
if (channelPtr == null || channelPtr.address == 0) {
throw Exception('Unable to create a channel');
}
return ZDChannel._(ZDHandlePair._(channelPtr));
}

static int _write(ZDHandle channel, ByteData data, List<ZDHandle> handles) {
final Pointer<zircon_dart_handle_list_t> handleList =
zirconFFIBindings!.zircon_dart_handle_list_create();
handles.forEach((ZDHandle handle) {
zirconFFIBindings!
.zircon_dart_handle_list_append(handleList, handle._ptr);
});

final Uint8List dataAsBytes = data.buffer.asUint8List();
final Pointer<zircon_dart_byte_array_t> byteArray =
zirconFFIBindings!.zircon_dart_byte_array_create(dataAsBytes.length);
for (int i = 0; i < dataAsBytes.length; i++) {
zirconFFIBindings!.zircon_dart_byte_array_set_value(
byteArray, i, dataAsBytes.elementAt(i));
}
int ret = zirconFFIBindings!
.zircon_dart_channel_write(channel._ptr, byteArray, handleList);

zirconFFIBindings!.zircon_dart_byte_array_free(byteArray);
zirconFFIBindings!.zircon_dart_handle_list_free(handleList);
return ret;
}

int writeLeft(ByteData data, List<ZDHandle> handles) {
return _write(handlePair.left, data, handles);
}

int writeRight(ByteData data, List<ZDHandle> handles) {
return _write(handlePair.right, data, handles);
}

@pragma('vm:entry-point')
ZDChannel._(this.handlePair);

final ZDHandlePair handlePair;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why keep both ends of the channel-pair inside of one object? Conceptually, a channel represents only one half of the pair, and very often dart code will only possess one half with no ability to refer to the other half

The old implementation has a shim object called "ChannelPair" to handle this


@override
String toString() => 'Channel(handlePair=$handlePair)';
}
77 changes: 77 additions & 0 deletions shell/platform/fuchsia/dart-pkg/zircon/lib/src/zd_handle.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

part of zircon;

@pragma('vm:entry-point')
class ZDHandle {
@pragma('vm:entry-point')
ZDHandle._(this._ptr) {
_attachFinalizer();
}

void _attachFinalizer() {
// TODO (kaushikiska): fix external allocation size.
final int? ret = zirconFFIBindings?.zircon_dart_handle_attach_finalizer(
this, _ptr.cast(), 128);
if (ret != 1) {
throw Exception('Unable to attach finalizer to handle');
}
}

int get handle => _ptr.ref.handle;

final Pointer<zircon_dart_handle_t> _ptr;

bool isValid() {
int? ret = zirconFFIBindings?.zircon_dart_handle_is_valid(_ptr);
return ret == 1;
}

bool close() {
assert(isValid());
if (isValid()) {
int? ret = zirconFFIBindings?.zircon_dart_handle_close(_ptr);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's assert(isValid()) here, then do the if check. 99% of the time, isValid() being false here indicates a coding error in the dart application

This is the behavior that the existing implementation has (DCHECK on handle validity, then proceed forward with an if)

return ret == 1;
}
return false;
}

@override
bool operator ==(Object other) {
return other is ZDHandle && other.handle == handle;
}

@override
int get hashCode => handle.hashCode;

@override
String toString() => 'ZDHandle(handle=$handle)';
}

@pragma('vm:entry-point')
class ZDHandlePair {
@pragma('vm:entry-point')
ZDHandlePair._(this._ptr)
: left = ZDHandle._(_ptr.ref.left),
right = ZDHandle._(_ptr.ref.right) {
_attachFinalizer();
}

void _attachFinalizer() {
// TODO (kaushikiska): fix external allocation size.
final int? ret = zirconFFIBindings
?.zircon_dart_handle_pair_attach_finalizer(this, _ptr.cast(), 128);
if (ret != 1) {
throw Exception('Unable to attach finalizer to handle');
}
}

final Pointer<zircon_dart_handle_pair_t> _ptr;
final ZDHandle left;
final ZDHandle right;

@override
String toString() => 'ZDHandlePair(left=$left, right=$right)';
}
5 changes: 5 additions & 0 deletions shell/platform/fuchsia/dart-pkg/zircon/lib/zircon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

library zircon;

// uncomment the next line for local testing.
// import 'package:zircon_ffi/zircon_ffi.dart';

import 'dart:convert' show utf8;
import 'dart:ffi';
import 'dart:io';
Expand All @@ -16,3 +19,5 @@ part 'src/handle_disposition.dart';
part 'src/handle_waiter.dart';
part 'src/init.dart';
part 'src/system.dart';
part 'src/zd_channel.dart';
part 'src/zd_handle.dart';
16 changes: 15 additions & 1 deletion shell/platform/fuchsia/dart-pkg/zircon/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,19 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

name: zircon

environment:
sdk: '>=2.11.0 <3.0.0'
sdk: '>=2.12.0 <3.0.0'


# Uncomment block for local testing

# dependencies:
# zircon_ffi:
# path: ../zircon_ffi

# dev_dependencies:
# test: ^1.17.10

# block end
20 changes: 20 additions & 0 deletions shell/platform/fuchsia/dart-pkg/zircon/test/channel_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ void main() {
expect(pair.second.isValid, isTrue);
});

test('[ffi] create channel', () {
final ZDChannel? channel = ZDChannel.create();
expect(channel, isNotNull);
final ZDHandlePair pair = channel!.handlePair;
expect(pair.left.isValid(), isTrue);
expect(pair.right.isValid(), isTrue);
});

test('close channel', () {
final HandlePairResult pair = System.channelCreate();
expect(pair.first.close(), equals(0));
Expand All @@ -34,6 +42,18 @@ void main() {
equals(ZX.ERR_PEER_CLOSED));
});

test('[ffi] close channel', () {
final ZDChannel? channel = ZDChannel.create();
final ZDHandlePair pair = channel!.handlePair;
expect(pair.left.close(), isTrue);
expect(pair.left.isValid, isFalse);
expect(pair.right.isValid, isTrue);
expect(channel.writeLeft(ByteData(1), <ZDHandle>[]),
equals(ZX.ERR_BAD_HANDLE));
expect(channel.writeRight(ByteData(1), <ZDHandle>[]),
equals(ZX.ERR_PEER_CLOSED));
});

test('channel bytes', () {
final HandlePairResult pair = System.channelCreate();

Expand Down
10 changes: 10 additions & 0 deletions shell/platform/fuchsia/dart-pkg/zircon_ffi/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,22 @@ shared_library("zircon_ffi") {
public_configs = [ ":zircon_ffi_config" ]

sources = [
"basic_types.cc",
"basic_types.h",
"channel.cc",
"channel.h",
"clock.cc",
"clock.h",
"dart_dl.cc",
"dart_dl.h",
"handle.cc",
"handle.h",
"macros.h",
]

deps = [
"$fuchsia_sdk_root/pkg:zx",
"//flutter/fml",
"//third_party/dart/runtime:dart_api",
]
}
Expand Down
32 changes: 32 additions & 0 deletions shell/platform/fuchsia/dart-pkg/zircon_ffi/basic_types.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "basic_types.h"

#include <cstdint>
#include <cstdlib>

#include "flutter/fml/logging.h"

zircon_dart_byte_array_t* zircon_dart_byte_array_create(uint32_t size) {
zircon_dart_byte_array_t* arr = static_cast<zircon_dart_byte_array_t*>(
malloc(sizeof(zircon_dart_byte_array_t)));
arr->length = size;
arr->data = static_cast<uint8_t*>(malloc(size * sizeof(uint8_t)));
return arr;
}

void zircon_dart_byte_array_set_value(zircon_dart_byte_array_t* arr,
uint32_t index,
uint8_t value) {
FML_CHECK(arr);
FML_CHECK(arr->length > index);
arr->data[index] = value;
}

void zircon_dart_byte_array_free(zircon_dart_byte_array_t* arr) {
FML_CHECK(arr);
free(arr->data);
free(arr);
}
36 changes: 36 additions & 0 deletions shell/platform/fuchsia/dart-pkg/zircon_ffi/basic_types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_SHELL_PLATFORM_FUCHSIA_DART_PKG_ZIRCON_FFI_BASIC_TYPES_H_
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_DART_PKG_ZIRCON_FFI_BASIC_TYPES_H_

#include "macros.h"

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct zircon_dart_byte_array_t {
uint8_t* data;
uint32_t length;
} zircon_dart_byte_array_t;

ZIRCON_FFI_EXPORT zircon_dart_byte_array_t* zircon_dart_byte_array_create(
uint32_t size);

ZIRCON_FFI_EXPORT void zircon_dart_byte_array_set_value(
zircon_dart_byte_array_t* arr,
uint32_t index,
uint8_t value);

ZIRCON_FFI_EXPORT void zircon_dart_byte_array_free(
zircon_dart_byte_array_t* arr);

#ifdef __cplusplus
} // extern "C"
#endif

#endif // FLUTTER_SHELL_PLATFORM_FUCHSIA_DART_PKG_ZIRCON_FFI_BASIC_TYPES_H_
Loading