summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYifan Hong <elsk@google.com>2016-11-14 18:31:05 -0800
committerYifan Hong <elsk@google.com>2016-11-16 19:00:17 +0000
commit7f97f44562b057c3c780c0a05c101b677f9b0f96 (patch)
tree3e0d589cad0b9af04e86dc053b92d869f671f9ff
parentb69926a728aa472be47f51dc5fc374571d7da5a8 (diff)
downloadlibhidl-7f97f44562b057c3c780c0a05c101b677f9b0f96.tar.gz
Separate HidlSupport.h to HidlSupportTransport.h
This is the preparation step to remove libhwbinder dependency from libhidl, because IBinder in libhwbinder needs to depend on IBase in libhidl. We would change libhidl depends on libhwbinder to libhwbinder depends on libhidl in follow-up CLs. This CL separates the code in libhidl that depends on libhwbinder out. Test: mma Test: hidl_test Bug: 32756130 Change-Id: I042c00605475f9aaa7e05ccc0260e6212854181d
-rw-r--r--Android.bp1
-rw-r--r--HidlBinderSupport.cpp145
-rw-r--r--HidlSupport.cpp24
-rw-r--r--Status.cpp69
-rw-r--r--include/hidl/HidlBinderSupport.h393
-rw-r--r--include/hidl/HidlSupport.h320
-rw-r--r--include/hidl/HidlTransportSupport.h60
-rw-r--r--include/hidl/MQDescriptor.h60
-rw-r--r--include/hidl/Status.h6
9 files changed, 600 insertions, 478 deletions
diff --git a/Android.bp b/Android.bp
index 6b08c87..87bee79 100644
--- a/Android.bp
+++ b/Android.bp
@@ -44,6 +44,7 @@ cc_library_shared {
srcs: [
"HidlSupport.cpp",
+ "HidlBinderSupport.cpp",
"ServiceManagement.cpp",
"Static.cpp",
"Status.cpp",
diff --git a/HidlBinderSupport.cpp b/HidlBinderSupport.cpp
new file mode 100644
index 0000000..c206018
--- /dev/null
+++ b/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/HidlSupport.cpp b/HidlSupport.cpp
index edab4de..8c5ac17 100644
--- a/HidlSupport.cpp
+++ b/HidlSupport.cpp
@@ -29,7 +29,6 @@ namespace android {
namespace hardware {
static const char *const kEmptyString = "";
-std::map<std::string, std::function<sp<IBinder>(void*)>> gBnConstructorMap{};
hidl_string::hidl_string()
: mBuffer(kEmptyString),
@@ -146,29 +145,6 @@ bool hidl_string::empty() const {
return mSize == 0;
}
-// 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);
-}
-
const char* IBase::descriptor = "android.hardware.base@0.0::IBase";
// ----------------------------------------------------------------------
diff --git a/Status.cpp b/Status.cpp
index 0a9f513..f018918 100644
--- a/Status.cpp
+++ b/Status.cpp
@@ -56,75 +56,6 @@ Status::Status(int32_t exceptionCode, int32_t errorCode, const String8& message)
mErrorCode(errorCode),
mMessage(message) {}
-status_t Status::readFromParcel(const Parcel& parcel) {
- status_t status = parcel.readInt32(&mException);
- if (status != OK) {
- setFromStatusT(status);
- return status;
- }
-
- // Skip over fat response headers. Not used (or propagated) in native code.
- if (mException == 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) {
- 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.
- mException = EX_NONE;
- }
-
- if (mException == EX_NONE) {
- return status;
- }
-
- // The remote threw an exception. Get the message back.
- String16 message;
- status = parcel.readString16(&message);
- if (status != OK) {
- setFromStatusT(status);
- return status;
- }
- mMessage = String8(message);
-
- if (mException == EX_SERVICE_SPECIFIC) {
- status = parcel.readInt32(&mErrorCode);
- }
- if (status != OK) {
- setFromStatusT(status);
- return status;
- }
-
- return status;
-}
-
-status_t Status::writeToParcel(Parcel* parcel) const {
- // Something really bad has happened, and we're not going to even
- // try returning rich error data.
- if (mException == EX_TRANSACTION_FAILED) {
- return mErrorCode;
- }
-
- status_t status = parcel->writeInt32(mException);
- if (status != OK) { return status; }
- if (mException == EX_NONE) {
- // We have no more information to write.
- return status;
- }
- status = parcel->writeString16(String16(mMessage));
- if (mException != EX_SERVICE_SPECIFIC) {
- // We have no more information to write.
- return status;
- }
- status = parcel->writeInt32(mErrorCode);
- return status;
-}
-
void Status::setException(int32_t ex, const String8& message) {
mException = ex;
mErrorCode = NO_ERROR; // an exception, not a transaction failure.
diff --git a/include/hidl/HidlBinderSupport.h b/include/hidl/HidlBinderSupport.h
new file mode 100644
index 0000000..b4a2aa2
--- /dev/null
+++ b/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> \
+ &notification) \
+ { \
+ 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/include/hidl/HidlSupport.h b/include/hidl/HidlSupport.h
index 4e63613..48cfd26 100644
--- a/include/hidl/HidlSupport.h
+++ b/include/hidl/HidlSupport.h
@@ -23,13 +23,12 @@
#include <cutils/properties.h>
#include <functional>
#include <hidl/Status.h>
-#include <hwbinder/IBinder.h>
-#include <hwbinder/Parcel.h>
#include <map>
#include <tuple>
#include <utils/Errors.h>
#include <utils/RefBase.h>
#include <utils/StrongPointer.h>
+#include <vector>
namespace android {
namespace hardware {
@@ -88,12 +87,6 @@ private:
void moveFrom(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);
-
inline bool operator==(const hidl_string &hs, const char *s) {
return strcmp(hs.c_str(), s) == 0;
}
@@ -247,10 +240,6 @@ struct hidl_vec {
mOwnsBuffer = true;
}
- status_t findInParcel(const Parcel &parcel, size_t *handle) const {
- return parcel.quickFindBuffer(mBuffer, handle);
- }
-
// offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
static const size_t kOffsetOfBuffer;
private:
@@ -277,36 +266,6 @@ private:
template <typename T>
const size_t hidl_vec<T>::kOffsetOfBuffer = offsetof(hidl_vec<T>, mBuffer);
-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);
-}
-
////////////////////////////////////////////////////////////////////////////////
namespace details {
@@ -431,127 +390,6 @@ private:
T mBuffer[SIZE1];
};
-///////////////////////////// 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);
-}
-
// ----------------------------------------------------------------------
// Version functions
struct hidl_version {
@@ -565,20 +403,6 @@ public:
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(static_cast<uint32_t>(mMajor) << 16 | mMinor);
- }
-
- static 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);
- }
- }
-
private:
uint16_t mMajor;
uint16_t mMinor;
@@ -597,69 +421,6 @@ struct IBase : virtual public RefBase {
static const char* descriptor;
};
-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)));
- }
-}
-
-// 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.
- }
- 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()));
-}
-
#if defined(__LP64__)
#define HAL_LIBRARY_PATH_SYSTEM "/system/lib64/hw/"
#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib64/hw/"
@@ -679,85 +440,6 @@ sp<IChild> castInterface(sp<IParent> parent, const char *childIndicator) {
const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> \
&notification); \
-#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> \
- &notification) \
- { \
- 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); \
- }
-
// ----------------------------------------------------------------------
// Class that provides Hidl instrumentation utilities.
struct HidlInstrumentor {
diff --git a/include/hidl/HidlTransportSupport.h b/include/hidl/HidlTransportSupport.h
new file mode 100644
index 0000000..f8cae2e
--- /dev/null
+++ b/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/include/hidl/MQDescriptor.h b/include/hidl/MQDescriptor.h
index f323834..8292035 100644
--- a/include/hidl/MQDescriptor.h
+++ b/include/hidl/MQDescriptor.h
@@ -194,66 +194,6 @@ MQDescriptor<flavor>::~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;
-}
-
-template<MQFlavor flavor>
size_t MQDescriptor<flavor>::getSize() const {
return mGrantors[DATAPTRPOS].extent;
}
diff --git a/include/hidl/Status.h b/include/hidl/Status.h
index 6dde65c..248d51c 100644
--- a/include/hidl/Status.h
+++ b/include/hidl/Status.h
@@ -20,7 +20,6 @@
#include <cstdint>
#include <sstream>
-#include <hwbinder/Parcel.h>
#include <utils/String8.h>
#include <android-base/macros.h>
@@ -98,11 +97,6 @@ public:
Status(Status&& status) = default;
Status& operator=(const Status& status) = default;
- // 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(const Parcel& parcel);
- status_t writeToParcel(Parcel* parcel) const;
-
// Set one of the pre-defined exception types defined above.
void setException(int32_t ex, const String8& message);
// Set a service specific exception with error code.