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