Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for exposing services #53

Open
s1341 opened this issue Mar 14, 2021 · 15 comments
Open

Support for exposing services #53

s1341 opened this issue Mar 14, 2021 · 15 comments

Comments

@s1341
Copy link

s1341 commented Mar 14, 2021

It doesn't seem like there is currently support for exposing services from an application.

I'd like to add this feature... How do I wire up the service from the 'java' to a function?

@dvc94ch
Copy link

dvc94ch commented Apr 30, 2021

looked into this a bit. unlike the NativeActivity there is no NativeService. there is a libbinder.so that provides what is needed, but it seems that that is only available for oems and not application developers. the libbinder_ndk.so that is available to app developers seems to lack essential functionality like AServiceManager_getService. Not sure what libbinder_ndk.so is useful for exactly. for these reasons I think cargo-apk won't work for services and you need to stick with java/gradle and loading a dynamic library. cc @wngr

@s1341
Copy link
Author

s1341 commented May 3, 2021

Thanks for looking into this.

I'm going to close the issue for now, as I don't see a way forward.

@s1341 s1341 closed this as completed May 3, 2021
@canndrew
Copy link

Hi, I'm a complete noob to this stuff and trying to write my first android app in rust, so sorry if this is a dumb question. Would it be possible to let users define services and have cargo apk generate a small java shim for each service which it links to from the manifest?

I was hoping to avoid having to deal with java and android studio, and it's cool that this project allows me to do that for the simple test app that I've written, but now I want to run my app as a background service. Since ordinary non-OEM developers are allowed to define services, and since cargo apk is already generating a bunch of stuff to wrap my rust program into an android package, it seems like it should be possible to have cargo apk generate whatever more stuff is necessary to define services and have the entry points of the service just call into my rust code, no? Or is this out-of-scope for this project or otherwise impossible for reasons explained above?

(Again, sorry for the noise if I'm being dumb. I've only been learning android for an entire hour.)

@dvc94ch
Copy link

dvc94ch commented May 30, 2021

It may be possible to invent a NativeService. I guess the first step would be to copy the NativeActivity (from the Android sources) and try to build an APK using the custom NativeActivity instead of the stock one. Then we could discuss extending cargo-apk/ndk-glue/etc with some service callbacks.

@MarijnS95
Copy link
Member

For the record android-ndk-rs doesn't generate anything besides AndroidManifest.xml. The rest is C bindings (and safe wrappers) around the NDK, toolchain discovery and setting up the compiler/linker to target Android.

Since the NDK does not provide any API to host native services this sounds like a separate project/crate that does all the heavy Java lifting through JNI.

@dvc94ch
Copy link

dvc94ch commented May 30, 2021

I agree with you that any jni stuff is out of scope (last part of the diagram below). But this is about the entry point:

java NativeActivity -> rust -> java libraries via jni

I think this might be in scope for cargo-apk as it requires support to compile a bit of java using javac and somehow link it agains android.jar and include it in the apk. Also the generated AndroidManifest.xml would need to support using it as an entry point.

@MarijnS95
Copy link
Member

@dvc94ch Ah, right, that sounds okay I guess. We have much better support for custom Manifest entries in Cargo.toml now so it wouldn't be too hard to define ones' custom <activity> in there now.

That said I do wonder if you can get away with implementing this in pure Rust through the JNI, instead of going through Java and javac like how NativeActivity is defined? Though, that's something for the implementor to investigate and decide on.

@dvc94ch
Copy link

dvc94ch commented May 30, 2021

That isn't possible, all apks are java applications with possibly native dynamic libraries. In addition there is a default java activity called NativeActivity that loads a dynamic library from an apk and calls some callbacks in it. In the AndroidManifest we declare that it should be loaded using the NativeActivity, and this works as long as the NativeActivity is sufficient. In the case of services or background tasks there is no support for loading native code directly, so we'd need to customize the NativeActivity to support more use cases.

@dvc94ch
Copy link

dvc94ch commented May 30, 2021

I guess once someone gives it a go and opens a PR and there is a concrete proposal we can discuss it further. I think we will have to create a custom rust loader in java and support it in ndk-glue and cargo-apk.

@MarijnS95
Copy link
Member

@dvc94ch Indeed NativeActivity (android.app.Activity subclass) is implemented in Java which loads the shared object and "forwards" callbacks to native functions. It should be possible to create a Java class from Rust that does the same for android.app.Service, but I have no idea how to teach ART and friends to retrieve and instantiate a class type from a native function instead of loading it from classes.dex (which is why NativeActivity exists in the first place). Seems like that is not possible unfortunately.

@dvc94ch
Copy link

dvc94ch commented Jun 10, 2022

@s1341 I see you wrote a rust binder implementation interfacing directly with /dev/binder. does this actually work without rooting?

@s1341
Copy link
Author

s1341 commented Jun 12, 2022

You cannot register a service without root, unfortunately. But you can talk to existing services/content-providers/etc.

@MarijnS95
Copy link
Member

Doesn't the NDK expose a Binder API nowadays? https://developer.android.com/ndk/reference/group/ndk-binder

@dvc94ch
Copy link

dvc94ch commented Jun 12, 2022

I'm a bit confused. android.jar seems to be mostly thin wrappers around aidl generated code. aidl has a c++ and rust backend. why doesn't the ndk generate support for all the services? Can we use the rust aidl backend to generate bindings that work?

@MarijnS95
Copy link
Member

Isn't that Rust backend fairly new? I'm not surprised/confused why our ndk doesn't use that yet :)

But I'm all in favour of adding a new ndk-aidl crate of some sorts!

@dvc94ch dvc94ch transferred this issue from rust-mobile/ndk Dec 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants