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