[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