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/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));