HidlBinderSupport.h revision 7e6404dd880b1f25c932f264c0ba2e00e79c536e
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 209b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen#include <android/hidl/base/1.0/IBase.h> 217f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#include <hidl/HidlSupport.h> 2212f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen#include <hidl/HidlTransportUtils.h> 237f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#include <hidl/MQDescriptor.h> 24b2c9c75b74c87e651dd08a100015eab17319556eYifan Hong#include <hidl/Static.h> 257f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#include <hwbinder/IBinder.h> 26e76c7a27eeb3763a2185c1502fd4572df1513b9aMartijn Coenen#include <hwbinder/IPCThreadState.h> 277f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#include <hwbinder/Parcel.h> 28e76c7a27eeb3763a2185c1502fd4572df1513b9aMartijn Coenen#include <hwbinder/ProcessState.h> 2912f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen#include <android/hidl/base/1.0/BnBase.h> 307f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Defines functions for hidl_string, hidl_version, Status, hidl_vec, MQDescriptor, 317f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// etc. to interact with Parcel. 327f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 337f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongnamespace android { 347f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongnamespace hardware { 357f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 369b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen// hidl_binder_death_recipient wraps a transport-independent 379b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen// hidl_death_recipient, and implements the binder-specific 389b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen// DeathRecipient interface. 399b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenenstruct hidl_binder_death_recipient : IBinder::DeathRecipient { 409b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen hidl_binder_death_recipient(const sp<hidl_death_recipient> &recipient, 419b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen uint64_t cookie, const sp<::android::hidl::base::V1_0::IBase> &base) : 429b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen mRecipient(recipient), mCookie(cookie), mBase(base) { 439b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen } 449b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen virtual void binderDied(const wp<IBinder>& /*who*/) { 459b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen sp<hidl_death_recipient> recipient = mRecipient.promote(); 469b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen if (recipient != nullptr) { 479b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen recipient->serviceDied(mCookie, mBase); 489b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen } 499b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen } 509b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen wp<hidl_death_recipient> getRecipient() { 519b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen return mRecipient; 529b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen } 539b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenenprivate: 549b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen wp<hidl_death_recipient> mRecipient; 559b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen uint64_t mCookie; 569b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen wp<::android::hidl::base::V1_0::IBase> mBase; 579b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen}; 589b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen 593079100878a2595be644d866e67c12a9de620fd5Martijn Coenen// ---------------------- hidl_memory 603079100878a2595be644d866e67c12a9de620fd5Martijn Coenen 613079100878a2595be644d866e67c12a9de620fd5Martijn Coenenstatus_t readEmbeddedFromParcel(hidl_memory *memory, 623079100878a2595be644d866e67c12a9de620fd5Martijn Coenen const Parcel &parcel, size_t parentHandle, size_t parentOffset); 633079100878a2595be644d866e67c12a9de620fd5Martijn Coenen 643079100878a2595be644d866e67c12a9de620fd5Martijn Coenenstatus_t writeEmbeddedToParcel(const hidl_memory &memory, 653079100878a2595be644d866e67c12a9de620fd5Martijn Coenen Parcel *parcel, size_t parentHandle, size_t parentOffset); 663079100878a2595be644d866e67c12a9de620fd5Martijn Coenen 677f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- hidl_string 687f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 697f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t readEmbeddedFromParcel(hidl_string *string, 707f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const Parcel &parcel, size_t parentHandle, size_t parentOffset); 717f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 727f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t writeEmbeddedToParcel(const hidl_string &string, 737f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong Parcel *parcel, size_t parentHandle, size_t parentOffset); 747f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 757f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- hidl_version 767f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 777f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t writeToParcel(const hidl_version &version, android::hardware::Parcel& parcel); 787f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 797f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Caller is responsible for freeing the returned object. 807f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Honghidl_version* readFromParcel(const android::hardware::Parcel& parcel); 817f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 827f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- Status 837f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 847f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Bear in mind that if the client or service is a Java endpoint, this 857f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// is not the logic which will provide/interpret the data here. 867f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t readFromParcel(Status *status, const Parcel& parcel); 877f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t writeToParcel(const Status &status, Parcel* parcel); 887f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 897f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- hidl_vec 907f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 917f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate<typename T> 927f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t readEmbeddedFromParcel( 937f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong hidl_vec<T> * /*vec*/, 947f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const Parcel &parcel, 957f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentHandle, 967f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentOffset, 977f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle) { 987f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const void *ptr = parcel.readEmbeddedBuffer( 997f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle, 1007f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 1017f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset + hidl_vec<T>::kOffsetOfBuffer); 1027f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1037f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return ptr != NULL ? OK : UNKNOWN_ERROR; 1047f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 1057f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1067f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate<typename T> 1077f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t writeEmbeddedToParcel( 1087f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const hidl_vec<T> &vec, 1097f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong Parcel *parcel, 1107f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentHandle, 1117f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentOffset, 1127f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle) { 1137f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeEmbeddedBuffer( 1147f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong vec.data(), 1157f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong sizeof(T) * vec.size(), 1167f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle, 1177f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 1187f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset + hidl_vec<T>::kOffsetOfBuffer); 1197f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 1207f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1217f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate<typename T> 1227f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t findInParcel(const hidl_vec<T> &vec, const Parcel &parcel, size_t *handle) { 1237f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel.quickFindBuffer(vec.data(), handle); 1247f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 1257f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1267f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- MQDescriptor 1277f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1287e6404dd880b1f25c932f264c0ba2e00e79c536eHridya Valsarajutemplate<typename T, MQFlavor flavor> 1297f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong::android::status_t readEmbeddedFromParcel( 1307e6404dd880b1f25c932f264c0ba2e00e79c536eHridya Valsaraju MQDescriptor<T, flavor> *obj, 1317f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const ::android::hardware::Parcel &parcel, 1327f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentHandle, 1337f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentOffset) { 1347f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ::android::status_t _hidl_err = ::android::OK; 1357f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1367f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t _hidl_grantors_child; 1377f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1387f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong _hidl_err = ::android::hardware::readEmbeddedFromParcel( 1397f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong &obj->grantors(), 1407f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parcel, 1417f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 1427e6404dd880b1f25c932f264c0ba2e00e79c536eHridya Valsaraju parentOffset + MQDescriptor<T, flavor>::kOffsetOfGrantors, 1437f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong &_hidl_grantors_child); 1447f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1457f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (_hidl_err != ::android::OK) { return _hidl_err; } 1467f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1477f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const native_handle_t *_hidl_mq_handle_ptr = parcel.readEmbeddedNativeHandle( 1487f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 1497e6404dd880b1f25c932f264c0ba2e00e79c536eHridya Valsaraju parentOffset + MQDescriptor<T, flavor>::kOffsetOfHandle); 1507f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1517f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (_hidl_mq_handle_ptr == nullptr) { 1527f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong _hidl_err = ::android::UNKNOWN_ERROR; 1537f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return _hidl_err; 1547f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 1557f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1567f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return _hidl_err; 1577f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 1587f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1597e6404dd880b1f25c932f264c0ba2e00e79c536eHridya Valsarajutemplate<typename T, MQFlavor flavor> 1607f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong::android::status_t writeEmbeddedToParcel( 1617e6404dd880b1f25c932f264c0ba2e00e79c536eHridya Valsaraju const MQDescriptor<T, flavor> &obj, 1627f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ::android::hardware::Parcel *parcel, 1637f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentHandle, 1647f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentOffset) { 1657f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ::android::status_t _hidl_err = ::android::OK; 1667f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1677f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t _hidl_grantors_child; 1687f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1697f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong _hidl_err = ::android::hardware::writeEmbeddedToParcel( 1707f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong obj.grantors(), 1717f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parcel, 1727f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 1737e6404dd880b1f25c932f264c0ba2e00e79c536eHridya Valsaraju parentOffset + MQDescriptor<T, flavor>::kOffsetOfGrantors, 1747f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong &_hidl_grantors_child); 1757f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1767f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (_hidl_err != ::android::OK) { return _hidl_err; } 1777f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1787f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong _hidl_err = parcel->writeEmbeddedNativeHandle( 1797f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong obj.handle(), 1807f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 1817e6404dd880b1f25c932f264c0ba2e00e79c536eHridya Valsaraju parentOffset + MQDescriptor<T, flavor>::kOffsetOfHandle); 1827f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1837f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (_hidl_err != ::android::OK) { return _hidl_err; } 1847f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1857f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return _hidl_err; 1867f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 1877f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1887f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- pointers for HIDL 1897f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1907f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate <typename T> 1917f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatic status_t readEmbeddedReferenceFromParcel( 1927f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong T const* * /* bufptr */, 1937f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const Parcel & parcel, 1947f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentHandle, 1957f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentOffset, 1967f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle, 1977f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool *shouldResolveRefInBuffer 1987f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ) { 1997f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // *bufptr is ignored because, if I am embedded in some 2007f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // other buffer, the kernel should have fixed me up already. 2017f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool isPreviouslyWritten; 2027f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong status_t result = parcel.readEmbeddedReference( 2037f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong nullptr, // ignored, not written to bufptr. 2047f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle, 2057f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 2067f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset, 2077f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong &isPreviouslyWritten); 2087f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // tell caller to run T::readEmbeddedToParcel and 2097f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // T::readEmbeddedReferenceToParcel if necessary. 2107f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // It is not called here because we don't know if these two are valid methods. 2117f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = !isPreviouslyWritten; 2127f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return result; 2137f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 2147f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2157f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate <typename T> 2167f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatic status_t writeEmbeddedReferenceToParcel( 2177f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong T const* buf, 2187f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong Parcel *parcel, size_t parentHandle, size_t parentOffset, 2197f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle, 2207f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool *shouldResolveRefInBuffer 2217f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ) { 2227f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2237f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(buf == nullptr) { 2247f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = false; 2257f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeEmbeddedNullReference(handle, parentHandle, parentOffset); 2267f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2277f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2287f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // find whether the buffer exists 2297f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t childHandle, childOffset; 2307f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong status_t result; 2317f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool found; 2327f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2337f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset); 2347f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2357f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // tell caller to run T::writeEmbeddedToParcel and 2367f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // T::writeEmbeddedReferenceToParcel if necessary. 2377f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // It is not called here because we don't know if these two are valid methods. 2387f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = !found; 2397f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2407f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(result != OK) { 2417f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return result; // bad pointers and length given 2427f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2437f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(!found) { // did not find it. 2447f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeEmbeddedBuffer(buf, sizeof(T), handle, 2457f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, parentOffset); 2467f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2477f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // found the buffer. easy case. 2487f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeEmbeddedReference( 2497f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle, 2507f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong childHandle, 2517f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong childOffset, 2527f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 2537f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset); 2547f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 2557f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2567f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate <typename T> 2577f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatic status_t readReferenceFromParcel( 2587f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong T const* *bufptr, 2597f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const Parcel & parcel, 2607f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle, 2617f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool *shouldResolveRefInBuffer 2627f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ) { 2637f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool isPreviouslyWritten; 2647f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong status_t result = parcel.readReference(reinterpret_cast<void const* *>(bufptr), 2657f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle, &isPreviouslyWritten); 2667f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // tell caller to run T::readEmbeddedToParcel and 2677f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // T::readEmbeddedReferenceToParcel if necessary. 2687f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // It is not called here because we don't know if these two are valid methods. 2697f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = !isPreviouslyWritten; 2707f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return result; 2717f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 2727f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2737f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate <typename T> 2747f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatic status_t writeReferenceToParcel( 2757f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong T const *buf, 2767f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong Parcel * parcel, 2777f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle, 2787f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool *shouldResolveRefInBuffer 2797f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ) { 2807f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2817f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(buf == nullptr) { 2827f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = false; 2837f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeNullReference(handle); 2847f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2857f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2867f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // find whether the buffer exists 2877f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t childHandle, childOffset; 2887f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong status_t result; 2897f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool found; 2907f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2917f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset); 2927f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2937f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // tell caller to run T::writeEmbeddedToParcel and 2947f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // T::writeEmbeddedReferenceToParcel if necessary. 2957f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // It is not called here because we don't know if these two are valid methods. 2967f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = !found; 2977f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2987f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(result != OK) { 2997f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return result; // bad pointers and length given 3007f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 3017f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(!found) { // did not find it. 3027f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeBuffer(buf, sizeof(T), handle); 3037f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 3047f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // found the buffer. easy case. 3057f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeReference(handle, 3067f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong childHandle, childOffset); 3077f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 3087f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 3097f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- support for casting interfaces 3107f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 3117f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Construct a smallest possible binder from the given interface. 3127f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// If it is remote, then its remote() will be retrieved. 3137f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Otherwise, the smallest possible BnChild is found where IChild is a subclass of IType 3147f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// and iface is of class IChild. BnChild will be used to wrapped the given iface. 3157f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Return nullptr if iface is null or any failure. 31612f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenentemplate <typename IType, typename ProxyType> 3177f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongsp<IBinder> toBinder(sp<IType> iface) { 3187f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong IType *ifacePtr = iface.get(); 3197f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (ifacePtr == nullptr) { 3207f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return nullptr; 3217f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 3227f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (ifacePtr->isRemote()) { 32312f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen return ::android::hardware::IInterface::asBinder(static_cast<ProxyType *>(ifacePtr)); 3247f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } else { 3256bf733ec867a5d46ea05ae5c280a27b051f5018cYifan Hong std::string myDescriptor = getDescriptor(ifacePtr); 3267f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (myDescriptor.empty()) { 327b2c9c75b74c87e651dd08a100015eab17319556eYifan Hong // interfaceChain fails 3287f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return nullptr; 3297f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 3307f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong auto iter = gBnConstructorMap.find(myDescriptor); 3317f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (iter == gBnConstructorMap.end()) { 3327f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return nullptr; 3337f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 3347f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return sp<IBinder>((iter->second)(reinterpret_cast<void *>(ifacePtr))); 3357f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 3367f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 3377f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 33812f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenentemplate <typename IType, typename ProxyType, typename StubType> 33912f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenensp<IType> fromBinder(const sp<IBinder>& binderIface) { 34012f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen using ::android::hidl::base::V1_0::IBase; 34112f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen using ::android::hidl::base::V1_0::BnBase; 34212f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen 34312f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen if (binderIface.get() == nullptr) { 34412f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen return nullptr; 34512f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen } 34612f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen if (binderIface->localBinder() == nullptr) { 34712f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen return new ProxyType(binderIface); 34812f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen } 34912f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen sp<IBase> base = static_cast<BnBase*>(binderIface.get())->getImpl(); 35012f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen if (canCastInterface(base.get(), IType::descriptor)) { 35112f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen StubType* stub = static_cast<StubType*>(binderIface.get()); 35212f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen return stub->getImpl(); 35312f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen } else { 35412f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen return nullptr; 35512f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen } 35612f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen} 35712f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen 358e76c7a27eeb3763a2185c1502fd4572df1513b9aMartijn Coeneninline void configureBinderRpcThreadpool(size_t maxThreads, bool callerWillJoin) { 359e76c7a27eeb3763a2185c1502fd4572df1513b9aMartijn Coenen ProcessState::self()->setThreadPoolConfiguration(maxThreads, callerWillJoin /*callerJoinsPool*/); 360e76c7a27eeb3763a2185c1502fd4572df1513b9aMartijn Coenen} 361e76c7a27eeb3763a2185c1502fd4572df1513b9aMartijn Coenen 362e76c7a27eeb3763a2185c1502fd4572df1513b9aMartijn Coeneninline void joinBinderRpcThreadpool() { 363e76c7a27eeb3763a2185c1502fd4572df1513b9aMartijn Coenen IPCThreadState::self()->joinThreadPool(); 364e76c7a27eeb3763a2185c1502fd4572df1513b9aMartijn Coenen} 365e76c7a27eeb3763a2185c1502fd4572df1513b9aMartijn Coenen 3667f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} // namespace hardware 3677f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} // namespace android 3687f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 3697f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 3707f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#endif // ANDROID_HIDL_BINDER_SUPPORT_H 371