servicemanager: expose updatable-via-apex
Service manager is already reading VINTF, so processes that need this
information can access this information w/o needing more permissions.
Bug: 185832616
Test: two added tests + manually specifying updatable-via-apex on a
service and checking the result
Change-Id: Id86a72d49466048a3e2173e40526981abb6f3123
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 61f4581..f684cf6 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -75,6 +75,7 @@
sp<IBinder> waitForService(const String16& name16) override;
bool isDeclared(const String16& name) override;
Vector<String16> getDeclaredInstances(const String16& interface) override;
+ std::optional<String16> updatableViaApex(const String16& name) override;
// for legacy ABI
const String16& getInterfaceDescriptor() const override {
@@ -388,4 +389,12 @@
return res;
}
+std::optional<String16> ServiceManagerShim::updatableViaApex(const String16& name) {
+ std::optional<std::string> declared;
+ if (!mTheRealServiceManager->updatableViaApex(String8(name).c_str(), &declared).isOk()) {
+ return std::nullopt;
+ }
+ return declared ? std::optional<String16>(String16(declared.value().c_str())) : std::nullopt;
+}
+
} // namespace android
diff --git a/libs/binder/aidl/android/os/IServiceManager.aidl b/libs/binder/aidl/android/os/IServiceManager.aidl
index 2fabf94..75c4092 100644
--- a/libs/binder/aidl/android/os/IServiceManager.aidl
+++ b/libs/binder/aidl/android/os/IServiceManager.aidl
@@ -108,6 +108,11 @@
@utf8InCpp String[] getDeclaredInstances(@utf8InCpp String iface);
/**
+ * If updatable-via-apex, returns the APEX via which this is updated.
+ */
+ @nullable @utf8InCpp String updatableViaApex(@utf8InCpp String name);
+
+ /**
* Request a callback when the number of clients of the service changes.
* Used by LazyServiceRegistrar to dynamically stop services that have no clients.
*/
diff --git a/libs/binder/include/binder/IServiceManager.h b/libs/binder/include/binder/IServiceManager.h
index 5f0d056..3dbe2c4 100644
--- a/libs/binder/include/binder/IServiceManager.h
+++ b/libs/binder/include/binder/IServiceManager.h
@@ -20,6 +20,8 @@
#include <utils/Vector.h>
#include <utils/String16.h>
+#include <optional>
+
namespace android {
// ----------------------------------------------------------------------
@@ -99,6 +101,12 @@
* Get all instances of a service as declared in the VINTF manifest
*/
virtual Vector<String16> getDeclaredInstances(const String16& interface) = 0;
+
+ /**
+ * If this instance is updatable via an APEX, returns the APEX with which
+ * this can be updated.
+ */
+ virtual std::optional<String16> updatableViaApex(const String16& name) = 0;
};
sp<IServiceManager> defaultServiceManager();
diff --git a/libs/binder/ndk/include_platform/android/binder_manager.h b/libs/binder/ndk/include_platform/android/binder_manager.h
index 5516914..a90b4aa 100644
--- a/libs/binder/ndk/include_platform/android/binder_manager.h
+++ b/libs/binder/ndk/include_platform/android/binder_manager.h
@@ -124,6 +124,15 @@
__INTRODUCED_IN(31);
/**
+ * Check if a service is updatable via an APEX module.
+ *
+ * \param instance identifier of the service
+ *
+ * \return whether the interface is updatable via APEX
+ */
+bool AServiceManager_isUpdatableViaApex(const char* instance) __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 67c85b6..7d4b82e 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -118,14 +118,15 @@
AIBinder_getCallingSid; # apex
AIBinder_setRequestingSid; # apex
AParcel_markSensitive; # llndk
- AServiceManager_isDeclared; # apex llndk
AServiceManager_forEachDeclaredInstance; # apex llndk
- AServiceManager_registerLazyService; # llndk
- AServiceManager_waitForService; # apex llndk
AServiceManager_forceLazyServicesPersist; # llndk
+ AServiceManager_isDeclared; # apex llndk
+ AServiceManager_isUpdatableViaApex; # apex
+ AServiceManager_reRegister; # llndk
+ AServiceManager_registerLazyService; # llndk
AServiceManager_setActiveServicesCallback; # llndk
AServiceManager_tryUnregister; # llndk
- AServiceManager_reRegister; # llndk
+ AServiceManager_waitForService; # apex llndk
AIBinder_forceDowngradeToSystemStability; # apex
AIBinder_forceDowngradeToVendorStability; # llndk
diff --git a/libs/binder/ndk/service_manager.cpp b/libs/binder/ndk/service_manager.cpp
index 1ccd0d2..7649a26 100644
--- a/libs/binder/ndk/service_manager.cpp
+++ b/libs/binder/ndk/service_manager.cpp
@@ -105,6 +105,14 @@
callback(String8(instance).c_str(), context);
}
}
+bool AServiceManager_isUpdatableViaApex(const char* instance) {
+ if (instance == nullptr) {
+ return false;
+ }
+
+ sp<IServiceManager> sm = defaultServiceManager();
+ return sm->updatableViaApex(String16(instance)) != std::nullopt;
+}
void AServiceManager_forceLazyServicesPersist(bool persist) {
auto serviceRegistrar = android::binder::LazyServiceRegistrar::getInstance();
serviceRegistrar.forcePersist(persist);
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index 496a915..1c43948 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -280,6 +280,11 @@
EXPECT_EQ(STATUS_OK, AIBinder_ping(binder.get()));
}
+TEST(NdkBinder, IsUpdatable) {
+ bool isUpdatable = AServiceManager_isUpdatableViaApex("android.hardware.light.ILights/default");
+ EXPECT_EQ(isUpdatable, false);
+}
+
// This is too slow
TEST(NdkBinder, CheckLazyServiceShutDown) {
ndk::SpAIBinder binder(AServiceManager_waitForService(kLazyBinderNdkUnitTestService));
diff --git a/libs/binder/tests/binderStabilityTest.cpp b/libs/binder/tests/binderStabilityTest.cpp
index cb309bd..2ce13df 100644
--- a/libs/binder/tests/binderStabilityTest.cpp
+++ b/libs/binder/tests/binderStabilityTest.cpp
@@ -192,6 +192,8 @@
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
android::defaultServiceManager()->addService(String16("."), vintfServer)) << instance8;
EXPECT_FALSE(android::defaultServiceManager()->isDeclared(instance)) << instance8;
+ EXPECT_EQ(std::nullopt, android::defaultServiceManager()->updatableViaApex(instance))
+ << instance8;
}
}