libbinder_ndk: expose declared services list
Fixes: 180607992
Test: libbinder_ndk_unit_test
Change-Id: Id3ae079ff3bfaf13617ce39c6ed2738d6703fbd4
diff --git a/libs/binder/ndk/include_platform/android/binder_manager.h b/libs/binder/ndk/include_platform/android/binder_manager.h
index 4580751..5df0012 100644
--- a/libs/binder/ndk/include_platform/android/binder_manager.h
+++ b/libs/binder/ndk/include_platform/android/binder_manager.h
@@ -96,6 +96,22 @@
bool AServiceManager_isDeclared(const char* instance) __INTRODUCED_IN(31);
/**
+ * Returns all declared instances for a particular interface.
+ *
+ * For instance, if 'android.foo.IFoo/foo' is declared, and 'android.foo.IFoo' is
+ * passed here, then ["foo"] would be returned.
+ *
+ * See also AServiceManager_isDeclared.
+ *
+ * \param interface interface, e.g. 'android.foo.IFoo'
+ * \param context to pass to callback
+ * \param callback taking instance (e.g. 'foo') and context
+ */
+void AServiceManager_forEachDeclaredInstance(const char* interface, void* context,
+ void (*callback)(const char*, void*))
+ __INTRODUCED_IN(31);
+
+/**
* Prevent lazy services without client from shutting down their process
*
* \param persist 'true' if the process should not exit.
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index cef0bf3..8d08275 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -118,6 +118,7 @@
AIBinder_getCallingSid; # apex
AIBinder_setRequestingSid; # apex
AServiceManager_isDeclared; # apex llndk
+ AServiceManager_forEachDeclaredInstance; # apex llndk
AServiceManager_registerLazyService; # llndk
AServiceManager_waitForService; # apex llndk
AServiceManager_forceLazyServicesPersist; # llndk
diff --git a/libs/binder/ndk/service_manager.cpp b/libs/binder/ndk/service_manager.cpp
index cb0987e..1ccd0d2 100644
--- a/libs/binder/ndk/service_manager.cpp
+++ b/libs/binder/ndk/service_manager.cpp
@@ -19,6 +19,7 @@
#include "ibinder_internal.h"
#include "status_internal.h"
+#include <android-base/logging.h>
#include <binder/IServiceManager.h>
#include <binder/LazyServiceRegistrar.h>
@@ -28,6 +29,7 @@
using ::android::sp;
using ::android::status_t;
using ::android::String16;
+using ::android::String8;
binder_exception_t AServiceManager_addService(AIBinder* binder, const char* instance) {
if (binder == nullptr || instance == nullptr) {
@@ -92,6 +94,17 @@
sp<IServiceManager> sm = defaultServiceManager();
return sm->isDeclared(String16(instance));
}
+void AServiceManager_forEachDeclaredInstance(const char* interface, void* context,
+ void (*callback)(const char*, void*)) {
+ CHECK(interface != nullptr);
+ // context may be nullptr
+ CHECK(callback != nullptr);
+
+ sp<IServiceManager> sm = defaultServiceManager();
+ for (const String16& instance : sm->getDeclaredInstances(String16(interface))) {
+ callback(String8(instance).c_str(), context);
+ }
+}
void AServiceManager_forceLazyServicesPersist(bool persist) {
auto serviceRegistrar = android::binder::LazyServiceRegistrar::getInstance();
serviceRegistrar.forcePersist(persist);
@@ -110,4 +123,4 @@
void AServiceManager_reRegister() {
auto serviceRegistrar = android::binder::LazyServiceRegistrar::getInstance();
serviceRegistrar.reRegister();
-}
\ No newline at end of file
+}
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index de1a48d..6a88401 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -270,6 +270,25 @@
EXPECT_EQ(2, out);
}
+void defaultInstanceCounter(const char* instance, void* context) {
+ if (strcmp(instance, "default") == 0) {
+ ++*(size_t*)(context);
+ }
+}
+
+TEST(NdkBinder, GetDeclaredInstances) {
+ bool hasLight = AServiceManager_isDeclared("android.hardware.light.ILights/default");
+
+ size_t count;
+ AServiceManager_forEachDeclaredInstance("android.hardware.light.ILights", &count,
+ defaultInstanceCounter);
+
+ // At the time of writing this test, there is no good interface guaranteed
+ // to be on all devices. Cuttlefish has light, so this will generally test
+ // things.
+ EXPECT_EQ(count, hasLight ? 1 : 0);
+}
+
TEST(NdkBinder, GetLazyService) {
// Not declared in the vintf manifest
ASSERT_FALSE(AServiceManager_isDeclared(kLazyBinderNdkUnitTestService));