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, 43108d09d4eae07cd1d70a76187a929dc61548a229Steven Moreland uint64_t cookie, const sp<::android::hidl::base::V1_0::IBase> &base); 44108d09d4eae07cd1d70a76187a929dc61548a229Steven Moreland virtual void binderDied(const wp<IBinder>& /*who*/); 45108d09d4eae07cd1d70a76187a929dc61548a229Steven Moreland wp<hidl_death_recipient> getRecipient(); 469b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenenprivate: 479b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen wp<hidl_death_recipient> mRecipient; 489b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen uint64_t mCookie; 499b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen wp<::android::hidl::base::V1_0::IBase> mBase; 509b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen}; 519b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen 523079100878a2595be644d866e67c12a9de620fd5Martijn Coenen// ---------------------- hidl_memory 533079100878a2595be644d866e67c12a9de620fd5Martijn Coenen 549d3eb357a2a3a64baa4824d550b5563b3dc0b15aMartijn Coenenstatus_t readEmbeddedFromParcel(const hidl_memory &memory, 553079100878a2595be644d866e67c12a9de620fd5Martijn Coenen const Parcel &parcel, size_t parentHandle, size_t parentOffset); 563079100878a2595be644d866e67c12a9de620fd5Martijn Coenen 573079100878a2595be644d866e67c12a9de620fd5Martijn Coenenstatus_t writeEmbeddedToParcel(const hidl_memory &memory, 583079100878a2595be644d866e67c12a9de620fd5Martijn Coenen Parcel *parcel, size_t parentHandle, size_t parentOffset); 593079100878a2595be644d866e67c12a9de620fd5Martijn Coenen 607f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- hidl_string 617f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 629d3eb357a2a3a64baa4824d550b5563b3dc0b15aMartijn Coenenstatus_t readEmbeddedFromParcel(const hidl_string &string, 637f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const Parcel &parcel, size_t parentHandle, size_t parentOffset); 647f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 657f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t writeEmbeddedToParcel(const hidl_string &string, 667f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong Parcel *parcel, size_t parentHandle, size_t parentOffset); 677f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 687f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- hidl_version 697f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 707f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t writeToParcel(const hidl_version &version, android::hardware::Parcel& parcel); 717f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 727f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Caller is responsible for freeing the returned object. 737f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Honghidl_version* readFromParcel(const android::hardware::Parcel& parcel); 747f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 757f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- Status 767f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 777f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Bear in mind that if the client or service is a Java endpoint, this 787f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// is not the logic which will provide/interpret the data here. 797f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t readFromParcel(Status *status, const Parcel& parcel); 807f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t writeToParcel(const Status &status, Parcel* parcel); 817f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 827f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- hidl_vec 837f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 847f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate<typename T> 857f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t readEmbeddedFromParcel( 869d3eb357a2a3a64baa4824d550b5563b3dc0b15aMartijn Coenen const hidl_vec<T> &vec, 877f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const Parcel &parcel, 887f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentHandle, 897f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentOffset, 907f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle) { 911f535a27054e7553e968cac664981073f0074009Steven Moreland const void *out; 926091d185242256107d6cffafaa7e9bf7880b79b4Martijn Coenen return parcel.readNullableEmbeddedBuffer( 939d3eb357a2a3a64baa4824d550b5563b3dc0b15aMartijn Coenen vec.size() * sizeof(T), 947f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle, 957f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 961f535a27054e7553e968cac664981073f0074009Steven Moreland parentOffset + hidl_vec<T>::kOffsetOfBuffer, 971f535a27054e7553e968cac664981073f0074009Steven Moreland &out); 987f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 997f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1007f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate<typename T> 1017f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t writeEmbeddedToParcel( 1027f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const hidl_vec<T> &vec, 1037f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong Parcel *parcel, 1047f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentHandle, 1057f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentOffset, 1067f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle) { 1077f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeEmbeddedBuffer( 1087f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong vec.data(), 1097f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong sizeof(T) * vec.size(), 1107f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle, 1117f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 1127f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset + hidl_vec<T>::kOffsetOfBuffer); 1137f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 1147f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1157f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate<typename T> 1167f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t findInParcel(const hidl_vec<T> &vec, const Parcel &parcel, size_t *handle) { 1177f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel.quickFindBuffer(vec.data(), handle); 1187f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 1197f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1207f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- MQDescriptor 1217f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1227e6404dd880b1f25c932f264c0ba2e00e79c536eHridya Valsarajutemplate<typename T, MQFlavor flavor> 1237f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong::android::status_t readEmbeddedFromParcel( 1249d3eb357a2a3a64baa4824d550b5563b3dc0b15aMartijn Coenen MQDescriptor<T, flavor> &obj, 1257f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const ::android::hardware::Parcel &parcel, 1267f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentHandle, 1277f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentOffset) { 1287f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ::android::status_t _hidl_err = ::android::OK; 1297f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1307f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t _hidl_grantors_child; 1317f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1327f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong _hidl_err = ::android::hardware::readEmbeddedFromParcel( 1339d3eb357a2a3a64baa4824d550b5563b3dc0b15aMartijn Coenen obj.grantors(), 1347f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parcel, 1357f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 1367e6404dd880b1f25c932f264c0ba2e00e79c536eHridya Valsaraju parentOffset + MQDescriptor<T, flavor>::kOffsetOfGrantors, 1377f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong &_hidl_grantors_child); 1387f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1397f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (_hidl_err != ::android::OK) { return _hidl_err; } 1407f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1411f535a27054e7553e968cac664981073f0074009Steven Moreland const native_handle_t *_hidl_mq_handle_ptr; 142f6fa2a90c428b48729505fe7602ab47c45d2fbd4Hridya Valsaraju _hidl_err = parcel.readNullableEmbeddedNativeHandle( 1437f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 1441f535a27054e7553e968cac664981073f0074009Steven Moreland parentOffset + MQDescriptor<T, flavor>::kOffsetOfHandle, 1451f535a27054e7553e968cac664981073f0074009Steven Moreland &_hidl_mq_handle_ptr); 1467f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1471f535a27054e7553e968cac664981073f0074009Steven Moreland if (_hidl_err != ::android::OK) { return _hidl_err; } 1487f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1497f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return _hidl_err; 1507f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 1517f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1527e6404dd880b1f25c932f264c0ba2e00e79c536eHridya Valsarajutemplate<typename T, MQFlavor flavor> 1537f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong::android::status_t writeEmbeddedToParcel( 1547e6404dd880b1f25c932f264c0ba2e00e79c536eHridya Valsaraju const MQDescriptor<T, flavor> &obj, 1557f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ::android::hardware::Parcel *parcel, 1567f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentHandle, 1577f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentOffset) { 1587f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ::android::status_t _hidl_err = ::android::OK; 1597f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1607f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t _hidl_grantors_child; 1617f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1627f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong _hidl_err = ::android::hardware::writeEmbeddedToParcel( 1637f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong obj.grantors(), 1647f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parcel, 1657f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 1667e6404dd880b1f25c932f264c0ba2e00e79c536eHridya Valsaraju parentOffset + MQDescriptor<T, flavor>::kOffsetOfGrantors, 1677f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong &_hidl_grantors_child); 1687f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1697f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (_hidl_err != ::android::OK) { return _hidl_err; } 1707f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1717f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong _hidl_err = parcel->writeEmbeddedNativeHandle( 1727f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong obj.handle(), 1737f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 1747e6404dd880b1f25c932f264c0ba2e00e79c536eHridya Valsaraju parentOffset + MQDescriptor<T, flavor>::kOffsetOfHandle); 1757f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1767f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (_hidl_err != ::android::OK) { return _hidl_err; } 1777f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1787f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return _hidl_err; 1797f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 1807f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1817f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- pointers for HIDL 1827f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 1837f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate <typename T> 1847f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatic status_t readEmbeddedReferenceFromParcel( 1857f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong T const* * /* bufptr */, 1867f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const Parcel & parcel, 1877f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentHandle, 1887f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t parentOffset, 1897f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle, 1907f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool *shouldResolveRefInBuffer 1917f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ) { 1927f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // *bufptr is ignored because, if I am embedded in some 1937f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // other buffer, the kernel should have fixed me up already. 1947f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool isPreviouslyWritten; 1957f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong status_t result = parcel.readEmbeddedReference( 1967f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong nullptr, // ignored, not written to bufptr. 1977f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle, 1987f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 1997f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset, 2007f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong &isPreviouslyWritten); 2017f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // tell caller to run T::readEmbeddedToParcel and 2027f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // T::readEmbeddedReferenceToParcel if necessary. 2037f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // It is not called here because we don't know if these two are valid methods. 2047f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = !isPreviouslyWritten; 2057f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return result; 2067f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 2077f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2087f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate <typename T> 2097f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatic status_t writeEmbeddedReferenceToParcel( 2107f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong T const* buf, 2117f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong Parcel *parcel, size_t parentHandle, size_t parentOffset, 2127f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle, 2137f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool *shouldResolveRefInBuffer 2147f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ) { 2157f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2167f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(buf == nullptr) { 2177f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = false; 2187f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeEmbeddedNullReference(handle, parentHandle, parentOffset); 2197f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2207f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2217f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // find whether the buffer exists 2227f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t childHandle, childOffset; 2237f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong status_t result; 2247f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool found; 2257f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2267f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset); 2277f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2287f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // tell caller to run T::writeEmbeddedToParcel and 2297f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // T::writeEmbeddedReferenceToParcel if necessary. 2307f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // It is not called here because we don't know if these two are valid methods. 2317f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = !found; 2327f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2337f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(result != OK) { 2347f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return result; // bad pointers and length given 2357f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2367f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(!found) { // did not find it. 2377f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeEmbeddedBuffer(buf, sizeof(T), handle, 2387f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, parentOffset); 2397f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2407f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // found the buffer. easy case. 2417f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeEmbeddedReference( 2427f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle, 2437f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong childHandle, 2447f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong childOffset, 2457f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentHandle, 2467f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong parentOffset); 2477f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 2487f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2497f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate <typename T> 2507f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatic status_t readReferenceFromParcel( 2517f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong T const* *bufptr, 2527f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong const Parcel & parcel, 2537f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle, 2547f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool *shouldResolveRefInBuffer 2557f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ) { 2567f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool isPreviouslyWritten; 2577f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong status_t result = parcel.readReference(reinterpret_cast<void const* *>(bufptr), 2587f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong handle, &isPreviouslyWritten); 2597f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // tell caller to run T::readEmbeddedToParcel and 2607f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // T::readEmbeddedReferenceToParcel if necessary. 2617f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // It is not called here because we don't know if these two are valid methods. 2627f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = !isPreviouslyWritten; 2637f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return result; 2647f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 2657f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2667f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate <typename T> 2677f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatic status_t writeReferenceToParcel( 2687f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong T const *buf, 2697f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong Parcel * parcel, 2707f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t *handle, 2717f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool *shouldResolveRefInBuffer 2727f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong ) { 2737f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2747f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(buf == nullptr) { 2757f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = false; 2767f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeNullReference(handle); 2777f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2787f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2797f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // find whether the buffer exists 2807f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong size_t childHandle, childOffset; 2817f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong status_t result; 2827f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong bool found; 2837f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2847f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset); 2857f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2867f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // tell caller to run T::writeEmbeddedToParcel and 2877f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // T::writeEmbeddedReferenceToParcel if necessary. 2887f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // It is not called here because we don't know if these two are valid methods. 2897f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong *shouldResolveRefInBuffer = !found; 2907f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 2917f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(result != OK) { 2927f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return result; // bad pointers and length given 2937f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2947f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if(!found) { // did not find it. 2957f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeBuffer(buf, sizeof(T), handle); 2967f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 2977f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong // found the buffer. easy case. 2987f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return parcel->writeReference(handle, 2997f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong childHandle, childOffset); 3007f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 3017f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 3027f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- support for casting interfaces 3037f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 3047f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Construct a smallest possible binder from the given interface. 3057f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// If it is remote, then its remote() will be retrieved. 3067f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Otherwise, the smallest possible BnChild is found where IChild is a subclass of IType 3077f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// and iface is of class IChild. BnChild will be used to wrapped the given iface. 3087f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Return nullptr if iface is null or any failure. 3095f82d3eb62d0c101d4f7f256d812e5010162ecabSteven Morelandtemplate <typename IType, 3105f82d3eb62d0c101d4f7f256d812e5010162ecabSteven Moreland typename = std::enable_if_t<std::is_same<details::i_tag, typename IType::_hidl_tag>::value>> 3117f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongsp<IBinder> toBinder(sp<IType> iface) { 3127f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong IType *ifacePtr = iface.get(); 3137f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (ifacePtr == nullptr) { 3147f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return nullptr; 3157f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 3167f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (ifacePtr->isRemote()) { 3172932c134c47318489d96e3e4de9ab8e5ff956952Steven Moreland return ::android::hardware::IInterface::asBinder( 3182932c134c47318489d96e3e4de9ab8e5ff956952Steven Moreland static_cast<BpInterface<IType>*>(ifacePtr)); 3197f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } else { 3202ac326f3a86f4c6c1c087ea4a565df5b918e4d2bYifan Hong std::string myDescriptor = details::getDescriptor(ifacePtr); 3217f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong if (myDescriptor.empty()) { 3222ac326f3a86f4c6c1c087ea4a565df5b918e4d2bYifan Hong // interfaceDescriptor fails 3237f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong return nullptr; 3247f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 3252932c134c47318489d96e3e4de9ab8e5ff956952Steven Moreland 3262932c134c47318489d96e3e4de9ab8e5ff956952Steven Moreland // for get + set 3272932c134c47318489d96e3e4de9ab8e5ff956952Steven Moreland std::unique_lock<std::mutex> _lock = details::gBnMap.lock(); 3282932c134c47318489d96e3e4de9ab8e5ff956952Steven Moreland 3292932c134c47318489d96e3e4de9ab8e5ff956952Steven Moreland wp<BHwBinder> wBnObj = details::gBnMap.getLocked(ifacePtr, nullptr); 3302932c134c47318489d96e3e4de9ab8e5ff956952Steven Moreland sp<IBinder> sBnObj = wBnObj.promote(); 3312932c134c47318489d96e3e4de9ab8e5ff956952Steven Moreland 3322932c134c47318489d96e3e4de9ab8e5ff956952Steven Moreland if (sBnObj == nullptr) { 33397f88f31b63c5f4cb12be40cbd9cc8d725a4ef80Yifan Hong auto func = details::getBnConstructorMap().get(myDescriptor, nullptr); 3342932c134c47318489d96e3e4de9ab8e5ff956952Steven Moreland if (!func) { 3352da958e782c7cf664f0e119c417470b4d5f8d4dfYifan Hong func = details::gBnConstructorMap.get(myDescriptor, nullptr); 3362da958e782c7cf664f0e119c417470b4d5f8d4dfYifan Hong if (!func) { 3372da958e782c7cf664f0e119c417470b4d5f8d4dfYifan Hong return nullptr; 3382da958e782c7cf664f0e119c417470b4d5f8d4dfYifan Hong } 3392932c134c47318489d96e3e4de9ab8e5ff956952Steven Moreland } 3402932c134c47318489d96e3e4de9ab8e5ff956952Steven Moreland 3412932c134c47318489d96e3e4de9ab8e5ff956952Steven Moreland sBnObj = sp<IBinder>(func(static_cast<void*>(ifacePtr))); 3422932c134c47318489d96e3e4de9ab8e5ff956952Steven Moreland 3432932c134c47318489d96e3e4de9ab8e5ff956952Steven Moreland if (sBnObj != nullptr) { 3442932c134c47318489d96e3e4de9ab8e5ff956952Steven Moreland details::gBnMap.setLocked(ifacePtr, static_cast<BHwBinder*>(sBnObj.get())); 3452932c134c47318489d96e3e4de9ab8e5ff956952Steven Moreland } 3467f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 3472932c134c47318489d96e3e4de9ab8e5ff956952Steven Moreland 3482932c134c47318489d96e3e4de9ab8e5ff956952Steven Moreland return sBnObj; 3497f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong } 3507f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} 3517f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 35212f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenentemplate <typename IType, typename ProxyType, typename StubType> 35312f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenensp<IType> fromBinder(const sp<IBinder>& binderIface) { 35412f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen using ::android::hidl::base::V1_0::IBase; 3554e92599704db4a3e29d4ad4a539586b019c99dfbYifan Hong using ::android::hidl::base::V1_0::BnHwBase; 35612f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen 35712f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen if (binderIface.get() == nullptr) { 35812f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen return nullptr; 35912f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen } 36012f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen if (binderIface->localBinder() == nullptr) { 36112f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen return new ProxyType(binderIface); 36212f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen } 3634e92599704db4a3e29d4ad4a539586b019c99dfbYifan Hong sp<IBase> base = static_cast<BnHwBase*>(binderIface.get())->getImpl(); 3642ac326f3a86f4c6c1c087ea4a565df5b918e4d2bYifan Hong if (details::canCastInterface(base.get(), IType::descriptor)) { 36512f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen StubType* stub = static_cast<StubType*>(binderIface.get()); 36612f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen return stub->getImpl(); 36712f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen } else { 36812f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen return nullptr; 36912f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen } 37012f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen} 37112f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen 3726cf8fa2d989bf57aed9a62fd9f54261176a9f860Steven Morelandvoid configureBinderRpcThreadpool(size_t maxThreads, bool callerWillJoin); 3736cf8fa2d989bf57aed9a62fd9f54261176a9f860Steven Morelandvoid joinBinderRpcThreadpool(); 3743f5ac4ca824f178bc60d2ae867c7453a74a122f9Martijn Coenenint setupBinderPolling(); 3753f5ac4ca824f178bc60d2ae867c7453a74a122f9Martijn Coenenstatus_t handleBinderPoll(); 376e76c7a27eeb3763a2185c1502fd4572df1513b9aMartijn Coenen 3777f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} // namespace hardware 3787f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong} // namespace android 3797f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 3807f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong 3817f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#endif // ANDROID_HIDL_BINDER_SUPPORT_H 382