getService needs to load default implementation.
IFoo::getService() first queries the servicemanager
to find out whether a binderized service is registered.
If it doens't find a binderized service, it instead tries
to load a default implementation by loading a well-known
shared library and calling a well-known function symbol on
it to generate an implementation of the interface.
For example, for interface android.hardware.tests.foo@1.0::IFoo
it tries to load the android.hardware.tests.foo@1.0.impl.so library,
and then calls HIDL_FETCH_IFOO(name), where 'name' corresponds to
the service name passed into getService().
Bug: 31228745
Change-Id: I77378f20469d015947974616c320b524a3f6d393
diff --git a/include/hidl/HidlSupport.h b/include/hidl/HidlSupport.h
index 4b0e369..ac3e3e2 100644
--- a/include/hidl/HidlSupport.h
+++ b/include/hidl/HidlSupport.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_HIDL_SUPPORT_H
#define ANDROID_HIDL_SUPPORT_H
+#include <dlfcn.h>
#include <hwbinder/Parcel.h>
namespace android {
@@ -221,15 +222,25 @@
return hidl_version(major,minor);
}
+#if defined(__LP64__)
+#define HAL_LIBRARY_PATH_SYSTEM "/system/lib64/hw/"
+#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib64/hw/"
+#define HAL_LIBRARY_PATH_ODM "/odm/lib64/hw/"
+#else
+#define HAL_LIBRARY_PATH_SYSTEM "/system/lib/hw/"
+#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib/hw/"
+#define HAL_LIBRARY_PATH_ODM "/odm/lib/hw/"
+#endif
+
#define DECLARE_REGISTER_AND_GET_SERVICE(INTERFACE) \
static ::android::sp<I##INTERFACE> getService( \
const ::android::String16 &serviceName, \
const hidl_version &version); \
- status_t registerAsService( \
+ status_t registerAsService( \
const ::android::String16& serviceName, \
const hidl_version &version);
-#define IMPLEMENT_REGISTER_AND_GET_SERVICE(INTERFACE) \
+#define IMPLEMENT_REGISTER_AND_GET_SERVICE(INTERFACE, LIB) \
::android::sp<I##INTERFACE> I##INTERFACE::getService( \
const ::android::String16 &serviceName, \
const hidl_version &version /* TODO get version from IFoo directly */) \
@@ -237,13 +248,31 @@
sp<I##INTERFACE> iface; \
const sp<IServiceManager> sm = defaultServiceManager(); \
if (sm != nullptr) { \
- sp<IBinder> binderIface = sm->getService(serviceName, version); \
+ sp<IBinder> binderIface = sm->checkService(serviceName, version); \
iface = IHw##INTERFACE::asInterface(binderIface); \
} \
- /* TODO: if we don't have a binder interface, try to instantiate default */ \
+ if (iface != nullptr) { \
+ return iface; \
+ } \
+ int dlMode = RTLD_LAZY; \
+ void *handle = dlopen(HAL_LIBRARY_PATH_ODM LIB, dlMode); \
+ if (handle == nullptr) { \
+ handle = dlopen(HAL_LIBRARY_PATH_VENDOR LIB, dlMode); \
+ } \
+ if (handle == nullptr) { \
+ handle = dlopen(HAL_LIBRARY_PATH_SYSTEM LIB, dlMode); \
+ } \
+ if (handle == nullptr) { \
+ return iface; \
+ } \
+ I##INTERFACE* (*generator)(const char* name); \
+ *(void **)(&generator) = dlsym(handle, "HIDL_FETCH_I"#INTERFACE); \
+ if (generator) { \
+ iface = (*generator)(String8(serviceName).string()); \
+ } \
return iface; \
} \
- status_t I##INTERFACE::registerAsService( \
+ status_t I##INTERFACE::registerAsService( \
const ::android::String16& serviceName, \
const hidl_version &version) \
{ \