libhidl: modify getService
1. Add a three-time retry after a second of delay each time if the first
attempt to get a binderized implementation of a HAL fails. This is
necessary since a client can start before the binderized service. In
the absence of better synchronization, we use a timeout.
2. Make it possible for the default passthrough implementation to be
asked for explicitly by the caller. When a binderized implementation
wishes to use the default implementation (e.g.,
android.hardware.nfc@1.0-impl), it can bypass the attempt to retrieve
the binderized call (which we know is missing).
b/31458381
b/31240290
causes b/31715232
Test: pass
Change-Id: I61b31593b381b2ab49fe20974b2316a7c0b5f25a
Signed-off-by: Iliyan Malchev <malchev@google.com>
diff --git a/include/hidl/HidlSupport.h b/include/hidl/HidlSupport.h
index 6b88664..791c3b3 100644
--- a/include/hidl/HidlSupport.h
+++ b/include/hidl/HidlSupport.h
@@ -239,23 +239,31 @@
#define DECLARE_REGISTER_AND_GET_SERVICE(INTERFACE) \
static ::android::sp<I##INTERFACE> getService( \
- const std::string &serviceName); \
+ const std::string &serviceName, bool getStub=false); \
status_t registerAsService( \
const std::string &serviceName); \
#define IMPLEMENT_REGISTER_AND_GET_SERVICE(INTERFACE, LIB) \
::android::sp<I##INTERFACE> I##INTERFACE::getService( \
- const std::string &serviceName) \
+ const std::string &serviceName, bool getStub) \
{ \
sp<I##INTERFACE> iface; \
- const sp<IServiceManager> sm = defaultServiceManager(); \
- if (sm != nullptr) { \
- sp<IBinder> binderIface = sm->checkService(String16(serviceName.c_str()), \
- I##INTERFACE::version); \
- iface = IHw##INTERFACE::asInterface(binderIface); \
- } \
- if (iface != nullptr) { \
- return iface; \
+ const struct timespec DELAY {1,0}; \
+ unsigned retries = 3; \
+ if (!getStub) { \
+ do { \
+ const sp<IServiceManager> sm = defaultServiceManager(); \
+ if (sm != nullptr) { \
+ sp<IBinder> binderIface = \
+ sm->checkService(String16(serviceName.c_str()), \
+ I##INTERFACE::version); \
+ iface = IHw##INTERFACE::asInterface(binderIface); \
+ } \
+ if (iface != nullptr) { \
+ return iface; \
+ } \
+ TEMP_FAILURE_RETRY(nanosleep(&DELAY, nullptr)); \
+ } while (retries--); \
} \
int dlMode = RTLD_LAZY; \
void *handle = dlopen(HAL_LIBRARY_PATH_ODM LIB, dlMode); \