HidlBinderSupport.h revision 12f04d913dae2fb287089f6db24f144731c79d9c
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> 2112f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen#include <hidl/HidlTransportUtils.h> 227f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#include <hidl/MQDescriptor.h> 23b2c9c75b74c87e651dd08a100015eab17319556eYifan Hong#include <hidl/Static.h> 247f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#include <hwbinder/IBinder.h> 257f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#include <hwbinder/Parcel.h> 2612f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen#include <android/hidl/base/1.0/BnBase.h> 277f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Defines functions for hidl_string, hidl_version, Status, hidl_vec, MQDescriptor, 287f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// etc. to interact with Parcel. 297f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 307f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongnamespace android { 317f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongnamespace hardware { 327f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 333079100878a2595be644d866e67c12a9de620fd5Martijn Coenen// ---------------------- hidl_memory 343079100878a2595be644d866e67c12a9de620fd5Martijn Coenen 353079100878a2595be644d866e67c12a9de620fd5Martijn Coenenstatus_t readEmbeddedFromParcel(hidl_memory *memory, 363079100878a2595be644d866e67c12a9de620fd5Martijn Coenen const Parcel &parcel, size_t parentHandle, size_t parentOffset); 373079100878a2595be644d866e67c12a9de620fd5Martijn Coenen 383079100878a2595be644d866e67c12a9de620fd5Martijn Coenenstatus_t writeEmbeddedToParcel(const hidl_memory &memory, 393079100878a2595be644d866e67c12a9de620fd5Martijn Coenen Parcel *parcel, size_t parentHandle, size_t parentOffset); 403079100878a2595be644d866e67c12a9de620fd5Martijn Coenen 417f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- hidl_string 427f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 437f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t readEmbeddedFromParcel(hidl_string *string, 447f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const Parcel &parcel, size_t parentHandle, size_t parentOffset); 457f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 467f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t writeEmbeddedToParcel(const hidl_string &string, 477f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong Parcel *parcel, size_t parentHandle, size_t parentOffset); 487f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 497f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- hidl_version 507f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 517f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t writeToParcel(const hidl_version &version, android::hardware::Parcel& parcel); 527f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 537f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Caller is responsible for freeing the returned object. 547f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Honghidl_version* readFromParcel(const android::hardware::Parcel& parcel); 557f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 567f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- Status 577f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 587f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Bear in mind that if the client or service is a Java endpoint, this 597f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// is not the logic which will provide/interpret the data here. 607f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t readFromParcel(Status *status, const Parcel& parcel); 617f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t writeToParcel(const Status &status, Parcel* parcel); 627f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 637f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- hidl_vec 647f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 657f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate<typename T> 667f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t readEmbeddedFromParcel( 677f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong hidl_vec<T> * /*vec*/, 687f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const Parcel &parcel, 697f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentHandle, 707f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentOffset, 717f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle) { 727f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const void *ptr = parcel.readEmbeddedBuffer( 737f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle, 747f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 757f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset + hidl_vec<T>::kOffsetOfBuffer); 767f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 777f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return ptr != NULL ? OK : UNKNOWN_ERROR; 787f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 797f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 807f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate<typename T> 817f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t writeEmbeddedToParcel( 827f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const hidl_vec<T> &vec, 837f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong Parcel *parcel, 847f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentHandle, 857f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentOffset, 867f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle) { 877f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeEmbeddedBuffer( 887f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong vec.data(), 897f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong sizeof(T) * vec.size(), 907f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle, 917f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 927f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset + hidl_vec<T>::kOffsetOfBuffer); 937f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 947f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 957f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate<typename T> 967f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t findInParcel(const hidl_vec<T> &vec, const Parcel &parcel, size_t *handle) { 977f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel.quickFindBuffer(vec.data(), handle); 987f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 997f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1007f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- MQDescriptor 1017f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1027f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate<MQFlavor flavor> 1037f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong::android::status_t readEmbeddedFromParcel( 1047f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong MQDescriptor<flavor> *obj, 1057f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const ::android::hardware::Parcel &parcel, 1067f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentHandle, 1077f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentOffset) { 1087f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ::android::status_t _hidl_err = ::android::OK; 1097f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1107f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t _hidl_grantors_child; 1117f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1127f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong _hidl_err = ::android::hardware::readEmbeddedFromParcel( 1137f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong &obj->grantors(), 1147f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parcel, 1157f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 1167f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset + MQDescriptor<flavor>::kOffsetOfGrantors, 1177f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong &_hidl_grantors_child); 1187f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1197f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (_hidl_err != ::android::OK) { return _hidl_err; } 1207f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1217f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const native_handle_t *_hidl_mq_handle_ptr = parcel.readEmbeddedNativeHandle( 1227f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 1237f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset + MQDescriptor<flavor>::kOffsetOfHandle); 1247f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1257f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (_hidl_mq_handle_ptr == nullptr) { 1267f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong _hidl_err = ::android::UNKNOWN_ERROR; 1277f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return _hidl_err; 1287f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 1297f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1307f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return _hidl_err; 1317f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 1327f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1337f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate<MQFlavor flavor> 1347f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong::android::status_t writeEmbeddedToParcel( 1357f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const MQDescriptor<flavor> &obj, 1367f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ::android::hardware::Parcel *parcel, 1377f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentHandle, 1387f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentOffset) { 1397f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ::android::status_t _hidl_err = ::android::OK; 1407f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1417f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t _hidl_grantors_child; 1427f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1437f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong _hidl_err = ::android::hardware::writeEmbeddedToParcel( 1447f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong obj.grantors(), 1457f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parcel, 1467f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 1477f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset + MQDescriptor<flavor>::kOffsetOfGrantors, 1487f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong &_hidl_grantors_child); 1497f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1507f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (_hidl_err != ::android::OK) { return _hidl_err; } 1517f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1527f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong _hidl_err = parcel->writeEmbeddedNativeHandle( 1537f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong obj.handle(), 1547f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 1557f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset + MQDescriptor<flavor>::kOffsetOfHandle); 1567f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1577f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (_hidl_err != ::android::OK) { return _hidl_err; } 1587f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1597f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return _hidl_err; 1607f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 1617f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1627f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- pointers for HIDL 1637f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1647f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate <typename T> 1657f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatic status_t readEmbeddedReferenceFromParcel( 1667f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong T const* * /* bufptr */, 1677f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const Parcel & parcel, 1687f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentHandle, 1697f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentOffset, 1707f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle, 1717f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool *shouldResolveRefInBuffer 1727f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ) { 1737f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // *bufptr is ignored because, if I am embedded in some 1747f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // other buffer, the kernel should have fixed me up already. 1757f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool isPreviouslyWritten; 1767f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong status_t result = parcel.readEmbeddedReference( 1777f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong nullptr, // ignored, not written to bufptr. 1787f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle, 1797f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 1807f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset, 1817f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong &isPreviouslyWritten); 1827f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // tell caller to run T::readEmbeddedToParcel and 1837f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // T::readEmbeddedReferenceToParcel if necessary. 1847f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // It is not called here because we don't know if these two are valid methods. 1857f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = !isPreviouslyWritten; 1867f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return result; 1877f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 1887f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1897f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate <typename T> 1907f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatic status_t writeEmbeddedReferenceToParcel( 1917f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong T const* buf, 1927f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong Parcel *parcel, size_t parentHandle, size_t parentOffset, 1937f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle, 1947f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool *shouldResolveRefInBuffer 1957f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ) { 1967f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1977f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(buf == nullptr) { 1987f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = false; 1997f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeEmbeddedNullReference(handle, parentHandle, parentOffset); 2007f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2017f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2027f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // find whether the buffer exists 2037f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t childHandle, childOffset; 2047f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong status_t result; 2057f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool found; 2067f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2077f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset); 2087f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2097f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // tell caller to run T::writeEmbeddedToParcel and 2107f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // T::writeEmbeddedReferenceToParcel if necessary. 2117f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // It is not called here because we don't know if these two are valid methods. 2127f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = !found; 2137f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2147f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(result != OK) { 2157f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return result; // bad pointers and length given 2167f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2177f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(!found) { // did not find it. 2187f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeEmbeddedBuffer(buf, sizeof(T), handle, 2197f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, parentOffset); 2207f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2217f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // found the buffer. easy case. 2227f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeEmbeddedReference( 2237f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle, 2247f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong childHandle, 2257f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong childOffset, 2267f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 2277f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset); 2287f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 2297f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2307f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate <typename T> 2317f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatic status_t readReferenceFromParcel( 2327f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong T const* *bufptr, 2337f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const Parcel & parcel, 2347f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle, 2357f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool *shouldResolveRefInBuffer 2367f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ) { 2377f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool isPreviouslyWritten; 2387f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong status_t result = parcel.readReference(reinterpret_cast<void const* *>(bufptr), 2397f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle, &isPreviouslyWritten); 2407f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // tell caller to run T::readEmbeddedToParcel and 2417f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // T::readEmbeddedReferenceToParcel if necessary. 2427f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // It is not called here because we don't know if these two are valid methods. 2437f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = !isPreviouslyWritten; 2447f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return result; 2457f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 2467f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2477f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate <typename T> 2487f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatic status_t writeReferenceToParcel( 2497f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong T const *buf, 2507f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong Parcel * parcel, 2517f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle, 2527f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool *shouldResolveRefInBuffer 2537f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ) { 2547f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2557f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(buf == nullptr) { 2567f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = false; 2577f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeNullReference(handle); 2587f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2597f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2607f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // find whether the buffer exists 2617f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t childHandle, childOffset; 2627f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong status_t result; 2637f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool found; 2647f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2657f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset); 2667f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2677f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // tell caller to run T::writeEmbeddedToParcel and 2687f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // T::writeEmbeddedReferenceToParcel if necessary. 2697f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // It is not called here because we don't know if these two are valid methods. 2707f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = !found; 2717f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2727f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(result != OK) { 2737f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return result; // bad pointers and length given 2747f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2757f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(!found) { // did not find it. 2767f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeBuffer(buf, sizeof(T), handle); 2777f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2787f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // found the buffer. easy case. 2797f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeReference(handle, 2807f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong childHandle, childOffset); 2817f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 2827f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2837f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- support for casting interfaces 2847f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2857f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Construct a smallest possible binder from the given interface. 2867f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// If it is remote, then its remote() will be retrieved. 2877f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Otherwise, the smallest possible BnChild is found where IChild is a subclass of IType 2887f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// and iface is of class IChild. BnChild will be used to wrapped the given iface. 2897f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Return nullptr if iface is null or any failure. 29012f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenentemplate <typename IType, typename ProxyType> 2917f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongsp<IBinder> toBinder(sp<IType> iface) { 2927f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong IType *ifacePtr = iface.get(); 2937f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (ifacePtr == nullptr) { 2947f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return nullptr; 2957f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2967f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (ifacePtr->isRemote()) { 29712f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen return ::android::hardware::IInterface::asBinder(static_cast<ProxyType *>(ifacePtr)); 2987f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } else { 2997f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong std::string myDescriptor{}; 3007f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ifacePtr->interfaceChain([&](const hidl_vec<hidl_string> &types) { 3017f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (types.size() > 0) { 3027f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong myDescriptor = types[0].c_str(); 3037f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 3047f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong }); 3057f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (myDescriptor.empty()) { 306b2c9c75b74c87e651dd08a100015eab17319556eYifan Hong // interfaceChain fails 3077f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return nullptr; 3087f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 3097f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong auto iter = gBnConstructorMap.find(myDescriptor); 3107f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (iter == gBnConstructorMap.end()) { 3117f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return nullptr; 3127f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 3137f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return sp<IBinder>((iter->second)(reinterpret_cast<void *>(ifacePtr))); 3147f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 3157f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 3167f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 31712f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenentemplate <typename IType, typename ProxyType, typename StubType> 31812f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenensp<IType> fromBinder(const sp<IBinder>& binderIface) { 31912f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen using ::android::hidl::base::V1_0::IBase; 32012f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen using ::android::hidl::base::V1_0::BnBase; 32112f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen 32212f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen if (binderIface.get() == nullptr) { 32312f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen return nullptr; 32412f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen } 32512f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen if (binderIface->localBinder() == nullptr) { 32612f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen return new ProxyType(binderIface); 32712f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen } 32812f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen sp<IBase> base = static_cast<BnBase*>(binderIface.get())->getImpl(); 32912f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen if (canCastInterface(base.get(), IType::descriptor)) { 33012f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen StubType* stub = static_cast<StubType*>(binderIface.get()); 33112f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen return stub->getImpl(); 33212f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen } else { 33312f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen return nullptr; 33412f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen } 33512f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen} 33612f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen 3377f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#define IMPLEMENT_SERVICE_MANAGER_INTERACTIONS(INTERFACE, PACKAGE) \ 3387f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ::android::sp<I##INTERFACE> I##INTERFACE::getService( \ 3397f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const std::string &serviceName, bool getStub) \ 3407f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong { \ 3417f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong using ::android::sp; \ 3427f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong using ::android::hardware::defaultServiceManager; \ 3437f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong using ::android::hidl::manager::V1_0::IServiceManager; \ 3447f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong sp<I##INTERFACE> iface; \ 3457f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const sp<IServiceManager> sm = defaultServiceManager(); \ 3467f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (sm != nullptr && !getStub) { \ 3472cd440cf0c589e89d0d4509d273142a35b5ef81cYifan Hong sp<::android::hidl::base::V1_0::IBase> base; \ 3487f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ::android::hardware::Return<void> ret = \ 3497f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong sm->get(PACKAGE "::I" #INTERFACE, serviceName.c_str(), \ 3502cd440cf0c589e89d0d4509d273142a35b5ef81cYifan Hong [&base](sp<::android::hidl::base::V1_0::IBase> found) { \ 3512cd440cf0c589e89d0d4509d273142a35b5ef81cYifan Hong base = found; \ 3527f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong }); \ 3537f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (ret.getStatus().isOk()) { \ 3542cd440cf0c589e89d0d4509d273142a35b5ef81cYifan Hong iface = I##INTERFACE::castFrom(base); \ 3557f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (iface != nullptr) { \ 3567f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return iface; \ 3577f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } \ 3587f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } \ 3597f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } \ 3607f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong int dlMode = RTLD_LAZY; \ 3617f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong void *handle = dlopen(HAL_LIBRARY_PATH_ODM PACKAGE "-impl.so", dlMode); \ 3627f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (handle == nullptr) { \ 3637f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle = dlopen(HAL_LIBRARY_PATH_VENDOR PACKAGE "-impl.so", dlMode); \ 3647f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } \ 3657f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (handle == nullptr) { \ 3667f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle = dlopen(HAL_LIBRARY_PATH_SYSTEM PACKAGE "-impl.so", dlMode); \ 3677f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } \ 3687f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (handle == nullptr) { \ 3697f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return iface; \ 3707f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } \ 3717f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong I##INTERFACE* (*generator)(const char* name); \ 3727f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *(void **)(&generator) = dlsym(handle, "HIDL_FETCH_I"#INTERFACE); \ 3737f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (generator) { \ 3747f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong iface = (*generator)(serviceName.c_str()); \ 3757f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (iface != nullptr) { \ 3767f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong iface = new Bs##INTERFACE(iface); \ 3777f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } \ 3787f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } \ 3797f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return iface; \ 3807f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } \ 3817f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ::android::status_t I##INTERFACE::registerAsService( \ 3827f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const std::string &serviceName) \ 3837f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong { \ 3847f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong using ::android::sp; \ 3857f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong using ::android::hardware::defaultServiceManager; \ 3867f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong using ::android::hidl::manager::V1_0::IServiceManager; \ 3877f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const sp<IServiceManager> sm = defaultServiceManager(); \ 3887f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool success = false; \ 3897f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ::android::hardware::Return<void> ret = \ 3907f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong this->interfaceChain( \ 39112f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen [&success, &sm, &serviceName, this](const auto &chain) { \ 392337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland ::android::hardware::Return<bool> addRet = \ 39312f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen sm->add(chain, serviceName.c_str(), this); \ 3941cfaee704c2d20d6d8d7dedf77bd73f61ee905f7Steven Moreland success = addRet.isOk() && addRet; \ 3957f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong }); \ 3967f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong success = success && ret.getStatus().isOk(); \ 3977f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return success ? ::android::OK : ::android::UNKNOWN_ERROR; \ 3987f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } \ 3997f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool I##INTERFACE::registerForNotifications( \ 4007f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const std::string &serviceName, \ 4017f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> \ 4027f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ¬ification) \ 4037f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong { \ 4047f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong using ::android::sp; \ 4057f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong using ::android::hardware::defaultServiceManager; \ 4067f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong using ::android::hidl::manager::V1_0::IServiceManager; \ 4077f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const sp<IServiceManager> sm = defaultServiceManager(); \ 4087f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (sm == nullptr) { \ 4097f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return false; \ 4107f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } \ 411337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland ::android::hardware::Return<bool> success = \ 412337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland sm->registerForNotifications(PACKAGE "::I" #INTERFACE, \ 413337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland serviceName, \ 414337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland notification); \ 4151cfaee704c2d20d6d8d7dedf77bd73f61ee905f7Steven Moreland return success.isOk() && success; \ 4167f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 4177f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 4187f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 4197f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} // namespace hardware 4207f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} // namespace android 4217f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 4227f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 4237f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#endif // ANDROID_HIDL_BINDER_SUPPORT_H 424