HidlBinderSupport.h revision 12f04d913dae2fb287089f6db24f144731c79d9c
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
207f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#include <hidl/HidlSupport.h>
2112f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen#include <hidl/HidlTransportUtils.h>
227f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#include <hidl/MQDescriptor.h>
23b2c9c75b74c87e651dd08a100015eab17319556eYifan Hong#include <hidl/Static.h>
247f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#include <hwbinder/IBinder.h>
257f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#include <hwbinder/Parcel.h>
2612f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen#include <android/hidl/base/1.0/BnBase.h>
277f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Defines functions for hidl_string, hidl_version, Status, hidl_vec, MQDescriptor,
287f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// etc. to interact with Parcel.
297f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
307f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongnamespace android {
317f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongnamespace hardware {
327f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
333079100878a2595be644d866e67c12a9de620fd5Martijn Coenen// ---------------------- hidl_memory
343079100878a2595be644d866e67c12a9de620fd5Martijn Coenen
353079100878a2595be644d866e67c12a9de620fd5Martijn Coenenstatus_t readEmbeddedFromParcel(hidl_memory *memory,
363079100878a2595be644d866e67c12a9de620fd5Martijn Coenen        const Parcel &parcel, size_t parentHandle, size_t parentOffset);
373079100878a2595be644d866e67c12a9de620fd5Martijn Coenen
383079100878a2595be644d866e67c12a9de620fd5Martijn Coenenstatus_t writeEmbeddedToParcel(const hidl_memory &memory,
393079100878a2595be644d866e67c12a9de620fd5Martijn Coenen        Parcel *parcel, size_t parentHandle, size_t parentOffset);
403079100878a2595be644d866e67c12a9de620fd5Martijn Coenen
417f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- hidl_string
427f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
437f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t readEmbeddedFromParcel(hidl_string *string,
447f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        const Parcel &parcel, size_t parentHandle, size_t parentOffset);
457f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
467f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t writeEmbeddedToParcel(const hidl_string &string,
477f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        Parcel *parcel, size_t parentHandle, size_t parentOffset);
487f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
497f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- hidl_version
507f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
517f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t writeToParcel(const hidl_version &version, android::hardware::Parcel& parcel);
527f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
537f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Caller is responsible for freeing the returned object.
547f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Honghidl_version* readFromParcel(const android::hardware::Parcel& parcel);
557f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
567f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- Status
577f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
587f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Bear in mind that if the client or service is a Java endpoint, this
597f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// is not the logic which will provide/interpret the data here.
607f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t readFromParcel(Status *status, const Parcel& parcel);
617f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t writeToParcel(const Status &status, Parcel* parcel);
627f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
637f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- hidl_vec
647f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
657f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate<typename T>
667f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t readEmbeddedFromParcel(
677f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        hidl_vec<T> * /*vec*/,
687f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        const Parcel &parcel,
697f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        size_t parentHandle,
707f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        size_t parentOffset,
717f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        size_t *handle) {
727f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    const void *ptr = parcel.readEmbeddedBuffer(
737f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            handle,
747f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            parentHandle,
757f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            parentOffset + hidl_vec<T>::kOffsetOfBuffer);
767f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
777f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    return ptr != NULL ? OK : UNKNOWN_ERROR;
787f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong}
797f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
807f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate<typename T>
817f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t writeEmbeddedToParcel(
827f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        const hidl_vec<T> &vec,
837f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        Parcel *parcel,
847f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        size_t parentHandle,
857f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        size_t parentOffset,
867f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        size_t *handle) {
877f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    return parcel->writeEmbeddedBuffer(
887f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            vec.data(),
897f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            sizeof(T) * vec.size(),
907f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            handle,
917f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            parentHandle,
927f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            parentOffset + hidl_vec<T>::kOffsetOfBuffer);
937f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong}
947f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
957f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate<typename T>
967f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatus_t findInParcel(const hidl_vec<T> &vec, const Parcel &parcel, size_t *handle) {
977f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    return parcel.quickFindBuffer(vec.data(), handle);
987f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong}
997f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
1007f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- MQDescriptor
1017f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
1027f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate<MQFlavor flavor>
1037f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong::android::status_t readEmbeddedFromParcel(
1047f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        MQDescriptor<flavor> *obj,
1057f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        const ::android::hardware::Parcel &parcel,
1067f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        size_t parentHandle,
1077f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        size_t parentOffset) {
1087f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    ::android::status_t _hidl_err = ::android::OK;
1097f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
1107f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    size_t _hidl_grantors_child;
1117f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
1127f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    _hidl_err = ::android::hardware::readEmbeddedFromParcel(
1137f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong                &obj->grantors(),
1147f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong                parcel,
1157f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong                parentHandle,
1167f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong                parentOffset + MQDescriptor<flavor>::kOffsetOfGrantors,
1177f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong                &_hidl_grantors_child);
1187f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
1197f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    if (_hidl_err != ::android::OK) { return _hidl_err; }
1207f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
1217f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    const native_handle_t *_hidl_mq_handle_ptr = parcel.readEmbeddedNativeHandle(
1227f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            parentHandle,
1237f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            parentOffset + MQDescriptor<flavor>::kOffsetOfHandle);
1247f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
1257f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    if (_hidl_mq_handle_ptr == nullptr) {
1267f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        _hidl_err = ::android::UNKNOWN_ERROR;
1277f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        return _hidl_err;
1287f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    }
1297f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
1307f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    return _hidl_err;
1317f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong}
1327f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
1337f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate<MQFlavor flavor>
1347f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong::android::status_t writeEmbeddedToParcel(
1357f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        const MQDescriptor<flavor> &obj,
1367f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        ::android::hardware::Parcel *parcel,
1377f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        size_t parentHandle,
1387f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        size_t parentOffset) {
1397f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    ::android::status_t _hidl_err = ::android::OK;
1407f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
1417f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    size_t _hidl_grantors_child;
1427f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
1437f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    _hidl_err = ::android::hardware::writeEmbeddedToParcel(
1447f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            obj.grantors(),
1457f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            parcel,
1467f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            parentHandle,
1477f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            parentOffset + MQDescriptor<flavor>::kOffsetOfGrantors,
1487f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            &_hidl_grantors_child);
1497f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
1507f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    if (_hidl_err != ::android::OK) { return _hidl_err; }
1517f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
1527f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    _hidl_err = parcel->writeEmbeddedNativeHandle(
1537f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            obj.handle(),
1547f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            parentHandle,
1557f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            parentOffset + MQDescriptor<flavor>::kOffsetOfHandle);
1567f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
1577f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    if (_hidl_err != ::android::OK) { return _hidl_err; }
1587f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
1597f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    return _hidl_err;
1607f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong}
1617f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
1627f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- pointers for HIDL
1637f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
1647f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate <typename T>
1657f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatic status_t readEmbeddedReferenceFromParcel(
1667f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        T const* * /* bufptr */,
1677f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        const Parcel & parcel,
1687f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        size_t parentHandle,
1697f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        size_t parentOffset,
1707f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        size_t *handle,
1717f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        bool *shouldResolveRefInBuffer
1727f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    ) {
1737f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    // *bufptr is ignored because, if I am embedded in some
1747f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    // other buffer, the kernel should have fixed me up already.
1757f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    bool isPreviouslyWritten;
1767f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    status_t result = parcel.readEmbeddedReference(
1777f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        nullptr, // ignored, not written to bufptr.
1787f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        handle,
1797f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        parentHandle,
1807f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        parentOffset,
1817f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        &isPreviouslyWritten);
1827f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    // tell caller to run T::readEmbeddedToParcel and
1837f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    // T::readEmbeddedReferenceToParcel if necessary.
1847f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    // It is not called here because we don't know if these two are valid methods.
1857f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    *shouldResolveRefInBuffer = !isPreviouslyWritten;
1867f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    return result;
1877f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong}
1887f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
1897f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate <typename T>
1907f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatic status_t writeEmbeddedReferenceToParcel(
1917f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        T const* buf,
1927f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        Parcel *parcel, size_t parentHandle, size_t parentOffset,
1937f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        size_t *handle,
1947f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        bool *shouldResolveRefInBuffer
1957f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        ) {
1967f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
1977f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    if(buf == nullptr) {
1987f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        *shouldResolveRefInBuffer = false;
1997f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        return parcel->writeEmbeddedNullReference(handle, parentHandle, parentOffset);
2007f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    }
2017f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
2027f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    // find whether the buffer exists
2037f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    size_t childHandle, childOffset;
2047f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    status_t result;
2057f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    bool found;
2067f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
2077f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);
2087f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
2097f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    // tell caller to run T::writeEmbeddedToParcel and
2107f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    // T::writeEmbeddedReferenceToParcel if necessary.
2117f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    // It is not called here because we don't know if these two are valid methods.
2127f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    *shouldResolveRefInBuffer = !found;
2137f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
2147f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    if(result != OK) {
2157f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        return result; // bad pointers and length given
2167f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    }
2177f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    if(!found) { // did not find it.
2187f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        return parcel->writeEmbeddedBuffer(buf, sizeof(T), handle,
2197f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong                parentHandle, parentOffset);
2207f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    }
2217f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    // found the buffer. easy case.
2227f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    return parcel->writeEmbeddedReference(
2237f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            handle,
2247f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            childHandle,
2257f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            childOffset,
2267f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            parentHandle,
2277f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            parentOffset);
2287f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong}
2297f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
2307f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate <typename T>
2317f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatic status_t readReferenceFromParcel(
2327f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        T const* *bufptr,
2337f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        const Parcel & parcel,
2347f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        size_t *handle,
2357f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        bool *shouldResolveRefInBuffer
2367f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    ) {
2377f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    bool isPreviouslyWritten;
2387f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    status_t result = parcel.readReference(reinterpret_cast<void const* *>(bufptr),
2397f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            handle, &isPreviouslyWritten);
2407f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    // tell caller to run T::readEmbeddedToParcel and
2417f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    // T::readEmbeddedReferenceToParcel if necessary.
2427f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    // It is not called here because we don't know if these two are valid methods.
2437f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    *shouldResolveRefInBuffer = !isPreviouslyWritten;
2447f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    return result;
2457f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong}
2467f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
2477f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongtemplate <typename T>
2487f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongstatic status_t writeReferenceToParcel(
2497f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        T const *buf,
2507f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        Parcel * parcel,
2517f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        size_t *handle,
2527f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        bool *shouldResolveRefInBuffer
2537f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    ) {
2547f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
2557f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    if(buf == nullptr) {
2567f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        *shouldResolveRefInBuffer = false;
2577f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        return parcel->writeNullReference(handle);
2587f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    }
2597f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
2607f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    // find whether the buffer exists
2617f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    size_t childHandle, childOffset;
2627f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    status_t result;
2637f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    bool found;
2647f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
2657f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);
2667f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
2677f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    // tell caller to run T::writeEmbeddedToParcel and
2687f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    // T::writeEmbeddedReferenceToParcel if necessary.
2697f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    // It is not called here because we don't know if these two are valid methods.
2707f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    *shouldResolveRefInBuffer = !found;
2717f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
2727f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    if(result != OK) {
2737f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        return result; // bad pointers and length given
2747f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    }
2757f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    if(!found) { // did not find it.
2767f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        return parcel->writeBuffer(buf, sizeof(T), handle);
2777f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    }
2787f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    // found the buffer. easy case.
2797f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    return parcel->writeReference(handle,
2807f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        childHandle, childOffset);
2817f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong}
2827f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
2837f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// ---------------------- support for casting interfaces
2847f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
2857f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Construct a smallest possible binder from the given interface.
2867f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// If it is remote, then its remote() will be retrieved.
2877f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Otherwise, the smallest possible BnChild is found where IChild is a subclass of IType
2887f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// and iface is of class IChild. BnChild will be used to wrapped the given iface.
2897f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong// Return nullptr if iface is null or any failure.
29012f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenentemplate <typename IType, typename ProxyType>
2917f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hongsp<IBinder> toBinder(sp<IType> iface) {
2927f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    IType *ifacePtr = iface.get();
2937f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    if (ifacePtr == nullptr) {
2947f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        return nullptr;
2957f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    }
2967f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    if (ifacePtr->isRemote()) {
29712f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen        return ::android::hardware::IInterface::asBinder(static_cast<ProxyType *>(ifacePtr));
2987f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    } else {
2997f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        std::string myDescriptor{};
3007f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        ifacePtr->interfaceChain([&](const hidl_vec<hidl_string> &types) {
3017f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            if (types.size() > 0) {
3027f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong                myDescriptor = types[0].c_str();
3037f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            }
3047f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        });
3057f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        if (myDescriptor.empty()) {
306b2c9c75b74c87e651dd08a100015eab17319556eYifan Hong            // interfaceChain fails
3077f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            return nullptr;
3087f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        }
3097f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        auto iter = gBnConstructorMap.find(myDescriptor);
3107f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        if (iter == gBnConstructorMap.end()) {
3117f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            return nullptr;
3127f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        }
3137f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        return sp<IBinder>((iter->second)(reinterpret_cast<void *>(ifacePtr)));
3147f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    }
3157f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong}
3167f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
31712f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenentemplate <typename IType, typename ProxyType, typename StubType>
31812f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenensp<IType> fromBinder(const sp<IBinder>& binderIface) {
31912f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen    using ::android::hidl::base::V1_0::IBase;
32012f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen    using ::android::hidl::base::V1_0::BnBase;
32112f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen
32212f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen    if (binderIface.get() == nullptr) {
32312f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen        return nullptr;
32412f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen    }
32512f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen    if (binderIface->localBinder() == nullptr) {
32612f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen        return new ProxyType(binderIface);
32712f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen    }
32812f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen    sp<IBase> base = static_cast<BnBase*>(binderIface.get())->getImpl();
32912f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen    if (canCastInterface(base.get(), IType::descriptor)) {
33012f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen        StubType* stub = static_cast<StubType*>(binderIface.get());
33112f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen        return stub->getImpl();
33212f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen    } else {
33312f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen        return nullptr;
33412f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen    }
33512f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen}
33612f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen
3377f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#define IMPLEMENT_SERVICE_MANAGER_INTERACTIONS(INTERFACE, PACKAGE)                       \
3387f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    ::android::sp<I##INTERFACE> I##INTERFACE::getService(                                \
3397f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            const std::string &serviceName, bool getStub)                                \
3407f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    {                                                                                    \
3417f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        using ::android::sp;                                                             \
3427f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        using ::android::hardware::defaultServiceManager;                                \
3437f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        using ::android::hidl::manager::V1_0::IServiceManager;                           \
3447f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        sp<I##INTERFACE> iface;                                                          \
3457f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        const sp<IServiceManager> sm = defaultServiceManager();                          \
3467f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        if (sm != nullptr && !getStub) {                                                 \
3472cd440cf0c589e89d0d4509d273142a35b5ef81cYifan Hong            sp<::android::hidl::base::V1_0::IBase> base;                                 \
3487f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            ::android::hardware::Return<void> ret =                                      \
3497f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong                sm->get(PACKAGE "::I" #INTERFACE, serviceName.c_str(),                   \
3502cd440cf0c589e89d0d4509d273142a35b5ef81cYifan Hong                    [&base](sp<::android::hidl::base::V1_0::IBase> found) {              \
3512cd440cf0c589e89d0d4509d273142a35b5ef81cYifan Hong                        base = found;                                                    \
3527f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong                    });                                                                  \
3537f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            if (ret.getStatus().isOk()) {                                                \
3542cd440cf0c589e89d0d4509d273142a35b5ef81cYifan Hong                iface = I##INTERFACE::castFrom(base);                                    \
3557f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong                if (iface != nullptr) {                                                  \
3567f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong                    return iface;                                                        \
3577f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong                }                                                                        \
3587f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            }                                                                            \
3597f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        }                                                                                \
3607f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        int dlMode = RTLD_LAZY;                                                          \
3617f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        void *handle = dlopen(HAL_LIBRARY_PATH_ODM PACKAGE "-impl.so", dlMode);          \
3627f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        if (handle == nullptr) {                                                         \
3637f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            handle = dlopen(HAL_LIBRARY_PATH_VENDOR PACKAGE "-impl.so", dlMode);         \
3647f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        }                                                                                \
3657f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        if (handle == nullptr) {                                                         \
3667f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            handle = dlopen(HAL_LIBRARY_PATH_SYSTEM PACKAGE "-impl.so", dlMode);         \
3677f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        }                                                                                \
3687f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        if (handle == nullptr) {                                                         \
3697f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            return iface;                                                                \
3707f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        }                                                                                \
3717f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        I##INTERFACE* (*generator)(const char* name);                                    \
3727f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        *(void **)(&generator) = dlsym(handle, "HIDL_FETCH_I"#INTERFACE);                \
3737f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        if (generator) {                                                                 \
3747f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            iface = (*generator)(serviceName.c_str());                                   \
3757f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            if (iface != nullptr) {                                                      \
3767f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong                iface = new Bs##INTERFACE(iface);                                        \
3777f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            }                                                                            \
3787f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        }                                                                                \
3797f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        return iface;                                                                    \
3807f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    }                                                                                    \
3817f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    ::android::status_t I##INTERFACE::registerAsService(                                 \
3827f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            const std::string &serviceName)                                              \
3837f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    {                                                                                    \
3847f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        using ::android::sp;                                                             \
3857f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        using ::android::hardware::defaultServiceManager;                                \
3867f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        using ::android::hidl::manager::V1_0::IServiceManager;                           \
3877f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        const sp<IServiceManager> sm = defaultServiceManager();                          \
3887f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        bool success = false;                                                            \
3897f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        ::android::hardware::Return<void> ret =                                          \
3907f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            this->interfaceChain(                                                        \
39112f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen                [&success, &sm, &serviceName, this](const auto &chain) {                 \
392337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland                    ::android::hardware::Return<bool> addRet =                           \
39312f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen                            sm->add(chain, serviceName.c_str(), this);                   \
3941cfaee704c2d20d6d8d7dedf77bd73f61ee905f7Steven Moreland                    success = addRet.isOk() && addRet;                                   \
3957f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong                });                                                                      \
3967f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        success = success && ret.getStatus().isOk();                                     \
3977f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        return success ? ::android::OK : ::android::UNKNOWN_ERROR;                       \
3987f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    }                                                                                    \
3997f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    bool I##INTERFACE::registerForNotifications(                                         \
4007f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            const std::string &serviceName,                                              \
4017f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification>    \
4027f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong                      &notification)                                                     \
4037f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    {                                                                                    \
4047f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        using ::android::sp;                                                             \
4057f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        using ::android::hardware::defaultServiceManager;                                \
4067f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        using ::android::hidl::manager::V1_0::IServiceManager;                           \
4077f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        const sp<IServiceManager> sm = defaultServiceManager();                          \
4087f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        if (sm == nullptr) {                                                             \
4097f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong            return false;                                                                \
4107f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong        }                                                                                \
411337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland        ::android::hardware::Return<bool> success =                                      \
412337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland                sm->registerForNotifications(PACKAGE "::I" #INTERFACE,                   \
413337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland                                             serviceName,                                \
414337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland                                             notification);                              \
4151cfaee704c2d20d6d8d7dedf77bd73f61ee905f7Steven Moreland        return success.isOk() && success;                                                \
4167f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong    }
4177f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
4187f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
4197f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong}  // namespace hardware
4207f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong}  // namespace android
4217f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
4227f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong
4237f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#endif  // ANDROID_HIDL_BINDER_SUPPORT_H
424