Skip to content
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
141 changes: 15 additions & 126 deletions .github/workflows/dart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Setup flutter SDK
uses: subosito/flutter-action@v2
Expand All @@ -26,140 +26,29 @@ jobs:

- run: flutter precache

- name: melos bootstrap
run: dart pub global run melos bootstrap
- run: melos bootstrap

- name: melos checkformat
run: dart pub global run melos run checkformat
- run: melos run checkformat

- name: melos analyze
run: dart pub global run melos run analyze
- run: melos run analyze

- name: melos test
run: dart pub global run melos test
- run: melos run test

create-panda-temp-key:
name: Create temporary SSH key
runs-on: panda
concurrency: panda-temp-key
steps:
- uses: actions/checkout@v3

- name: Generate keypair
run: |
ssh-keygen -b 4096 -t rsa -f ./sshkey -q -N ""

- name: Add public key to authorized_keys
run: |
echo expiry-time='"'$(date --date=+1hour +%Y%m%d%H%M)'"' $(cat ./sshkey.pub) > ~/.ssh/authorized_keys

- name: Encrypt private key for uploading
env:
AES_KEY: ${{ secrets.AES_KEY }}
run: |
gpg \
--batch --yes \
--symmetric --cipher-algo AES256 \
--passphrase="$AES_KEY" \
--output ./sshkey.gpg \
sshkey
can-test:
runs-on: doublecan

- name: Upload keypair
uses: actions/upload-artifact@v3
with:
name: keypair
path: |
sshkey.gpg
sshkey.pub

integration-test:
runs-on: ubuntu-latest
needs: create-panda-temp-key
concurrency: panda-temp-key
steps:
- uses: actions/checkout@v3

- name: Download keypair
uses: actions/download-artifact@v3
with:
name: keypair
path: .

- name: Decrypt private key
env:
AES_KEY: ${{ secrets.AES_KEY }}
run: |
gpg \
--batch --yes \
--decrypt \
--passphrase="$AES_KEY" \
--output ./sshkey \
./sshkey.gpg
chmod 0600 ./sshkey

- name: Setup adb forward
run: |
mkdir -p ~/.ssh
echo "[md.ardera.dev]:23 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBC41DBiTm+uvaeZqUp4LcUck99c7+vIv/nS4rH4rt/rmSs5KAlJrz7TwicgDYobAdDL8Nnfyz0F2CG88uCNRea0=" >> ~/.ssh/known_hosts
ssh -vvv -N -n -o ExitOnForwardFailure=yes -o BatchMode=yes -L 127.0.0.1:5555:odroid-c4:5555 -p 23 -i ./sshkey ci@md.ardera.dev &
sleep 5
- uses: actions/checkout@v4

- name: Setup Android SDK
uses: android-actions/setup-android@v2
- name: Setup Dart SDK
uses: dart-lang/setup-dart@v1

- name: List adb devices
run: |
adb devices -l
adb connect 127.0.0.1:5555
adb devices -l

- name: Setup flutter SDK
uses: subosito/flutter-action@v2
with:
cache: true

- name: Setup melos
run: dart pub global activate melos

- run: flutter doctor -v

- run: flutter precache

- name: melos bootstrap
run: dart pub global run melos bootstrap

- name: make ODROID C4 gpio chips accessible
run: |
adb -t 2 shell chmod 0777 /dev/gpiochip0
adb -t 2 shell chmod 0777 /dev/gpiochip1

- name: run flutter_gpiod_test_app on ODROID C4
working-directory: packages/flutter_gpiod_test_app
run: flutter test -d "127.0.0.1:5555" -t odroidc4 integration_test/gpio_test.dart

delete-panda-temp-key:
name: Delete temporary SSH key
runs-on: panda
needs: integration-test
concurrency: panda-temp-key

# run even if integration-test failed
if: ${{ always() }}
steps:
- uses: actions/checkout@v3
- run: melos bootstrap --no-flutter

- name: Download keypair
uses: actions/download-artifact@v3
with:
name: keypair
path: .

