How does a Kotlin program on Android (sing-box) interact with Golang code?

Hi all.
Please help me understand one point in the interaction of a program written in Kotlin with a program written in Golang.
I can’t understand how they interact.

There is a program called sing-box (The universal proxy platform), written in Golang - GitHub - SagerNet/sing-box: The universal proxy platform.
This program implements a client and server to create VPN tunnels on very different protocols. The entire list of supported protocols is listed here - Introduction - sing-box, it is very large.

There is a graphical client for Android, written in Kotlin - GitHub - SagerNet/sing-box-for-android: Experimental Android client for sing-box.
Aka - sing-box | F-Droid - Free and Open Source Android App Repository
It works like this: a VPN connection profile is created and a text config is inserted into it, which describes what we will connect through and where. Or this config is loaded by url. Those. in the graphical client there are no windows where I choose what I will connect through. I just have to specify the config by url myself or copy-paste the config code.

I looked through a lot of Kotlin source files for the program and never found any code sections where interaction with sing-box (The universal proxy platform) in Golang is implemented.
The whole point is that 99% of the functionality is in golang code, and in kotlin there is only a minimal interface.

Please help me find the code in the Android client where exactly the interaction with sing-box in golang occurs.
Many thanks to everyone who responds.

I think, if I understand your question correctly, you want to know where the Kotlin code calls the Golang code, right?

Well I haven’t dug deep into this code base, but I would be reasonably confident in stating that the Kotlin code never calls the Golang code. I suspect it interacts with it via HTTP calls.

For example, if you look at TypedProfile, you can see it has a remoteURL property. You can then see that property being used in Shares.

HTTP interfaces between a client and server are pretty standard, and mean that you can have the client and server written in completely different languages. :slight_smile:

1 Like

Thank you for your response.

If you install the sing-box android client, you will notice that it has the ability to specify a link to a remote config and this config can be updated.
Those. config can be added to the program in the following ways:

  1. Import from file
  2. Scan QR code
  3. Create manually
    3.1) Type: Remote
    3.2) Type: Local

If the config type is “Remote”, then an http link to this config is indicated and it can be updated at a specified interval.
This is what remoteURL is.

Those. The program does not even have the ability to graphically manage the config, only importing a text config manually or via a link.

Looking at the repo of the Android code on GitHub, there are imports of classes from the package io.nekohasekai.libbox. That package doesn’t match any Maven dependency in build.gradle.

What we find in build.gradle instead, is a dependency inclusion of a local “libs” folder:

implementation(fileTree("libs"))

That app/libs folder is not part of the repo, it is ignored via the .gitignore file. So where does this folder come from?

Well, looking at the repo of the Go code, we see that the Android repo is included as a Git submodule there (the repo for the Apple code, too).

Now, looking at the Makefile we find several interesting targets, e.g.

lib_android:
	go run ./cmd/internal/build_libbox -target android

build_libbox runs something to generate that libbox library. That something is gomobile / gobind, the docs of which state:

Gobind generates language bindings that make it possible to call Go functions from Java and Objective-C.

Bingo. (actually, it uses a fork of gomobile)

This should give you enough pointers to look at and figure things out from there. :slight_smile: There are also some build instructions, albeit a bit thin.

2 Likes

Thank you very much frozenice.
You solved my problem. Now I know how to write programs in kotlin+golang.