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