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