/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_HIDL_BINDER_SUPPORT_H #define ANDROID_HIDL_BINDER_SUPPORT_H #include #include #include #include #include #include #include #include #include // TODO(b/65843592): remove. Too many users depending on this transitively. // Defines functions for hidl_string, Status, hidl_vec, MQDescriptor, // etc. to interact with Parcel. namespace android { namespace hardware { // hidl_binder_death_recipient wraps a transport-independent // hidl_death_recipient, and implements the binder-specific // DeathRecipient interface. struct hidl_binder_death_recipient : IBinder::DeathRecipient { hidl_binder_death_recipient(const sp &recipient, uint64_t cookie, const sp<::android::hidl::base::V1_0::IBase> &base); virtual void binderDied(const wp& /*who*/); wp getRecipient(); private: wp mRecipient; uint64_t mCookie; wp<::android::hidl::base::V1_0::IBase> mBase; }; // ---------------------- hidl_handle status_t readEmbeddedFromParcel(const hidl_handle &handle, const Parcel &parcel, size_t parentHandle, size_t parentOffset); status_t writeEmbeddedToParcel(const hidl_handle &handle, Parcel *parcel, size_t parentHandle, size_t parentOffset); // ---------------------- hidl_memory status_t readEmbeddedFromParcel(const hidl_memory &memory, const Parcel &parcel, size_t parentHandle, size_t parentOffset); status_t writeEmbeddedToParcel(const hidl_memory &memory, Parcel *parcel, size_t parentHandle, size_t parentOffset); // ---------------------- hidl_string status_t readEmbeddedFromParcel(const hidl_string &string, const Parcel &parcel, size_t parentHandle, size_t parentOffset); status_t writeEmbeddedToParcel(const hidl_string &string, Parcel *parcel, size_t parentHandle, size_t parentOffset); // ---------------------- Status // Bear in mind that if the client or service is a Java endpoint, this // is not the logic which will provide/interpret the data here. status_t readFromParcel(Status *status, const Parcel& parcel); status_t writeToParcel(const Status &status, Parcel* parcel); // ---------------------- hidl_vec template status_t readEmbeddedFromParcel( const hidl_vec &vec, const Parcel &parcel, size_t parentHandle, size_t parentOffset, size_t *handle) { const void *out; return parcel.readNullableEmbeddedBuffer( vec.size() * sizeof(T), handle, parentHandle, parentOffset + hidl_vec::kOffsetOfBuffer, &out); } template status_t writeEmbeddedToParcel( const hidl_vec &vec, Parcel *parcel, size_t parentHandle, size_t parentOffset, size_t *handle) { return parcel->writeEmbeddedBuffer( vec.data(), sizeof(T) * vec.size(), handle, parentHandle, parentOffset + hidl_vec::kOffsetOfBuffer); } template status_t findInParcel(const hidl_vec &vec, const Parcel &parcel, size_t *handle) { return parcel.quickFindBuffer(vec.data(), handle); } // ---------------------- MQDescriptor template ::android::status_t readEmbeddedFromParcel( MQDescriptor &obj, const ::android::hardware::Parcel &parcel, size_t parentHandle, size_t parentOffset) { ::android::status_t _hidl_err = ::android::OK; size_t _hidl_grantors_child; _hidl_err = ::android::hardware::readEmbeddedFromParcel( obj.grantors(), parcel, parentHandle, parentOffset + MQDescriptor::kOffsetOfGrantors, &_hidl_grantors_child); if (_hidl_err != ::android::OK) { return _hidl_err; } const native_handle_t *_hidl_mq_handle_ptr; _hidl_err = parcel.readNullableEmbeddedNativeHandle( parentHandle, parentOffset + MQDescriptor::kOffsetOfHandle, &_hidl_mq_handle_ptr); if (_hidl_err != ::android::OK) { return _hidl_err; } return _hidl_err; } template ::android::status_t writeEmbeddedToParcel( const MQDescriptor &obj, ::android::hardware::Parcel *parcel, size_t parentHandle, size_t parentOffset) { ::android::status_t _hidl_err = ::android::OK; size_t _hidl_grantors_child; _hidl_err = ::android::hardware::writeEmbeddedToParcel( obj.grantors(), parcel, parentHandle, parentOffset + MQDescriptor::kOffsetOfGrantors, &_hidl_grantors_child); if (_hidl_err != ::android::OK) { return _hidl_err; } _hidl_err = parcel->writeEmbeddedNativeHandle( obj.handle(), parentHandle, parentOffset + MQDescriptor::kOffsetOfHandle); if (_hidl_err != ::android::OK) { return _hidl_err; } return _hidl_err; } // ---------------------- support for casting interfaces // Constructs a binder for this interface and caches it. If it has already been created // then it returns it. sp getOrCreateCachedBinder(::android::hidl::base::V1_0::IBase* ifacePtr); // Construct a smallest possible binder from the given interface. // If it is remote, then its remote() will be retrieved. // Otherwise, the smallest possible BnChild is found where IChild is a subclass of IType // and iface is of class IChild. BnChild will be used to wrapped the given iface. // Return nullptr if iface is null or any failure. template ::value>> sp toBinder(sp iface) { IType *ifacePtr = iface.get(); return getOrCreateCachedBinder(ifacePtr); } template sp fromBinder(const sp& binderIface) { using ::android::hidl::base::V1_0::IBase; using ::android::hidl::base::V1_0::BnHwBase; if (binderIface.get() == nullptr) { return nullptr; } if (binderIface->localBinder() == nullptr) { return new ProxyType(binderIface); } sp base = static_cast(binderIface.get())->getImpl(); if (details::canCastInterface(base.get(), IType::descriptor)) { StubType* stub = static_cast(binderIface.get()); return stub->getImpl(); } else { return nullptr; } } void configureBinderRpcThreadpool(size_t maxThreads, bool callerWillJoin); void joinBinderRpcThreadpool(); int setupBinderPolling(); status_t handleBinderPoll(); void addPostCommandTask(const std::function task); } // namespace hardware } // namespace android #endif // ANDROID_HIDL_BINDER_SUPPORT_H