4

I started out writing a simple C++ program that tried to get the handle of a service using

defaultServiceManager()->getService(String16('ServiceName'));

Which has now snowballed into this terrible dependency recursion. Ultimately what I need is:

  • libbinder for defaultServiceManager and getService
  • libutils for String16

Neither of these are available in the NDK. Their sources are in the SDK along with all the appropriate headers. I can get everything to behave nicely until link time:

undefined reference to `android::defaultServiceManager()'
undefined reference to `android::String16::String16(char const*)'
undefined reference to `android::String16::~String16()'
undefined reference to `android::String16::~String16()'

Is it required to build this as a part of AOSP? Perhaps through something like ndk-build? What I am building is more of a toy application that only needs access to those (and related, e.g. service->transact APIs) APIs along with Parcel.

Perhaps building AOSP once and using -L to include a search path to the generated libs.

sherrellbc
  • 4,650
  • 9
  • 48
  • 77
  • "Neither of these are available in the NDK. Their sources are in the SDK along with all the appropriate headers." Where? – Dan Albert Jun 04 '20 at 20:59
  • @DanAlbert `libbinder` is at `$SDK/frameworks/native/libs/binder` and `libutils` is at `$SDK/system/core/libutils`. – sherrellbc Jun 05 '20 at 09:53

2 Answers2

1

libbinder and libutils are not part of the app API surface. https://developer.android.com/ndk/reference/group/ndk-binder is the NDK binder API.

Dan Albert
  • 10,079
  • 2
  • 36
  • 79
  • Hm. There seems to be quite a bit of useful Binder APIs in there, including `transact` and `Parcel`-related ones for communicating. Many of them take `AIBinder` pointers. From what I've seen, many/all services inherit from the `IBinder` class. Is the A-prefix an indication of NDK somehow? – sherrellbc Jun 05 '20 at 11:51
  • If not, what are `AIBinder` pointers? The APIs seem very similar to the ones provided by the C++ code in `libbinder`. Overall it seems quite close, and even usable from regular C. But I don't see a way to lookup a service as with `defaultServiceManager()->getService(name))`. Are you aware of a way to do this? – sherrellbc Jun 05 '20 at 11:52
  • Also now that I'm looking at this again I recall running into issues with linking. The NDK indeed has `libbinder_ndk.so`, but the device does not have this object, only `libbinder.so`. While not huge deal for my purposes (since I can use `LD_PRELOAD`, or `LD_LIBRARY_PATH`), I was unsure what to make of the absence. Although `libc++_shared.so` is the same way and according to the documentation must be packed into any APKs that want to link against it. I didn't see any mention of this regarding `libbinder_ndk.so`, though. – sherrellbc Jun 05 '20 at 12:07
  • Regarding my comment about finding services, I found [this](https://android.googlesource.com/platform/frameworks/native/+/master/libs/binder/ndk/service_manager.cpp)/[this](https://gerrit.pixelexperience.org/plugins/gitiles/frameworks_native/+/0dc848b8adf4451b393e80008795d9387953c271/libs/binder/ndk/include_apex/android/binder_manager.h) reference to code that apparently does this lookup, though I can't find it in the source tree. – sherrellbc Jun 05 '20 at 12:11
  • So, it seems like the issue I've found with this answer is that the `libbinder_ndk.so` included in the latest NDK (r21c) does _not_ have the new `AServiceManager_getService` API, despite claiming to be API29 compliant. – sherrellbc Jun 05 '20 at 15:23
  • `AServiceManager_getService` is not an NDK API. I know this isn't the answer you wanted, but it appears that what you're trying to do is not supported for apps, at least not directly through the NDK (I don't know if the Java API surface has what you're looking for). – Dan Albert Jun 05 '20 at 23:30
  • "The NDK indeed has libbinder_ndk.so, but the device does not have this object" the API is only available on devices of API 29 and higher. – Dan Albert Jun 05 '20 at 23:32
  • I opened another question [here](https://stackoverflow.com/questions/62219306/latest-android-ndk-r21cs-libbinder-ndk-is-missing-several-exported-apis) last week. That API appears to be part of the NDK, though it is not exported in `libbinder_ndk.so` for some reason. Although if you build AOSP from source for API29+ (Android 10) then the built object _does_ export these symbols. This seems incorrect to me. I feel as if the NDK has been neglecting to export these APIs for some time. That code has been available for several years, though the documentation does not mention it. – sherrellbc Jun 08 '20 at 11:21
  • It is correct. They exist for vendor and APEX users. Those domains do not carry the same guarantees that are needed for apps to use them reliably, so they are not exposed to apps. – Dan Albert Jun 09 '20 at 08:40
0

This (dirty hack) is working fine for me:

#include <android/binder_ibinder.h>

typedef AIBinder* (*AServiceManager_getService_func)(const char* instance);

extern "C"
JNIEXPORT void JNICALL
Java_com_irsl_greedybinder_MainActivity_testService(JNIEnv *env, jclass clazz) {

    void* binder_ndk = dlopen("/system/lib/libbinder_ndk.so", RTLD_LAZY);
    if (binder_ndk == nullptr) {
        ALOGI("Unable to load libbinder_ndk.so");
        return;
    }

    AServiceManager_getService_func AServiceManager_getService;

    AServiceManager_getService = (AServiceManager_getService_func) dlsym(binder_ndk, "AServiceManager_getService");
    if(AServiceManager_getService == nullptr) {
        ALOGI("Failed to look up AServiceManager_getService");
        return;
    }
    ALOGI("AServiceManager_getService symbol found at: %p", AServiceManager_getService);

    AIBinder* binder = AServiceManager_getService("activity");
    if (binder == nullptr) {
        ALOGI("Unable to obtain Activity Manager service");
        return;
    }

    ALOGI("We got the binder to the Activity Manager!: %p", binder);
}

Disclaimer by Dan Albert applies: They exist for vendor and APEX users. Those domains do not carry the same guarantees that are needed for apps to use them reliably, so they are not exposed to apps.

Saturnus
  • 99
  • 6