[Unison-hackers] Interface for an external GUI
Michael von Glasow
michael at vonglasow.com
Thu Feb 9 14:26:31 EST 2023
On 08/02/2023 21:34, Tõivo Leedjärv wrote:
> On Tue, 7 Feb 2023 at 20:28, Michael von Glasow <michael at vonglasow.com> wrote:
>> Actually I was thinking of something far less complex:
>>
>> – basically, a plumbing-style CLI, but that isn’t exactly elegant. It would have been a quick win, had Unison already provided the necessary functionality – but if I need to modify Unison anyway, it’s not worth the effort.
> Right, this is not worth the effort. The problem with this approach is
> not the interface. This approach requires runtime state to be always
> persisted, and that's a big change. Plus, I'd imagine this would
> became rather inefficient with larger roots/number of updates.
The CLI would need to output its entire run-time state and the caller
would need to keep track of it. The diff report would need to include
hashes with every file, and the sync operation would need to be passed
these hashes so it can skip synchronization of any file whose hash has
changed.
>> Better turn it into a library with a somewhat well-defined API that a frontend can call.
>> I haven’t dug deeply yet into the Objective-C to OCaml bindings, but I see the Mac GUI does a few things involving thread creation and the like, which I interpret to mean that it’s not as simple as a few function/method calls. But with the assumption of the clean universal API, this would be my preferred architecture.
> There is some non-trivial amount of housekeeping and boilerplate to be
> done, for sure.
>
> I personally would advise not to go this object-linkable library
> route. Not because it wouldn't work, but because it is a more
> inflexible and tightly coupled way with no immediately obvious
> benefits. Does it make the backend or the UI implementation simpler?
> No. Does it offer better performance or resource usage? Maybe a
> little. Does Android make it hard/impossible to have multiple
> processes or a meaningful IPC? In that case, yes, this option is
> better.
> I would prefer the IPC option because it's just more flexible in every
> way. It can be used by not only UIs but also other "clients" and
> frontends. You could use the same UI with different versions of Unison
> (and even upgrade them separately, if needed) and even with multiple
> Unisons at the same time. Depending on the design, it could be
> possible to connect/disconnect to a running process as needed. The
> language of UI/"client"/frontend would be completely independent of
> the backend's. No worrying about FFI, bindings and C wrappers and so
> on. And finally, if really desired, the linkable library interface can
> be built on top of this solution afterwards.
Multiple processes inside an app are possible on Android. As for IPC,
Android comes with its own framework for exchanging data between
processes/apps and expects apps to use that.
Although Android runs on a (somewhat modified) Linux kernel, there’s a
bunch of differences and restrictions not normally found on a Linux
system. What works on Linux may not necessarily work on Android, or may
stop working a few versions in the future – over the last five versions,
Android has gathered quite a track record of cutting off certain
functionalities, especially undocumented ones. Even full filesystem
access is by now getting restricted; apps requiring this need to obtain
storage manager permissions but Google will not allow such apps into the
Play store unless they can provide a valid use case. (Syncthing requests
this permissions and is available on the Play Store, thus Unison would
have a good chance of being allowed as well.)
Unix domain sockets are available, but their use has been restricted
since Android 9. They can still be used within an app, but not across
apps. The other option, of course, is command line arguments and
stdin/stdout. (Being able to spawn a native executable presumably is a
requirement for SSH synchronization anyway.)
What is also officially supported on Android is building a dynamic
library (.so) and calling that from the Android app via JNI. (Calling
Java code from the library is also supported, but that might introduce
dependencies in the opposite direction.) Admittedly, that is the
approach I am familiar and comfortable with, unlike the rest. It should
also be a fairly quick win.
Bottom line: if we build something that works now but uses some
undocumented features, or Linux features not officially documented on
Android, or anything native to Linux when Android provides its own
alternative, there’s a risk that future Android versions will break it
and we’ll have to redesign things. I’d personally avoid making overly
aggressive use of features that just happen to work in Android rather
than being officially supported.
For the library approach, I would suggest building Unison’s core, plus
what we need from the Mac GUI (probably Bridge plus some extra), into a
libunison.so library. The library would need to have a well-defined API
with stable function names and signatures – Bridge.h should have most of
this already. Android would then call this library, and the Mac GUI
could be reworked to rely on it as well. It should be portable to any
platform which supports dynamic linking to native libraries, and to
which we can port the library. A frontend/backend architecture like the
one you mention could also be built top of said library.
Regarding duplicate code in the Mac GUI: after a brief glimpse,
duplicates I found seem to be related to profile files and the options
used in them. But I may well have missed something – further input is
welcome.
> Just to be clear, I don't mean that you would have to do any of this.
> I am myself interested in this concept as a universal solution and am
> willing to implement the backend bits if/when there is a design
> created and agreed upon (which I'm also willing to help with).
Great to hear I’m getting support :-) I have some experience with
Android development, but never touched OCaml code so far.
Let’s put it this way: if someone makes the necessary changes to Unison
in a way that is compatible with Android, I’ll be happy to built an
Android GUI on top of that. I’ll happily contribute to the design, with
the caveat that I have limited knowledge about the inner workings of
Unison. Main challenge for me right now is to get Unison in any form to
build for an Android target.
More information about the Unison-hackers
mailing list