Split libhidl into base and transport.
libhidlbase contains "pure" classes that has nothing
to do with tranport level stuff. libhwbinder can now
safely depend on libhidlbase.
IBinder inheriting from IBase will be in a follow up
CL.
Bug: 32756130
Test: mma under hardware/interfaces
Test: hidl_test
Change-Id: Ie2bd80769df3816aab83789ba0d7fca9b5a2e52f
diff --git a/transport/Android.bp b/transport/Android.bp
new file mode 100644
index 0000000..032381a
--- /dev/null
+++ b/transport/Android.bp
@@ -0,0 +1,52 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+subdirs = [
+ "manager/1.0"
+]
+
+cc_library_shared {
+ name: "libhidltransport",
+ shared_libs: [
+ "libbase",
+ "liblog",
+ "libutils",
+ "libhidlbase",
+ "libhwbinder",
+ "libcutils",
+ ],
+ export_shared_lib_headers: [
+ "libbase",
+ "libutils",
+ "libhidlbase",
+ ],
+
+ export_include_dirs: ["include"],
+
+ generated_sources: ["android.hidl.manager@1.0_genc++"],
+ generated_headers: ["android.hidl.manager@1.0_genc++_headers"],
+ export_generated_headers: ["android.hidl.manager@1.0_genc++_headers"],
+
+ srcs: [
+ "HidlBinderSupport.cpp",
+ "ServiceManagement.cpp",
+ "Static.cpp"
+ ],
+
+ product_variables: {
+ debuggable: {
+ cflags: ["-DLIBHIDL_TARGET_DEBUGGABLE"],
+ },
+ },
+}
diff --git a/transport/HidlBinderSupport.cpp b/transport/HidlBinderSupport.cpp
new file mode 100644
index 0000000..c206018
--- /dev/null
+++ b/transport/HidlBinderSupport.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "HidlSupport"
+
+#include <hidl/HidlBinderSupport.h>
+
+#ifdef LIBHIDL_TARGET_DEBUGGABLE
+#include <android-base/logging.h>
+#endif
+
+namespace android {
+namespace hardware {
+
+std::map<std::string, std::function<sp<IBinder>(void*)>> gBnConstructorMap{};
+
+// static
+const size_t hidl_string::kOffsetOfBuffer = offsetof(hidl_string, mBuffer);
+
+status_t readEmbeddedFromParcel(hidl_string * /* string */,
+ const Parcel &parcel, size_t parentHandle, size_t parentOffset) {
+ const void *ptr = parcel.readEmbeddedBuffer(
+ nullptr /* buffer_handle */,
+ parentHandle,
+ parentOffset + hidl_string::kOffsetOfBuffer);
+
+ return ptr != NULL ? OK : UNKNOWN_ERROR;
+}
+
+status_t writeEmbeddedToParcel(const hidl_string &string,
+ Parcel *parcel, size_t parentHandle, size_t parentOffset) {
+ return parcel->writeEmbeddedBuffer(
+ string.c_str(),
+ string.size() + 1,
+ nullptr /* handle */,
+ parentHandle,
+ parentOffset + hidl_string::kOffsetOfBuffer);
+}
+
+android::status_t writeToParcel(const hidl_version &version, android::hardware::Parcel& parcel) {
+ return parcel.writeUint32(static_cast<uint32_t>(version.get_major()) << 16 | version.get_minor());
+}
+
+hidl_version* readFromParcel(const android::hardware::Parcel& parcel) {
+ uint32_t version;
+ android::status_t status = parcel.readUint32(&version);
+ if (status != OK) {
+ return nullptr;
+ } else {
+ return new hidl_version(version >> 16, version & 0xFFFF);
+ }
+}
+
+status_t readFromParcel(Status *s, const Parcel& parcel) {
+ int32_t exception;
+ int32_t errorCode;
+ status_t status = parcel.readInt32(&exception);
+ if (status != OK) {
+ s->setFromStatusT(status);
+ return status;
+ }
+
+ // Skip over fat response headers. Not used (or propagated) in native code.
+ if (exception == Status::EX_HAS_REPLY_HEADER) {
+ // Note that the header size includes the 4 byte size field.
+ const int32_t header_start = parcel.dataPosition();
+ int32_t header_size;
+ status = parcel.readInt32(&header_size);
+ if (status != OK) {
+ s->setFromStatusT(status);
+ return status;
+ }
+ parcel.setDataPosition(header_start + header_size);
+ // And fat response headers are currently only used when there are no
+ // exceptions, so act like there was no error.
+ exception = Status::EX_NONE;
+ }
+
+ if (exception == Status::EX_NONE) {
+ *s = Status::ok();
+ return status;
+ }
+
+ // The remote threw an exception. Get the message back.
+ String16 message;
+ status = parcel.readString16(&message);
+ if (status != OK) {
+ s->setFromStatusT(status);
+ return status;
+ }
+
+ if (exception == Status::EX_SERVICE_SPECIFIC) {
+ status = parcel.readInt32(&errorCode);
+ }
+ if (status != OK) {
+ s->setFromStatusT(status);
+ return status;
+ }
+
+ if (exception == Status::EX_SERVICE_SPECIFIC) {
+ s->setServiceSpecificError(errorCode, String8(message));
+ } else {
+ s->setException(exception, String8(message));
+ }
+
+ return status;
+}
+
+status_t writeToParcel(const Status &s, Parcel* parcel) {
+ // Something really bad has happened, and we're not going to even
+ // try returning rich error data.
+ if (s.exceptionCode() == Status::EX_TRANSACTION_FAILED) {
+ return s.transactionError();
+ }
+
+ status_t status = parcel->writeInt32(s.exceptionCode());
+ if (status != OK) { return status; }
+ if (s.exceptionCode() == Status::EX_NONE) {
+ // We have no more information to write.
+ return status;
+ }
+ status = parcel->writeString16(String16(s.exceptionMessage()));
+ if (s.exceptionCode() != Status::EX_SERVICE_SPECIFIC) {
+ // We have no more information to write.
+ return status;
+ }
+ status = parcel->writeInt32(s.serviceSpecificErrorCode());
+ return status;
+}
+
+} // namespace hardware
+} // namespace android
diff --git a/transport/ServiceManagement.cpp b/transport/ServiceManagement.cpp
new file mode 100644
index 0000000..102fa6c
--- /dev/null
+++ b/transport/ServiceManagement.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ServiceManagement"
+
+#include <hidl/ServiceManagement.h>
+#include <hidl/Static.h>
+#include <hidl/Status.h>
+
+#include <hwbinder/IPCThreadState.h>
+#include <hwbinder/Parcel.h>
+#include <utils/Log.h>
+#include <utils/SystemClock.h>
+
+#include <unistd.h>
+
+#include <android/hidl/manager/1.0/IServiceManager.h>
+#include <android/hidl/manager/1.0/IHwServiceManager.h>
+
+using android::hidl::manager::V1_0::IHwServiceManager;
+using android::hidl::manager::V1_0::IServiceManager;
+
+namespace android {
+namespace hardware {
+
+sp<IServiceManager> defaultServiceManager() {
+
+ if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
+ if (access("/dev/hwbinder", F_OK|R_OK|W_OK) != 0) {
+ // HwBinder not available on this device or not accessible to
+ // this process.
+ return nullptr;
+ }
+ {
+ AutoMutex _l(gDefaultServiceManagerLock);
+ while (gDefaultServiceManager == NULL) {
+ gDefaultServiceManager = interface_cast<IHwServiceManager>(
+ ProcessState::self()->getContextObject(NULL));
+ if (gDefaultServiceManager == NULL)
+ sleep(1);
+ }
+ }
+
+ return gDefaultServiceManager;
+}
+
+}; // namespace hardware
+}; // namespace android
diff --git a/transport/Static.cpp b/transport/Static.cpp
new file mode 100644
index 0000000..3bd0285
--- /dev/null
+++ b/transport/Static.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// All static variables go here, to control initialization and
+// destruction order in the library.
+
+#include <hidl/Static.h>
+
+namespace android {
+namespace hardware {
+
+Mutex gDefaultServiceManagerLock;
+sp<android::hidl::manager::V1_0::IServiceManager> gDefaultServiceManager;
+
+} // namespace hardware
+} // namespace android
diff --git a/transport/include/hidl/HidlBinderSupport.h b/transport/include/hidl/HidlBinderSupport.h
new file mode 100644
index 0000000..b4a2aa2
--- /dev/null
+++ b/transport/include/hidl/HidlBinderSupport.h
@@ -0,0 +1,393 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HIDL_BINDER_SUPPORT_H
+#define ANDROID_HIDL_BINDER_SUPPORT_H
+
+#include <hidl/HidlSupport.h>
+#include <hidl/MQDescriptor.h>
+#include <hwbinder/IBinder.h>
+#include <hwbinder/Parcel.h>
+
+// Defines functions for hidl_string, hidl_version, Status, hidl_vec, MQDescriptor,
+// etc. to interact with Parcel.
+
+namespace android {
+namespace hardware {
+
+// ---------------------- hidl_string
+
+status_t readEmbeddedFromParcel(hidl_string *string,
+ const Parcel &parcel, size_t parentHandle, size_t parentOffset);
+
+status_t writeEmbeddedToParcel(const hidl_string &string,
+ Parcel *parcel, size_t parentHandle, size_t parentOffset);
+
+// ---------------------- hidl_version
+
+status_t writeToParcel(const hidl_version &version, android::hardware::Parcel& parcel);
+
+// Caller is responsible for freeing the returned object.
+hidl_version* readFromParcel(const android::hardware::Parcel& parcel);
+
+// ---------------------- Status
+
+// Bear in mind that if the client or service is a Java endpoint, this
+// is not the logic which will provide/interpret the data here.
+status_t readFromParcel(Status *status, const Parcel& parcel);
+status_t writeToParcel(const Status &status, Parcel* parcel);
+
+// ---------------------- hidl_vec
+
+template<typename T>
+status_t readEmbeddedFromParcel(
+ hidl_vec<T> * /*vec*/,
+ const Parcel &parcel,
+ size_t parentHandle,
+ size_t parentOffset,
+ size_t *handle) {
+ const void *ptr = parcel.readEmbeddedBuffer(
+ handle,
+ parentHandle,
+ parentOffset + hidl_vec<T>::kOffsetOfBuffer);
+
+ return ptr != NULL ? OK : UNKNOWN_ERROR;
+}
+
+template<typename T>
+status_t writeEmbeddedToParcel(
+ const hidl_vec<T> &vec,
+ Parcel *parcel,
+ size_t parentHandle,
+ size_t parentOffset,
+ size_t *handle) {
+ return parcel->writeEmbeddedBuffer(
+ vec.data(),
+ sizeof(T) * vec.size(),
+ handle,
+ parentHandle,
+ parentOffset + hidl_vec<T>::kOffsetOfBuffer);
+}
+
+template<typename T>
+status_t findInParcel(const hidl_vec<T> &vec, const Parcel &parcel, size_t *handle) {
+ return parcel.quickFindBuffer(vec.data(), handle);
+}
+
+// ---------------------- MQDescriptor
+
+template<MQFlavor flavor>
+::android::status_t readEmbeddedFromParcel(
+ MQDescriptor<flavor> *obj,
+ const ::android::hardware::Parcel &parcel,
+ size_t parentHandle,
+ size_t parentOffset) {
+ ::android::status_t _hidl_err = ::android::OK;
+
+ size_t _hidl_grantors_child;
+
+ _hidl_err = ::android::hardware::readEmbeddedFromParcel(
+ &obj->grantors(),
+ parcel,
+ parentHandle,
+ parentOffset + MQDescriptor<flavor>::kOffsetOfGrantors,
+ &_hidl_grantors_child);
+
+ if (_hidl_err != ::android::OK) { return _hidl_err; }
+
+ const native_handle_t *_hidl_mq_handle_ptr = parcel.readEmbeddedNativeHandle(
+ parentHandle,
+ parentOffset + MQDescriptor<flavor>::kOffsetOfHandle);
+
+ if (_hidl_mq_handle_ptr == nullptr) {
+ _hidl_err = ::android::UNKNOWN_ERROR;
+ return _hidl_err;
+ }
+
+ return _hidl_err;
+}
+
+template<MQFlavor flavor>
+::android::status_t writeEmbeddedToParcel(
+ const MQDescriptor<flavor> &obj,
+ ::android::hardware::Parcel *parcel,
+ size_t parentHandle,
+ size_t parentOffset) {
+ ::android::status_t _hidl_err = ::android::OK;
+
+ size_t _hidl_grantors_child;
+
+ _hidl_err = ::android::hardware::writeEmbeddedToParcel(
+ obj.grantors(),
+ parcel,
+ parentHandle,
+ parentOffset + MQDescriptor<flavor>::kOffsetOfGrantors,
+ &_hidl_grantors_child);
+
+ if (_hidl_err != ::android::OK) { return _hidl_err; }
+
+ _hidl_err = parcel->writeEmbeddedNativeHandle(
+ obj.handle(),
+ parentHandle,
+ parentOffset + MQDescriptor<flavor>::kOffsetOfHandle);
+
+ if (_hidl_err != ::android::OK) { return _hidl_err; }
+
+ return _hidl_err;
+}
+
+// ---------------------- pointers for HIDL
+
+template <typename T>
+static status_t readEmbeddedReferenceFromParcel(
+ T const* * /* bufptr */,
+ const Parcel & parcel,
+ size_t parentHandle,
+ size_t parentOffset,
+ size_t *handle,
+ bool *shouldResolveRefInBuffer
+ ) {
+ // *bufptr is ignored because, if I am embedded in some
+ // other buffer, the kernel should have fixed me up already.
+ bool isPreviouslyWritten;
+ status_t result = parcel.readEmbeddedReference(
+ nullptr, // ignored, not written to bufptr.
+ handle,
+ parentHandle,
+ parentOffset,
+ &isPreviouslyWritten);
+ // tell caller to run T::readEmbeddedToParcel and
+ // T::readEmbeddedReferenceToParcel if necessary.
+ // It is not called here because we don't know if these two are valid methods.
+ *shouldResolveRefInBuffer = !isPreviouslyWritten;
+ return result;
+}
+
+template <typename T>
+static status_t writeEmbeddedReferenceToParcel(
+ T const* buf,
+ Parcel *parcel, size_t parentHandle, size_t parentOffset,
+ size_t *handle,
+ bool *shouldResolveRefInBuffer
+ ) {
+
+ if(buf == nullptr) {
+ *shouldResolveRefInBuffer = false;
+ return parcel->writeEmbeddedNullReference(handle, parentHandle, parentOffset);
+ }
+
+ // find whether the buffer exists
+ size_t childHandle, childOffset;
+ status_t result;
+ bool found;
+
+ result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);
+
+ // tell caller to run T::writeEmbeddedToParcel and
+ // T::writeEmbeddedReferenceToParcel if necessary.
+ // It is not called here because we don't know if these two are valid methods.
+ *shouldResolveRefInBuffer = !found;
+
+ if(result != OK) {
+ return result; // bad pointers and length given
+ }
+ if(!found) { // did not find it.
+ return parcel->writeEmbeddedBuffer(buf, sizeof(T), handle,
+ parentHandle, parentOffset);
+ }
+ // found the buffer. easy case.
+ return parcel->writeEmbeddedReference(
+ handle,
+ childHandle,
+ childOffset,
+ parentHandle,
+ parentOffset);
+}
+
+template <typename T>
+static status_t readReferenceFromParcel(
+ T const* *bufptr,
+ const Parcel & parcel,
+ size_t *handle,
+ bool *shouldResolveRefInBuffer
+ ) {
+ bool isPreviouslyWritten;
+ status_t result = parcel.readReference(reinterpret_cast<void const* *>(bufptr),
+ handle, &isPreviouslyWritten);
+ // tell caller to run T::readEmbeddedToParcel and
+ // T::readEmbeddedReferenceToParcel if necessary.
+ // It is not called here because we don't know if these two are valid methods.
+ *shouldResolveRefInBuffer = !isPreviouslyWritten;
+ return result;
+}
+
+template <typename T>
+static status_t writeReferenceToParcel(
+ T const *buf,
+ Parcel * parcel,
+ size_t *handle,
+ bool *shouldResolveRefInBuffer
+ ) {
+
+ if(buf == nullptr) {
+ *shouldResolveRefInBuffer = false;
+ return parcel->writeNullReference(handle);
+ }
+
+ // find whether the buffer exists
+ size_t childHandle, childOffset;
+ status_t result;
+ bool found;
+
+ result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);
+
+ // tell caller to run T::writeEmbeddedToParcel and
+ // T::writeEmbeddedReferenceToParcel if necessary.
+ // It is not called here because we don't know if these two are valid methods.
+ *shouldResolveRefInBuffer = !found;
+
+ if(result != OK) {
+ return result; // bad pointers and length given
+ }
+ if(!found) { // did not find it.
+ return parcel->writeBuffer(buf, sizeof(T), handle);
+ }
+ // found the buffer. easy case.
+ return parcel->writeReference(handle,
+ childHandle, childOffset);
+}
+
+// ---------------------- support for casting interfaces
+
+extern std::map<std::string, std::function<sp<IBinder>(void*)>> gBnConstructorMap;
+
+// Construct a smallest possible binder from the given interface.
+// If it is remote, then its remote() will be retrieved.
+// Otherwise, the smallest possible BnChild is found where IChild is a subclass of IType
+// and iface is of class IChild. BnChild will be used to wrapped the given iface.
+// Return nullptr if iface is null or any failure.
+template <typename IType, typename IHwType>
+sp<IBinder> toBinder(sp<IType> iface) {
+ IType *ifacePtr = iface.get();
+ if (ifacePtr == nullptr) {
+ return nullptr;
+ }
+ if (ifacePtr->isRemote()) {
+ return ::android::hardware::IInterface::asBinder(static_cast<IHwType *>(ifacePtr));
+ } else {
+ std::string myDescriptor{};
+ ifacePtr->interfaceChain([&](const hidl_vec<hidl_string> &types) {
+ if (types.size() > 0) {
+ myDescriptor = types[0].c_str();
+ }
+ });
+ if (myDescriptor.empty()) {
+ // interfaceChain fails || types.size() == 0
+ return nullptr;
+ }
+ auto iter = gBnConstructorMap.find(myDescriptor);
+ if (iter == gBnConstructorMap.end()) {
+ return nullptr;
+ }
+ return sp<IBinder>((iter->second)(reinterpret_cast<void *>(ifacePtr)));
+ }
+}
+
+#define IMPLEMENT_SERVICE_MANAGER_INTERACTIONS(INTERFACE, PACKAGE) \
+ ::android::sp<I##INTERFACE> I##INTERFACE::getService( \
+ const std::string &serviceName, bool getStub) \
+ { \
+ using ::android::sp; \
+ using ::android::hardware::defaultServiceManager; \
+ using ::android::hardware::IBinder; \
+ using ::android::hidl::manager::V1_0::IServiceManager; \
+ sp<I##INTERFACE> iface; \
+ const sp<IServiceManager> sm = defaultServiceManager(); \
+ if (sm != nullptr && !getStub) { \
+ sp<IBinder> binderIface; \
+ ::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 PACKAGE "-impl.so", dlMode); \
+ if (handle == nullptr) { \
+ handle = dlopen(HAL_LIBRARY_PATH_VENDOR PACKAGE "-impl.so", dlMode); \
+ } \
+ if (handle == nullptr) { \
+ handle = dlopen(HAL_LIBRARY_PATH_SYSTEM PACKAGE "-impl.so", 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()); \
+ if (iface != nullptr) { \
+ iface = new Bs##INTERFACE(iface); \
+ } \
+ } \
+ return iface; \
+ } \
+ ::android::status_t I##INTERFACE::registerAsService( \
+ const std::string &serviceName) \
+ { \
+ using ::android::sp; \
+ using ::android::hardware::defaultServiceManager; \
+ using ::android::hidl::manager::V1_0::IServiceManager; \
+ sp<Bn##INTERFACE> binderIface = new Bn##INTERFACE(this); \
+ const sp<IServiceManager> sm = defaultServiceManager(); \
+ 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; \
+ } \
+ bool I##INTERFACE::registerForNotifications( \
+ const std::string &serviceName, \
+ const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> \
+ ¬ification) \
+ { \
+ using ::android::sp; \
+ using ::android::hardware::defaultServiceManager; \
+ using ::android::hidl::manager::V1_0::IServiceManager; \
+ const sp<IServiceManager> sm = defaultServiceManager(); \
+ if (sm == nullptr) { \
+ return false; \
+ } \
+ return sm->registerForNotifications(PACKAGE "::I" #INTERFACE, \
+ serviceName, \
+ notification); \
+ }
+
+
+} // namespace hardware
+} // namespace android
+
+
+#endif // ANDROID_HIDL_BINDER_SUPPORT_H
diff --git a/transport/include/hidl/HidlTransportSupport.h b/transport/include/hidl/HidlTransportSupport.h
new file mode 100644
index 0000000..f8cae2e
--- /dev/null
+++ b/transport/include/hidl/HidlTransportSupport.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HIDL_TRANSPORT_SUPPORT_H
+#define ANDROID_HIDL_TRANSPORT_SUPPORT_H
+
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlBinderSupport.h>
+
+namespace android {
+namespace hardware {
+
+// cast the interface IParent to IChild.
+// Return nullptr if parent is null or any failure.
+template<typename IChild, typename IParent, typename BpChild, typename IHwParent>
+sp<IChild> castInterface(sp<IParent> parent, const char *childIndicator) {
+ if (parent.get() == nullptr) {
+ // casts always succeed with nullptrs.
+ return nullptr;
+ }
+ bool canCast = false;
+ parent->interfaceChain([&](const hidl_vec<hidl_string> &allowedCastTypes) {
+ for (size_t i = 0; i < allowedCastTypes.size(); i++) {
+ if (allowedCastTypes[i] == childIndicator) {
+ canCast = true;
+ break;
+ }
+ }
+ });
+
+ if (!canCast) {
+ return sp<IChild>(nullptr); // cast failed.
+ }
+ // TODO b/32001926 Needs to be fixed for socket mode.
+ if (parent->isRemote()) {
+ // binderized mode. Got BpChild. grab the remote and wrap it.
+ return sp<IChild>(new BpChild(toBinder<IParent, IHwParent>(parent)));
+ }
+ // Passthrough mode. Got BnChild and BsChild.
+ return sp<IChild>(static_cast<IChild *>(parent.get()));
+}
+
+} // namespace hardware
+} // namespace android
+
+
+#endif // ANDROID_HIDL_TRANSPORT_SUPPORT_H
diff --git a/transport/include/hidl/LegacySupport.h b/transport/include/hidl/LegacySupport.h
new file mode 100644
index 0000000..2ff1785
--- /dev/null
+++ b/transport/include/hidl/LegacySupport.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <utils/Log.h>
+
+#include <hwbinder/IPCThreadState.h>
+#include <hwbinder/ProcessState.h>
+#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
+
+#ifndef ANDROID_HIDL_LEGACY_SUPPORT_H
+#define ANDROID_HIDL_LEGACY_SUPPORT_H
+
+namespace android {
+namespace hardware {
+
+/**
+ * Registers passthrough service implementation.
+ */
+template<class Interface>
+status_t registerPassthroughServiceImplementation(std::string name) {
+ sp<Interface> service = Interface::getService(name, true /* getStub */);
+
+ if (service == nullptr) {
+ ALOGE("Could not get passthrough implementation for %s.", name.c_str());
+ return EXIT_FAILURE;
+ }
+
+ LOG_FATAL_IF(service->isRemote(), "Implementation of %s is remote!", name.c_str());
+
+ status_t status = service->registerAsService(name);
+
+ if (status == OK) {
+ ALOGI("Registration complete for %s.", name.c_str());
+ } else {
+ ALOGE("Could not register service %s (%d).", name.c_str(), status);
+ }
+
+ return status;
+}
+
+/**
+ * Launches the RPC threadpool. This method never returns.
+ *
+ * Return value is exit status.
+ */
+inline int launchRpcServer(size_t maxThreads) {
+ ProcessState::self()->setThreadPoolMaxThreadCount(maxThreads);
+ ProcessState::self()->startThreadPool();
+ IPCThreadState::self()->joinThreadPool();
+
+ return 0;
+}
+
+/**
+ * Creates default passthrough service implementation. This method never returns.
+ *
+ * Return value is exit status.
+ */
+template<class Interface>
+int defaultPassthroughServiceImplementation(std::string name) {
+ registerPassthroughServiceImplementation<Interface>(name);
+ return launchRpcServer(0);
+}
+
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HIDL_LEGACY_SUPPORT_H
diff --git a/transport/include/hidl/ServiceManagement.h b/transport/include/hidl/ServiceManagement.h
new file mode 100644
index 0000000..51faf0b
--- /dev/null
+++ b/transport/include/hidl/ServiceManagement.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_ISERVICE_MANAGER_H
+#define ANDROID_HARDWARE_ISERVICE_MANAGER_H
+
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+namespace hidl {
+namespace manager {
+namespace V1_0 {
+ struct IServiceManager;
+}; // namespace V1_0
+}; // namespace manager
+}; // namespace hidl
+
+namespace hardware {
+
+sp<::android::hidl::manager::V1_0::IServiceManager> defaultServiceManager();
+
+}; // namespace hardware
+}; // namespace android
+
+#endif // ANDROID_HARDWARE_ISERVICE_MANAGER_H
+
diff --git a/transport/include/hidl/Static.h b/transport/include/hidl/Static.h
new file mode 100644
index 0000000..00db8a7
--- /dev/null
+++ b/transport/include/hidl/Static.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// All static variables go here, to control initialization and
+// destruction order in the library.
+
+#include <utils/threads.h>
+#include <android/hidl/manager/1.0/IServiceManager.h>
+
+namespace android {
+namespace hardware {
+
+// For ServiceManagement.cpp
+extern Mutex gDefaultServiceManagerLock;
+extern sp<android::hidl::manager::V1_0::IServiceManager> gDefaultServiceManager;
+
+} // namespace hardware
+} // namespace android
diff --git a/transport/manager/1.0/Android.bp b/transport/manager/1.0/Android.bp
new file mode 100644
index 0000000..9cea8aa
--- /dev/null
+++ b/transport/manager/1.0/Android.bp
@@ -0,0 +1,57 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+genrule {
+ name: "android.hidl.manager@1.0_genc++",
+ tools: ["hidl-gen"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hidl:system/libhidl/transport android.hidl.manager@1.0",
+ srcs: [
+ "IServiceManager.hal",
+ "IServiceNotification.hal",
+ ],
+ out: [
+ "android/hidl/manager/1.0/ServiceManagerAll.cpp",
+ "android/hidl/manager/1.0/ServiceNotificationAll.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hidl.manager@1.0_genc++_headers",
+ tools: ["hidl-gen"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hidl:system/libhidl/transport android.hidl.manager@1.0",
+ srcs: [
+ "IServiceManager.hal",
+ "IServiceNotification.hal",
+ ],
+ out: [
+ "android/hidl/manager/1.0/IServiceManager.h",
+ "android/hidl/manager/1.0/IHwServiceManager.h",
+ "android/hidl/manager/1.0/BnServiceManager.h",
+ "android/hidl/manager/1.0/BpServiceManager.h",
+ "android/hidl/manager/1.0/BsServiceManager.h",
+ "android/hidl/manager/1.0/IServiceNotification.h",
+ "android/hidl/manager/1.0/IHwServiceNotification.h",
+ "android/hidl/manager/1.0/BnServiceNotification.h",
+ "android/hidl/manager/1.0/BpServiceNotification.h",
+ "android/hidl/manager/1.0/BsServiceNotification.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hidl.manager@1.0",
+ generated_sources: ["android.hidl.manager@1.0_genc++"],
+ generated_headers: ["android.hidl.manager@1.0_genc++_headers"],
+ export_generated_headers: ["android.hidl.manager@1.0_genc++_headers"],
+ shared_libs: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libutils",
+ "libcutils",
+ ],
+ export_shared_lib_headers: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libutils",
+ ],
+}
diff --git a/transport/manager/1.0/Android.mk b/transport/manager/1.0/Android.mk
new file mode 100644
index 0000000..9721993
--- /dev/null
+++ b/transport/manager/1.0/Android.mk
@@ -0,0 +1,102 @@
+# This file is autogenerated by hidl-gen. Do not edit manually.
+
+LOCAL_PATH := $(call my-dir)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hidl.manager@1.0-java
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(local-generated-sources-dir)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+#
+# Build IServiceManager.hal
+#
+GEN := $(intermediates)/android/hidl/manager/1.0/IServiceManager.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IServiceManager.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/IServiceNotification.hal
+$(GEN): $(LOCAL_PATH)/IServiceNotification.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava -randroid.hidl:system/libhidl/transport \
+ android.hidl.manager@1.0::IServiceManager
+
+$(GEN): $(LOCAL_PATH)/IServiceManager.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build IServiceNotification.hal
+#
+GEN := $(intermediates)/android/hidl/manager/1.0/IServiceNotification.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IServiceNotification.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava -randroid.hidl:system/libhidl/transport \
+ android.hidl.manager@1.0::IServiceNotification
+
+$(GEN): $(LOCAL_PATH)/IServiceNotification.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_JAVA_LIBRARY)
+
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hidl.manager@1.0-java-static
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(local-generated-sources-dir)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+#
+# Build IServiceManager.hal
+#
+GEN := $(intermediates)/android/hidl/manager/1.0/IServiceManager.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IServiceManager.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/IServiceNotification.hal
+$(GEN): $(LOCAL_PATH)/IServiceNotification.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava -randroid.hidl:system/libhidl/transport \
+ android.hidl.manager@1.0::IServiceManager
+
+$(GEN): $(LOCAL_PATH)/IServiceManager.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build IServiceNotification.hal
+#
+GEN := $(intermediates)/android/hidl/manager/1.0/IServiceNotification.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IServiceNotification.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava -randroid.hidl:system/libhidl/transport \
+ android.hidl.manager@1.0::IServiceNotification
+
+$(GEN): $(LOCAL_PATH)/IServiceNotification.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/transport/manager/1.0/IServiceManager.hal b/transport/manager/1.0/IServiceManager.hal
new file mode 100644
index 0000000..0fcf7dc
--- /dev/null
+++ b/transport/manager/1.0/IServiceManager.hal
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hidl.manager@1.0;
+
+import IServiceNotification;
+
+/**
+ * Manages all the hidl hals on a device.
+ *
+ * All examples in this file assume that there is one service registered with
+ * the service manager, "android.hidl.manager@1.0::IServiceManager/manager"
+ *
+ * Terminology:
+ * Package: "android.hidl.manager"
+ * Major version: "1"
+ * Minor version: "0"
+ * Version: "1.0"
+ * Interface name: "IServiceManager"
+ * Fully-qualified interface name: "android.hidl.manager@1.0::IServiceManager"
+ * Instance name: "manager"
+ * Fully-qualified instance name: "android.hidl.manager@1.0::IServiceManager/manager"
+ */
+interface IServiceManager {
+
+ /**
+ * Retrieve an existing service that supports the requested version.
+ *
+ * WARNING: This function is for libhidl/HwBinder use only. You are likely
+ * looking for 'IMyInterface::getService("name")' instead.
+ *
+ * @param iface Fully-qualified interface name.
+ * @param name Instance name. Same as in IServiceManager::add.
+ *
+ * @return service Handle to requested service, same as provided in
+ * IServiceManager::add. Will be nullptr if not available.
+ */
+ get(string fqName, string name) generates (interface service);
+
+ /**
+ * Register a service. The service manager must be registered as all of the
+ * services that it inherits from.
+ *
+ * WARNING: This function is for libhidl/HwBinder use only. You are likely
+ * looking for 'INTERFACE::registerAsService("name")' instead.
+ *
+ * @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 Instance name. Must also be used to retrieve service.
+ * @param service Handle to registering service.
+ *
+ * @return success Whether or not the service was registered.
+ *
+ */
+ add(vec<string> interfaceChain, string name, interface service)
+ generates (bool success);
+
+ /**
+ * List all registered services.
+ *
+ * @return fqInstanceNames List of fully-qualified instance names.
+ */
+ list() generates (vec<string> fqInstanceNames);
+
+ /**
+ * List all instances of a particular service.
+ *
+ * @param fqName Fully-qualified interface name.
+ *
+ * @return instanceNames List of instance names running the particular service.
+ */
+ listByInterface(string fqName) generates (vec<string> instanceNames);
+
+ /**
+ * Register for service notifications for a particular service. Must support
+ * multiple registrations.
+ *
+ * onRegistration must be sent out for all services which support the
+ * version provided in the fqName. For instance, if a client registers for
+ * notifications from "android.hardware.foo@1.0", they must also get
+ * notifications from "android.hardware.foo@1.1". If a matching service
+ * is already registered, onRegistration must be sent out with preexisting
+ * = true.
+ *
+ * @param fqName Fully-qualified interface name.
+ * @param name Instance name. If name is empty, notifications must be
+ * sent out for all names.
+ * @param callback Client callback to recieve notifications.
+ *
+ * @return success Whether or not registration was successful.
+ */
+ registerForNotifications(string fqName,
+ string name,
+ IServiceNotification callback)
+ generates (bool success);
+};
\ No newline at end of file
diff --git a/transport/manager/1.0/IServiceNotification.hal b/transport/manager/1.0/IServiceNotification.hal
new file mode 100644
index 0000000..a6151e3
--- /dev/null
+++ b/transport/manager/1.0/IServiceNotification.hal
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hidl.manager@1.0;
+
+interface IServiceNotification {
+
+ /**
+ * Must be called when a service is registered.
+ *
+ * @param fqInstanceName Fully-qualified instance name (see IServiceManager)
+ * @param preexisting If true, this means the registration was
+ * pre-existing at the time this IServiceNotification
+ * object is itself registered. Otherwise, this means
+ * onRegistration is triggered by a newly registered
+ * service.
+ */
+ oneway onRegistration(string fqName, string name, bool preexisting);
+
+
+};
\ No newline at end of file
diff --git a/transport/manager/1.0/update-makefiles.sh b/transport/manager/1.0/update-makefiles.sh
new file mode 100755
index 0000000..850ca7b
--- /dev/null
+++ b/transport/manager/1.0/update-makefiles.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+if [ ! -d system/libhidl ] ; then
+ echo "Where is system/libhidl?";
+ exit 1;
+fi
+
+hidl-gen -Lmakefile -r android.hidl:system/libhidl/transport android.hidl.manager@1.0
+hidl-gen -Landroidbp -r android.hidl:system/libhidl/transport android.hidl.manager@1.0