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