fyne-io / fyne

Cross platform GUI toolkit in Go inspired by Material Design
https://fyne.io/
Other
25.2k stars 1.4k forks source link

Access to (FTDI) USB serial device (on Android) #3256

Open ThomasKurz opened 2 years ago

ThomasKurz commented 2 years ago

Checklist

Is your feature request related to a problem?

We have developed a Fyne based UI for a sensor hardware which consists of a microcontroller and a FTDI based USB-Serial interface (a lot like many Arduinos have).

This was easy to implement for Linux and Windows with ziutek's libftdi/libusb1 package.

But now we struggle with the Android platform port: We have not yet succeeded in getting ziutek/ftdi compile and link correctly into Fyne projects. Probably the best way would be to let CGO compile the libftdi + libusb1 sources as karalabe does, but this seems quite complicated and a lot of effort. It seemed to be a lot more straightforward to use mik3y's usb-serial-for-android Java lib for the Android platform, but according to https://stackoverflow.com/questions/65278073/reverse-java-bindings-with-gomobile-and-fyne-io it is not possible to add and use Java APIs with Fyne.

Especially for the zillions of Arduino fans out there it should be interesting to have a working solution to access their devices from Fyne apps in a platform independent way.

How could we solve this best? Is there any interest for a more general approach?

Is it possible to construct a solution with the existing API?

The only current solution we know of is to implement USB device access in a separate app using the mentioned Java lib and make our Fyne app communicate with it.

Describe the solution you'd like to see.

Best would be a platform independent interface for accessing (USB) serial devices, including RTS/CTS/DTD/DTR handling, baudrate and parity configuration ... which abstracts on platform specific implementations using whatever libs there are available.

While this can certainly only be a future goal, any kind of workaround/hint/proposal/idea of how to solve our actual problem is appreciated.

One could think of either a FTDI specific approach or a more general approch to access also usb serial devices of other vendors.

andydotxyz commented 2 years ago

It is easier to use C libs through CGo compared to Java libraries because of 1) how they get bundled and 2) We don't expose the JVM context (yet). We are exploring how to get access to the JVM and android context, but in the meantime CGo is the way to go.

pjanx commented 2 months ago

I also have interest in USB OTG, for non-serial devices (a $4 infrared remote control dongle). Getting the generic libusb to work would probably be best, however the instructions seem to require getting privileges and opening the device from within Java code.

andydotxyz commented 2 months ago

You can execute Java instructions from C using JNI - this may be the way forward. There are examples in the Fyne codebase or at https://fynelabs.com/2024/03/01/running-native-android-code-in-a-fyne-app/

pjanx commented 2 months ago

Apparently, you need to create a Java subclass of the abstract BroadcastReceiver. Pure JNI offers:

And then you need to make that pre-compiled Java class call back into your native code—RegisterNatives (one example, another example) might just work with some static methods.

I would be thankful for a full working minimal example. System broadcasts appear to be widely useful.

Embedding notes

#!/bin/sh -e
javac NativeReceiver.java
dx --dex --output=NativeReceiver.dex NativeReceiver.class
import "embed"

//go:generate ./gen-native-receiver.sh

//go:embed NativeReceiver.dex
var dexNativeReceiver string

DEX looks like it might be committable.

andydotxyz commented 2 months ago

The only example of pure Java being compiled into Fyne would be the bootstrap code which is .dex bundled for the package command - the generator is at https://github.com/fyne-io/fyne/blob/master/cmd/fyne/internal/mobile/gendex/gendex.go