- name: Remove key from authorized_keys file
run: |
echo "::group::List authorized keys"
echo "::debug::$(cat ~/.ssh/authorized_keys)"
echo "::endgroup::"
grep -v "$(cat sshkey.pub)" ~/.ssh/authorized_keys | sponge ~/.ssh/authorized_keys
echo "::group::List authorized keys"
echo "::debug::$(cat ~/.ssh/authorized_keys)"
echo "::endgroup::"
- name: Test linux_can
working-directory: packages/linux_can
run:
dart test integration_test --tags "double-can"
76 changes: 42 additions & 34 deletions packages/_ardera_common_libc_bindings/lib/src/epoll_listener.dart
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ class EpollIsolate {

static const _maxEvents = 128;
final _events = ffi.calloc<epoll_event>(_maxEvents);
final _eventFdBuffer = ffi.calloc<ffi.Uint8>(8);

var _shouldRun = true;
var _nextCapabilityMapIndex = 1;
Expand Down Expand Up @@ -456,6 +457,7 @@ class EpollIsolate {
void dispose() {
_subscription.cancel();
ffi.calloc.free(_events);
ffi.calloc.free(_eventFdBuffer);
}

int _retry(int Function() syscall, {Set<int> retryErrorCodes = const {EINTR}}) {
Expand Down Expand Up @@ -505,44 +507,50 @@ class EpollIsolate {
));
if (ok < 0) {
throw LinuxError('Could not wait for epoll events.', 'epoll_wait', libc.errno);
} else if (ok == 0) {
continue;
}

if (ok > 0) {
// process any epoll events
for (var i = 0; i < ok; i++) {
final event = _events + i;
// process any epoll events
for (var i = 0; i < ok; i++) {
final event = _events + i;

final capability = _capabilityMap[event.ref.data.u64]!;
final capability = _capabilityMap[event.ref.data.u64]!;

final flags = <EpollFlag>{};
for (final flag in EpollFlag.values) {
if (event.ref.events & flag._value != 0) {
flags.add(flag);
}
final flags = <EpollFlag>{};
for (final flag in EpollFlag.values) {
if (event.ref.events & flag._value != 0) {
flags.add(flag);
}
}

if (capability == _eventFdCap) {
// do nothing
} else {
assert(capability is Capability);

// Find and invoke the handler.
final handler = _handlerMap[capability]!;

try {
final value = handler.callback(this, handler.fd, flags, handler.callbackContext);

_sendEvent(
handlerId: handler.id,
event: value,
);
} on Exception catch (err, st) {
_sendError(
handlerId: handler.id,
error: err,
stackTrace: st,
);
}
if (capability == _eventFdCap) {
// clear the eventfd buffer.
final result = _retry(() => libc.read(_eventFd, _eventFdBuffer.cast<ffi.Void>(), 8));
if (result < 0) {
throw LinuxError('Could not clear event fd.', 'read', libc.errno);
} else if (result == 0) {
throw LinuxError('Event fd got EOF.', 'read');
}
} else {
assert(capability is Capability);

// Find and invoke the handler.
final handler = _handlerMap[capability]!;

try {
final value = handler.callback(this, handler.fd, flags, handler.callbackContext);

_sendEvent(
handlerId: handler.id,
event: value,
);
} on Exception catch (err, st) {
_sendError(
handlerId: handler.id,
error: err,
stackTrace: st,
);
}
}
}
Expand Down Expand Up @@ -709,7 +717,7 @@ class EpollEventLoop {

throw RemoteError(_isolateError!, _isolateErrorStackTrace!);
} else {
assert(false);
throw StateError('Got unexpected message from isolate: $msg');
}
}

Expand Down Expand Up @@ -818,7 +826,7 @@ class EpollEventLoop {
ValueCallback? callback,
}) async {
assert(_alive);
assert(_handlers.containsKey(listener));
assert(_handlers.containsKey(listener._id));

final seq = Capability();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ typedef SymbolLookupFn = ffi.Pointer<T> Function<T extends ffi.NativeType>(Strin
class LibCArm extends LibC {
final backend.LibCArm _backend;

LibCArm.fromLookup(SymbolLookupFn _lookup)
LibCArm.fromLookup(super._lookup)
: _backend = backend.LibCArm.fromLookup(_lookup),
super._fromLookup(_lookup);
super._fromLookup();

@override
int bind(int __fd, ffi.Pointer<sockaddr> __addr, int __len) {
Expand Down Expand Up @@ -222,9 +222,9 @@ class LibCArm extends LibC {
class LibCArm64 extends LibC {
final backend.LibCArm64 _backend;

LibCArm64.fromLookup(SymbolLookupFn _lookup)
LibCArm64.fromLookup(super._lookup)
: _backend = backend.LibCArm64.fromLookup(_lookup),
super._fromLookup(_lookup);
super._fromLookup();

@override
int bind(int __fd, ffi.Pointer<sockaddr> __addr, int __len) {
Expand Down Expand Up @@ -425,9 +425,9 @@ class LibCArm64 extends LibC {
class LibCI386 extends LibC {
final backend.LibCI386 _backend;

LibCI386.fromLookup(SymbolLookupFn _lookup)
LibCI386.fromLookup(super._lookup)
: _backend = backend.LibCI386.fromLookup(_lookup),
super._fromLookup(_lookup);
super._fromLookup();

@override
int bind(int __fd, ffi.Pointer<sockaddr> __addr, int __len) {
Expand Down Expand Up @@ -628,9 +628,9 @@ class LibCI386 extends LibC {
class LibCAmd64 extends LibC {
final backend.LibCAmd64 _backend;

LibCAmd64.fromLookup(SymbolLookupFn _lookup)
LibCAmd64.fromLookup(super._lookup)
: _backend = backend.LibCAmd64.fromLookup(_lookup),
super._fromLookup(_lookup);
super._fromLookup();

@override
int bind(int __fd, ffi.Pointer<sockaddr> __addr, int __len) {
Expand Down
11 changes: 6 additions & 5 deletions packages/flutterpi_gstreamer_video_player/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,24 @@ class _ExampleVideoPageState extends State<ExampleVideoPage> {
autoInitialize: true,
autoPlay: true,
looping: true,
additionalOptions: (context) {
additionalOptions: (_) {
return [
OptionItem(
onTap: () {
onTap: (_) {
_controller.stepForward();
},
iconData: Icons.arrow_right,
title: 'Step Forward',
),
OptionItem(
onTap: () {
onTap: (_) {
_controller.stepBackward();
},
iconData: Icons.arrow_left,
title: 'Step Backward',
),
OptionItem(
onTap: () {},
onTap: (_) {},
iconData: Icons.fast_forward_outlined,
title: 'Fast Seek',
),
Expand Down Expand Up @@ -120,7 +120,8 @@ class _CameraViewPageState extends State<CameraViewPage> {
}

class _VideoApp extends StatefulWidget {
const _VideoApp({Key? key}) : super(key: key);
// ignore: unused_element_parameter
const _VideoApp({super.key}) : super();

@override
_VideoAppState createState() => _VideoAppState();
Expand Down
Loading