Closed RangerMauve closed 2 years ago
More details for running the binary. https://stackoverflow.com/questions/16179062/using-exec-with-ndk
We will likely want to use a bound service launched from our activity. This should also make the lifecycle of the service easy to manage because it can terminate the gateway once all activities have stopped asking for it.
We'll want to bundle the gateway binary in here: https://www.chromium.org/developers/design-documents/java-resources-on-android/
We could potentially make a Java class for starting the gateway and invoke it via JNI from the C++ code when the context is created. https://chromium.googlesource.com/chromium/src/+/HEAD/base/android/jni_generator/README.md
Maybe we can reuse Chrome's ChildProcessLauncher class?
This class is wrapped by the C++ code in here: https://source.chromium.org/chromium/chromium/src/+/main:content/browser/child_process_launcher_helper_android.cc;l=100;drc=4f70b046f82976388f68084840bd3e9b2811ec27;bpv=1;bpt=1
The CommandLine class might be relevant for us.
It takes a path and some commandline options.
This is used in the ChildProcessLauncher class which I think launches child processes.
This is used to implement the BrowserChildProcessHost and the RendererProcessHost
We could also use the ProcessSingleton class which takes a FilePath to a user directory and has methods for controlling the lifecycle like .Create()
and .Cleanup()
. Though this might be specific to the Chrome process and won't have options for using the gateway. 🤔
Feels like it might be easier to just use a Java service in Android and invoke some JNI
I think the right place to bind to the IPFSService would be inside ChromeActivity.initDeferrdStartupForActivity which gets invoked once the top level activity is initialized.
Inside it we can do whatever we want with the activity context to bind and unbind the service.
The method I used where we copy the binary from the res/raw
folder isn't working because Android Q blocks running binaries from writable directories.
Instead I'm going to find a way to move the binary into the lib
folder for the correct architecture and follow something like this
We potentially have no choice but to use gomobile or CGO or something to generate a regular library file to invoke via JNI somehow. ðŸ˜
Google's reponse has basically be "Oh well sucks to suck, deal with it GG no Re", and there's been no updates since 2020. 🙃
https://issuetracker.google.com/issues/160129591
The alternative is to publish the app as debuggable? But that seems wrong too.
As well, to use the work around, we'd need to use android:extractnativeLibs="true"
which conflicts with chrome setting android:extractnativeLibs="false"
in the manifest.
But Google does run multiple processes from the binary... so there must be something going on there.
So, manually copying the daemon as a .so
file in the APK doesn't work because the APK is signed. We could either figure out how to generate unsigned APKs, or to keep looking into the build process.
So far it looks like we'll need to modify third_party/android_deps/BUILD.gn to add a .jar
or .aar
We might be able to get away with prebuilding an aar
with gomobile in @makeworld-the-better-one 's GithubActions workflow, but we might also need to add the gateway as a submodule within third_party/
and have it's own BUILD.gn
in there to trigger the build.
To add the gateway to the source tree, we'll need to add the repo to the root DEPS file with a commit and repo.
For example, inside third_party/android_deps/com_android_support_coordinatorlayout there's an .aar
file with a bit of metadata which we can likely look at for our structure.
Going to instead base things off of the arcore-android-sdk-client
library since it's at the top level of third_party and might be easier to pull in.
Managed to get the AAR and the libgojni.so
binary loaded in the GN build system.
Now running into a runtime error due to the MitlicastLock not being enabled. https://github.com/ipfs-shipyard/gomobile-ipfs/issues/68
I think I can just aquire the lock inside the IPFSService before starting the go thread and to relinquish it on destroy (or on error?)
It's working, but we need to figure out why it's crashing on boot sometimes. Might be related to zeroconf errors we're seeing in the logs.
@makeworld-the-better-one fixed the zeroconf issues in the latest version of the daemon and it's all good to go as of #11 !
There might be some issues here.
Looking at the docs for chromium Android they mentioned that Android doesn't support forking processes. https://docs.google.com/document/d/1PTI3udZ6TI-R0MlSsl2aflxRcnZ5blnkGGHE5JRI_Z8/edit#
Chromium folks work around this by having processes run inside separate services.
We might need to run the gateway within its own service and to run it from Java using this method