HidlBinderSupport.h revision 7f97f44562b057c3c780c0a05c101b677f9b0f96
17f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong/* 27f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong * Copyright (C) 2016 The Android Open Source Project 37f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong * 47f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong * Licensed under the Apache License, Version 2.0 (the "License"); 57f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong * you may not use this file except in compliance with the License. 67f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong * You may obtain a copy of the License at 77f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong * 87f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong * http://www.apache.org/licenses/LICENSE-2.0 97f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong * 107f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong * Unless required by applicable law or agreed to in writing, software 117f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong * distributed under the License is distributed on an "AS IS" BASIS, 127f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong * See the License for the specific language governing permissions and 147f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong * limitations under the License. 157f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong */ 167f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 177f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#ifndef ANDROID_HIDL_BINDER_SUPPORT_H 187f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#define ANDROID_HIDL_BINDER_SUPPORT_H 197f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 207f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#include <hidl/HidlSupport.h> 217f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#include <hidl/MQDescriptor.h> 227f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#include <hwbinder/IBinder.h> 237f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#include <hwbinder/Parcel.h> 247f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 257f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Defines functions for hidl_string, hidl_version, Status, hidl_vec, MQDescriptor, 267f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// etc. to interact with Parcel. 277f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 287f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongnamespace android { 297f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongnamespace hardware { 307f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 317f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- hidl_string 327f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 337f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t readEmbeddedFromParcel(hidl_string *string, 347f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const Parcel &parcel, size_t parentHandle, size_t parentOffset); 357f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 367f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t writeEmbeddedToParcel(const hidl_string &string, 377f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong Parcel *parcel, size_t parentHandle, size_t parentOffset); 387f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 397f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- hidl_version 407f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 417f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t writeToParcel(const hidl_version &version, android::hardware::Parcel& parcel); 427f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 437f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Caller is responsible for freeing the returned object. 447f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Honghidl_version* readFromParcel(const android::hardware::Parcel& parcel); 457f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 467f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- Status 477f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 487f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Bear in mind that if the client or service is a Java endpoint, this 497f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// is not the logic which will provide/interpret the data here. 507f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t readFromParcel(Status *status, const Parcel& parcel); 517f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t writeToParcel(const Status &status, Parcel* parcel); 527f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 537f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- hidl_vec 547f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 557f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate<typename T> 567f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t readEmbeddedFromParcel( 577f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong hidl_vec<T> * /*vec*/, 587f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const Parcel &parcel, 597f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentHandle, 607f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentOffset, 617f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle) { 627f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const void *ptr = parcel.readEmbeddedBuffer( 637f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle, 647f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 657f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset + hidl_vec<T>::kOffsetOfBuffer); 667f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 677f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return ptr != NULL ? OK : UNKNOWN_ERROR; 687f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 697f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 707f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate<typename T> 717f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t writeEmbeddedToParcel( 727f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const hidl_vec<T> &vec, 737f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong Parcel *parcel, 747f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentHandle, 757f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentOffset, 767f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle) { 777f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeEmbeddedBuffer( 787f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong vec.data(), 797f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong sizeof(T) * vec.size(), 807f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle, 817f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 827f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset + hidl_vec<T>::kOffsetOfBuffer); 837f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 847f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 857f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate<typename T> 867f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t findInParcel(const hidl_vec<T> &vec, const Parcel &parcel, size_t *handle) { 877f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel.quickFindBuffer(vec.data(), handle); 887f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 897f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 907f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- MQDescriptor 917f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 927f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate<MQFlavor flavor> 937f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong::android::status_t readEmbeddedFromParcel( 947f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong MQDescriptor<flavor> *obj, 957f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const ::android::hardware::Parcel &parcel, 967f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentHandle, 977f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentOffset) { 987f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ::android::status_t _hidl_err = ::android::OK; 997f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1007f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t _hidl_grantors_child; 1017f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1027f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong _hidl_err = ::android::hardware::readEmbeddedFromParcel( 1037f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong &obj->grantors(), 1047f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parcel, 1057f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 1067f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset + MQDescriptor<flavor>::kOffsetOfGrantors, 1077f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong &_hidl_grantors_child); 1087f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1097f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (_hidl_err != ::android::OK) { return _hidl_err; } 1107f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1117f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const native_handle_t *_hidl_mq_handle_ptr = parcel.readEmbeddedNativeHandle( 1127f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 1137f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset + MQDescriptor<flavor>::kOffsetOfHandle); 1147f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1157f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (_hidl_mq_handle_ptr == nullptr) { 1167f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong _hidl_err = ::android::UNKNOWN_ERROR; 1177f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return _hidl_err; 1187f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 1197f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1207f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return _hidl_err; 1217f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 1227f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1237f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate<MQFlavor flavor> 1247f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong::android::status_t writeEmbeddedToParcel( 1257f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const MQDescriptor<flavor> &obj, 1267f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ::android::hardware::Parcel *parcel, 1277f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentHandle, 1287f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentOffset) { 1297f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ::android::status_t _hidl_err = ::android::OK; 1307f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1317f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t _hidl_grantors_child; 1327f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1337f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong _hidl_err = ::android::hardware::writeEmbeddedToParcel( 1347f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong obj.grantors(), 1357f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parcel, 1367f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 1377f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset + MQDescriptor<flavor>::kOffsetOfGrantors, 1387f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong &_hidl_grantors_child); 1397f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1407f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (_hidl_err != ::android::OK) { return _hidl_err; } 1417f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1427f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong _hidl_err = parcel->writeEmbeddedNativeHandle( 1437f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong obj.handle(), 1447f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 1457f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset + MQDescriptor<flavor>::kOffsetOfHandle); 1467f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1477f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (_hidl_err != ::android::OK) { return _hidl_err; } 1487f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1497f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return _hidl_err; 1507f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 1517f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1527f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- pointers for HIDL 1537f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1547f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate <typename T> 1557f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatic status_t readEmbeddedReferenceFromParcel( 1567f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong T const* * /* bufptr */, 1577f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const Parcel & parcel, 1587f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentHandle, 1597f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentOffset, 1607f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle, 1617f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool *shouldResolveRefInBuffer 1627f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ) { 1637f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // *bufptr is ignored because, if I am embedded in some 1647f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // other buffer, the kernel should have fixed me up already. 1657f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool isPreviouslyWritten; 1667f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong status_t result = parcel.readEmbeddedReference( 1677f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong nullptr, // ignored, not written to bufptr. 1687f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle, 1697f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 1707f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset, 1717f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong &isPreviouslyWritten); 1727f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // tell caller to run T::readEmbeddedToParcel and 1737f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // T::readEmbeddedReferenceToParcel if necessary. 1747f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // It is not called here because we don't know if these two are valid methods. 1757f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = !isPreviouslyWritten; 1767f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return result; 1777f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 1787f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1797f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate <typename T> 1807f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatic status_t writeEmbeddedReferenceToParcel( 1817f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong T const* buf, 1827f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong Parcel *parcel, size_t parentHandle, size_t parentOffset, 1837f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle, 1847f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool *shouldResolveRefInBuffer 1857f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ) { 1867f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1877f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(buf == nullptr) { 1887f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = false; 1897f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeEmbeddedNullReference(handle, parentHandle, parentOffset); 1907f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 1917f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1927f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // find whether the buffer exists 1937f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t childHandle, childOffset; 1947f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong status_t result; 1957f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool found; 1967f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1977f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset); 1987f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1997f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // tell caller to run T::writeEmbeddedToParcel and 2007f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // T::writeEmbeddedReferenceToParcel if necessary. 2017f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // It is not called here because we don't know if these two are valid methods. 2027f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = !found; 2037f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2047f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(result != OK) { 2057f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return result; // bad pointers and length given 2067f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2077f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(!found) { // did not find it. 2087f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeEmbeddedBuffer(buf, sizeof(T), handle, 2097f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, parentOffset); 2107f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2117f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // found the buffer. easy case. 2127f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeEmbeddedReference( 2137f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle, 2147f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong childHandle, 2157f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong childOffset, 2167f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 2177f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset); 2187f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 2197f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2207f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate <typename T> 2217f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatic status_t readReferenceFromParcel( 2227f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong T const* *bufptr, 2237f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const Parcel & parcel, 2247f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle, 2257f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool *shouldResolveRefInBuffer 2267f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ) { 2277f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool isPreviouslyWritten; 2287f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong status_t result = parcel.readReference(reinterpret_cast<void const* *>(bufptr), 2297f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle, &isPreviouslyWritten); 2307f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // tell caller to run T::readEmbeddedToParcel and 2317f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // T::readEmbeddedReferenceToParcel if necessary. 2327f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // It is not called here because we don't know if these two are valid methods. 2337f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = !isPreviouslyWritten; 2347f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return result; 2357f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 2367f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2377f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate <typename T> 2387f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatic status_t writeReferenceToParcel( 2397f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong T const *buf, 2407f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong Parcel * parcel, 2417f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle, 2427f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool *shouldResolveRefInBuffer 2437f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ) { 2447f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2457f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(buf == nullptr) { 2467f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = false; 2477f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeNullReference(handle); 2487f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2497f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2507f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // find whether the buffer exists 2517f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t childHandle, childOffset; 2527f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong status_t result; 2537f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool found; 2547f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2557f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset); 2567f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2577f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // tell caller to run T::writeEmbeddedToParcel and 2587f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // T::writeEmbeddedReferenceToParcel if necessary. 2597f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // It is not called here because we don't know if these two are valid methods. 2607f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = !found; 2617f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2627f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(result != OK) { 2637f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return result; // bad pointers and length given 2647f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2657f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(!found) { // did not find it. 2667f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeBuffer(buf, sizeof(T), handle); 2677f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2687f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // found the buffer. easy case. 2697f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeReference(handle, 2707f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong childHandle, childOffset); 2717f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 2727f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2737f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- support for casting interfaces 2747f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2757f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongextern std::map<std::string, std::function<sp<IBinder>(void*)>> gBnConstructorMap; 2767f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2777f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Construct a smallest possible binder from the given interface. 2787f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// If it is remote, then its remote() will be retrieved. 2797f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Otherwise, the smallest possible BnChild is found where IChild is a subclass of IType 2807f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// and iface is of class IChild. BnChild will be used to wrapped the given iface. 2817f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Return nullptr if iface is null or any failure. 2827f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate <typename IType, typename IHwType> 2837f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongsp<IBinder> toBinder(sp<IType> iface) { 2847f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong IType *ifacePtr = iface.get(); 2857f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (ifacePtr == nullptr) { 2867f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return nullptr; 2877f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2887f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (ifacePtr->isRemote()) { 2897f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return ::android::hardware::IInterface::asBinder(static_cast<IHwType *>(ifacePtr)); 2907f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } else { 2917f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong std::string myDescriptor{}; 2927f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ifacePtr->interfaceChain([&](const hidl_vec<hidl_string> &types) { 2937f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (types.size() > 0) { 2947f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong myDescriptor = types[0].c_str(); 2957f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2967f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong }); 2977f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (myDescriptor.empty()) { 2987f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // interfaceChain fails || types.size() == 0 2997f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return nullptr; 3007f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 3017f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong auto iter = gBnConstructorMap.find(myDescriptor); 3027f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (iter == gBnConstructorMap.end()) { 3037f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return nullptr; 3047f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 3057f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return sp<IBinder>((iter->second)(reinterpret_cast<void *>(ifacePtr))); 3067f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 3077f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 3087f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 3097f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#define IMPLEMENT_SERVICE_MANAGER_INTERACTIONS(INTERFACE, PACKAGE) \ 3107f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ::android::sp<I##INTERFACE> I##INTERFACE::getService( \ 3117f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const std::string &serviceName, bool getStub) \ 3127f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong { \ 3137f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong using ::android::sp; \ 3147f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong using ::android::hardware::defaultServiceManager; \ 3157f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong using ::android::hardware::IBinder; \ 3167f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong using ::android::hidl::manager::V1_0::IServiceManager; \ 3177f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong sp<I##INTERFACE> iface; \ 3187f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const sp<IServiceManager> sm = defaultServiceManager(); \ 3197f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (sm != nullptr && !getStub) { \ 3207f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong sp<IBinder> binderIface; \ 3217f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ::android::hardware::Return<void> ret = \ 3227f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong sm->get(PACKAGE "::I" #INTERFACE, serviceName.c_str(), \ 3237f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong [&binderIface](sp<IBinder> iface) { \ 3247f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong binderIface = iface; \ 3257f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong }); \ 3267f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (ret.getStatus().isOk()) { \ 3277f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong iface = IHw##INTERFACE::asInterface(binderIface); \ 3287f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (iface != nullptr) { \ 3297f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return iface; \ 3307f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } \ 3317f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } \ 3327f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } \ 3337f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong int dlMode = RTLD_LAZY; \ 3347f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong void *handle = dlopen(HAL_LIBRARY_PATH_ODM PACKAGE "-impl.so", dlMode); \ 3357f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (handle == nullptr) { \ 3367f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle = dlopen(HAL_LIBRARY_PATH_VENDOR PACKAGE "-impl.so", dlMode); \ 3377f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } \ 3387f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (handle == nullptr) { \ 3397f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle = dlopen(HAL_LIBRARY_PATH_SYSTEM PACKAGE "-impl.so", dlMode); \ 3407f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } \ 3417f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (handle == nullptr) { \ 3427f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return iface; \ 3437f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } \ 3447f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong I##INTERFACE* (*generator)(const char* name); \ 3457f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *(void **)(&generator) = dlsym(handle, "HIDL_FETCH_I"#INTERFACE); \ 3467f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (generator) { \ 3477f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong iface = (*generator)(serviceName.c_str()); \ 3487f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (iface != nullptr) { \ 3497f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong iface = new Bs##INTERFACE(iface); \ 3507f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } \ 3517f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } \ 3527f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return iface; \ 3537f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } \ 3547f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ::android::status_t I##INTERFACE::registerAsService( \ 3557f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const std::string &serviceName) \ 3567f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong { \ 3577f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong using ::android::sp; \ 3587f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong using ::android::hardware::defaultServiceManager; \ 3597f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong using ::android::hidl::manager::V1_0::IServiceManager; \ 3607f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong sp<Bn##INTERFACE> binderIface = new Bn##INTERFACE(this); \ 3617f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const sp<IServiceManager> sm = defaultServiceManager(); \ 3627f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool success = false; \ 3637f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ::android::hardware::Return<void> ret = \ 3647f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong this->interfaceChain( \ 3657f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong [&success, &sm, &serviceName, &binderIface](const auto &chain) { \ 3667f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong success = sm->add(chain, serviceName.c_str(), binderIface); \ 3677f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong }); \ 3687f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong success = success && ret.getStatus().isOk(); \ 3697f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return success ? ::android::OK : ::android::UNKNOWN_ERROR; \ 3707f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } \ 3717f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool I##INTERFACE::registerForNotifications( \ 3727f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const std::string &serviceName, \ 3737f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> \ 3747f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ¬ification) \ 3757f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong { \ 3767f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong using ::android::sp; \ 3777f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong using ::android::hardware::defaultServiceManager; \ 3787f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong using ::android::hidl::manager::V1_0::IServiceManager; \ 3797f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const sp<IServiceManager> sm = defaultServiceManager(); \ 3807f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (sm == nullptr) { \ 3817f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return false; \ 3827f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } \ 3837f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return sm->registerForNotifications(PACKAGE "::I" #INTERFACE, \ 3847f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong serviceName, \ 3857f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong notification); \ 3867f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 3877f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 3887f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 3897f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} // namespace hardware 3907f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} // namespace android 3917f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 3927f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 3937f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#endif // ANDROID_HIDL_BINDER_SUPPORT_H 394