Merge "Don't initialize ProcessState without /dev/hwbinder."
diff --git a/include/hidl/HidlSupport.h b/include/hidl/HidlSupport.h
index 4b0e369..8c864ca 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 {
@@ -189,14 +190,14 @@
// Version functions
struct hidl_version {
public:
- hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {};
+ constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {};
bool operator==(const hidl_version& other) {
return (mMajor == other.get_major() && mMinor == other.get_minor());
}
- uint16_t get_major() const { return mMajor; }
- uint16_t get_minor() const { return mMinor; }
+ constexpr uint16_t get_major() const { return mMajor; }
+ constexpr uint16_t get_minor() const { return mMinor; }
android::status_t writeToParcel(android::hardware::Parcel& parcel) const {
return parcel.writeUint32((uint32_t) mMajor << 16 | mMinor);
@@ -221,35 +222,61 @@
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( \
- const ::android::String16& serviceName, \
- const hidl_version &version);
+ const std::string &serviceName); \
+ status_t registerAsService( \
+ const std::string &serviceName); \
-#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 */) \
+ const std::string &serviceName) \
{ \
sp<I##INTERFACE> iface; \
const sp<IServiceManager> sm = defaultServiceManager(); \
if (sm != nullptr) { \
- sp<IBinder> binderIface = sm->getService(serviceName, version); \
+ sp<IBinder> binderIface = sm->checkService(String16(serviceName.c_str()), \
+ I##INTERFACE::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)(serviceName.c_str()); \
+ } \
return iface; \
} \
- status_t I##INTERFACE::registerAsService( \
- const ::android::String16& serviceName, \
- const hidl_version &version) \
+ status_t I##INTERFACE::registerAsService( \
+ const std::string &serviceName) \
{ \
sp<Bn##INTERFACE> binderIface = new Bn##INTERFACE(this); \
const sp<IServiceManager> sm = defaultServiceManager(); \
- return sm->addService(serviceName, binderIface, version); \
+ return sm->addService(String16(serviceName.c_str()), binderIface, \
+ I##INTERFACE::version); \
}
} // namespace hardware
diff --git a/include/hidl/Status.h b/include/hidl/Status.h
index aa8f1b2..59e4d65 100644
--- a/include/hidl/Status.h
+++ b/include/hidl/Status.h
@@ -147,20 +147,33 @@
std::stringstream& operator<< (std::stringstream& stream, const Status& s);
template<typename T> class Return {
+private:
+ T val {};
+ Status status {};
public:
- T val;
- Status status;
-public:
- Return(T v) : val(v), status(Status::ok()) { }
- Return(Status s) : status(s) {
- // TODO(malchev): Spew a LOG error here
- }
- ~Return() {
- // TODO(malchev): Assert that status isOk() if it hasn't been checked
- }
+ Return(T v) : val{v} {}
+ Return(Status s) : status(s) {}
operator T() { return val; }
+ const Status& getStatus() const {
+ return status;
+ }
};
+template<> class Return<void> {
+private:
+ Status status {};
+public:
+ Return() = default;
+ Return(Status s) : status(s) {}
+ const Status& getStatus() const {
+ return status;
+ }
+};
+
+static inline Return<void> Void() {
+ return Return<void>();
+}
+
} // namespace hardware
} // namespace android