Update for namespaced services in hwservicemanager.
IServiceManager now takes interfaceChain for registration and a
fully-qualified name for service retrieval. This allows for services to
register as their parent classes as well. So, for instance, a vendor hal
can serve both vendor code and the android framework which expects a
non-customized hal.
Technically, we should be able to call 'interfaceChain' on the interface
that is passed into the service manager, however at the time that 'get'
is called, the registering hal won't be serving itself over binder.
Test: end to end
Bug: 31861268
Change-Id: I9904b3ab959a47a5556d5773ffe6fb535983cf00
diff --git a/include/hidl/HidlSupport.h b/include/hidl/HidlSupport.h
index cdeb2c8..da82850 100644
--- a/include/hidl/HidlSupport.h
+++ b/include/hidl/HidlSupport.h
@@ -636,7 +636,7 @@
::android::status_t registerAsService( \
const std::string &serviceName); \
-#define IMPLEMENT_REGISTER_AND_GET_SERVICE(INTERFACE, LIB) \
+#define IMPLEMENT_REGISTER_AND_GET_SERVICE(INTERFACE, PACKAGE) \
::android::sp<I##INTERFACE> I##INTERFACE::getService( \
const std::string &serviceName, bool getStub) \
{ \
@@ -648,26 +648,25 @@
const sp<IServiceManager> sm = defaultServiceManager(); \
if (sm != nullptr && !getStub) { \
sp<IBinder> binderIface; \
- IServiceManager::Version version { \
- .major = I##INTERFACE::version.get_major(), \
- .minor = I##INTERFACE::version.get_minor(), \
- }; \
- sm->get(serviceName.c_str(), version, \
- [&binderIface](sp<IBinder> iface) { \
- binderIface = iface; \
- }); \
- iface = IHw##INTERFACE::asInterface(binderIface); \
- if (iface != nullptr) { \
- return iface; \
+ ::android::hardware::Return<void> ret = \
+ sm->get(PACKAGE "::I" #INTERFACE, serviceName.c_str(), \
+ [&binderIface](sp<IBinder> iface) { \
+ binderIface = iface; \
+ }); \
+ if (ret.getStatus().isOk()) { \
+ iface = IHw##INTERFACE::asInterface(binderIface); \
+ if (iface != nullptr) { \
+ return iface; \
+ } \
} \
} \
int dlMode = RTLD_LAZY; \
- void *handle = dlopen(HAL_LIBRARY_PATH_ODM LIB, dlMode); \
+ void *handle = dlopen(HAL_LIBRARY_PATH_ODM PACKAGE "-impl.so", dlMode); \
if (handle == nullptr) { \
- handle = dlopen(HAL_LIBRARY_PATH_VENDOR LIB, dlMode); \
+ handle = dlopen(HAL_LIBRARY_PATH_VENDOR PACKAGE "-impl.so", dlMode); \
} \
if (handle == nullptr) { \
- handle = dlopen(HAL_LIBRARY_PATH_SYSTEM LIB, dlMode); \
+ handle = dlopen(HAL_LIBRARY_PATH_SYSTEM PACKAGE "-impl.so", dlMode); \
} \
if (handle == nullptr) { \
return iface; \
@@ -687,16 +686,18 @@
{ \
using ::android::sp; \
using ::android::hardware::defaultServiceManager; \
+ using ::android::hardware::hidl_string; \
using ::android::hidl::manager::V1_0::IServiceManager; \
sp<Bn##INTERFACE> binderIface = new Bn##INTERFACE(this); \
const sp<IServiceManager> sm = defaultServiceManager(); \
- IServiceManager::Version version { \
- .major = I##INTERFACE::version.get_major(), \
- .minor = I##INTERFACE::version.get_minor(), \
- }; \
- sm->add(serviceName.c_str(), binderIface, version); \
- /* TODO return value */ \
- return ::android::OK; \
+ bool success = false; \
+ ::android::hardware::Return<void> ret = \
+ this->interfaceChain( \
+ [&success, &sm, &serviceName, &binderIface](const auto &chain) { \
+ success = sm->add(chain, serviceName.c_str(), binderIface); \
+ }); \
+ success = success && ret.getStatus().isOk(); \
+ return success ? ::android::OK : ::android::UNKNOWN_ERROR; \
}
// ----------------------------------------------------------------------
diff --git a/manager/1.0/IServiceManager.hal b/manager/1.0/IServiceManager.hal
index 1e76814..16c0c8c 100644
--- a/manager/1.0/IServiceManager.hal
+++ b/manager/1.0/IServiceManager.hal
@@ -17,28 +17,39 @@
package android.hidl.manager@1.0;
interface IServiceManager {
- struct Version {
- uint16_t major;
- uint16_t minor;
- };
/**
* Retrieve an existing service.
*
- * Warning: This function should only be used in specific circumstances. You
- * are likely looking for 'IMyInterface::getService("name");'.
+ * WARNING: This function is for libhidl/HwBinder use only. You are likely
+ * looking for 'IMyInterface::getService("name")' instead.
+ *
+ * @param iface Fully-qualified interface name.
+ * e.x. "android.hidl.manager@1.0::IServiceManager"
+ * @param name Name of the specific instance of the service. Same as
+ * name in IServiceManager::add. e.x. "manager"
+ *
+ * @return service Handle to requested service, same as provided in
+ * IServiceManager::add.
*/
- get(string name, Version version) generates (interface service);
+ get(string fqName, string name) generates (interface service);
/**
* Register a service.
*
- * Warning: Function 'INTERFACE::registerAsService' should be used
- * instead of this to register services.
+ * WARNING: This function is for libhidl/HwBinder use only. You are likely
+ * looking for 'INTERFACE::registerAsService("name")' instead.
*
- * TODO: namespace out name per interface type.
- * register as super classes as well.
+ * @param interfaceChain List of fully-qualified interface names. The first
+ * must be the actual interface name. Subsequent names must
+ * follow the inheritance hierarchy of the interface.
+ * @param name Can be anything. Must also be used to retrieve service.
+ * @param service Handle to registering service.
+ *
+ * @return success Whether or not the service was registered.
+ *
*/
- add(string name, interface service, Version version) generates (bool success);
+ add(vec<string> interfaceChain, string name, interface service)
+ generates (bool success);
};
\ No newline at end of file