1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_HIDL_BINDER_SUPPORT_H 18 #define ANDROID_HIDL_BINDER_SUPPORT_H 19 20 #include <sys/types.h> 21 22 #include <android/hidl/base/1.0/BnHwBase.h> 23 #include <android/hidl/base/1.0/IBase.h> 24 #include <hidl/HidlSupport.h> 25 #include <hidl/HidlTransportUtils.h> 26 #include <hidl/MQDescriptor.h> 27 #include <hwbinder/IBinder.h> 28 #include <hwbinder/Parcel.h> 29 #include <log/log.h> // TODO(b/65843592): remove. Too many users depending on this transitively. 30 31 // Defines functions for hidl_string, Status, hidl_vec, MQDescriptor, 32 // etc. to interact with Parcel. 33 34 namespace android { 35 namespace hardware { 36 37 // hidl_binder_death_recipient wraps a transport-independent 38 // hidl_death_recipient, and implements the binder-specific 39 // DeathRecipient interface. 40 struct hidl_binder_death_recipient : IBinder::DeathRecipient { 41 hidl_binder_death_recipient(const sp<hidl_death_recipient> &recipient, 42 uint64_t cookie, const sp<::android::hidl::base::V1_0::IBase> &base); 43 virtual void binderDied(const wp<IBinder>& /*who*/); 44 wp<hidl_death_recipient> getRecipient(); 45 private: 46 wp<hidl_death_recipient> mRecipient; 47 uint64_t mCookie; 48 wp<::android::hidl::base::V1_0::IBase> mBase; 49 }; 50 51 // ---------------------- hidl_handle 52 53 status_t readEmbeddedFromParcel(const hidl_handle &handle, 54 const Parcel &parcel, size_t parentHandle, size_t parentOffset); 55 56 status_t writeEmbeddedToParcel(const hidl_handle &handle, 57 Parcel *parcel, size_t parentHandle, size_t parentOffset); 58 59 // ---------------------- hidl_memory 60 61 status_t readEmbeddedFromParcel(const hidl_memory &memory, 62 const Parcel &parcel, size_t parentHandle, size_t parentOffset); 63 64 status_t writeEmbeddedToParcel(const hidl_memory &memory, 65 Parcel *parcel, size_t parentHandle, size_t parentOffset); 66 67 // ---------------------- hidl_string 68 69 status_t readEmbeddedFromParcel(const hidl_string &string, 70 const Parcel &parcel, size_t parentHandle, size_t parentOffset); 71 72 status_t writeEmbeddedToParcel(const hidl_string &string, 73 Parcel *parcel, size_t parentHandle, size_t parentOffset); 74 75 // ---------------------- Status 76 77 // Bear in mind that if the client or service is a Java endpoint, this 78 // is not the logic which will provide/interpret the data here. 79 status_t readFromParcel(Status *status, const Parcel& parcel); 80 status_t writeToParcel(const Status &status, Parcel* parcel); 81 82 // ---------------------- hidl_vec 83 84 template<typename T> 85 status_t readEmbeddedFromParcel( 86 const hidl_vec<T> &vec, 87 const Parcel &parcel, 88 size_t parentHandle, 89 size_t parentOffset, 90 size_t *handle) { 91 const void *out; 92 return parcel.readNullableEmbeddedBuffer( 93 vec.size() * sizeof(T), 94 handle, 95 parentHandle, 96 parentOffset + hidl_vec<T>::kOffsetOfBuffer, 97 &out); 98 } 99 100 template<typename T> 101 status_t writeEmbeddedToParcel( 102 const hidl_vec<T> &vec, 103 Parcel *parcel, 104 size_t parentHandle, 105 size_t parentOffset, 106 size_t *handle) { 107 return parcel->writeEmbeddedBuffer( 108 vec.data(), 109 sizeof(T) * vec.size(), 110 handle, 111 parentHandle, 112 parentOffset + hidl_vec<T>::kOffsetOfBuffer); 113 } 114 115 template<typename T> 116 status_t findInParcel(const hidl_vec<T> &vec, const Parcel &parcel, size_t *handle) { 117 return parcel.quickFindBuffer(vec.data(), handle); 118 } 119 120 // ---------------------- MQDescriptor 121 122 template<typename T, MQFlavor flavor> 123 ::android::status_t readEmbeddedFromParcel( 124 MQDescriptor<T, flavor> &obj, 125 const ::android::hardware::Parcel &parcel, 126 size_t parentHandle, 127 size_t parentOffset) { 128 ::android::status_t _hidl_err = ::android::OK; 129 130 size_t _hidl_grantors_child; 131 132 _hidl_err = ::android::hardware::readEmbeddedFromParcel( 133 obj.grantors(), 134 parcel, 135 parentHandle, 136 parentOffset + MQDescriptor<T, flavor>::kOffsetOfGrantors, 137 &_hidl_grantors_child); 138 139 if (_hidl_err != ::android::OK) { return _hidl_err; } 140 141 const native_handle_t *_hidl_mq_handle_ptr; 142 _hidl_err = parcel.readNullableEmbeddedNativeHandle( 143 parentHandle, 144 parentOffset + MQDescriptor<T, flavor>::kOffsetOfHandle, 145 &_hidl_mq_handle_ptr); 146 147 if (_hidl_err != ::android::OK) { return _hidl_err; } 148 149 return _hidl_err; 150 } 151 152 template<typename T, MQFlavor flavor> 153 ::android::status_t writeEmbeddedToParcel( 154 const MQDescriptor<T, flavor> &obj, 155 ::android::hardware::Parcel *parcel, 156 size_t parentHandle, 157 size_t parentOffset) { 158 ::android::status_t _hidl_err = ::android::OK; 159 160 size_t _hidl_grantors_child; 161 162 _hidl_err = ::android::hardware::writeEmbeddedToParcel( 163 obj.grantors(), 164 parcel, 165 parentHandle, 166 parentOffset + MQDescriptor<T, flavor>::kOffsetOfGrantors, 167 &_hidl_grantors_child); 168 169 if (_hidl_err != ::android::OK) { return _hidl_err; } 170 171 _hidl_err = parcel->writeEmbeddedNativeHandle( 172 obj.handle(), 173 parentHandle, 174 parentOffset + MQDescriptor<T, flavor>::kOffsetOfHandle); 175 176 if (_hidl_err != ::android::OK) { return _hidl_err; } 177 178 return _hidl_err; 179 } 180 181 // ---------------------- support for casting interfaces 182 183 // Constructs a binder for this interface and caches it. If it has already been created 184 // then it returns it. 185 sp<IBinder> getOrCreateCachedBinder(::android::hidl::base::V1_0::IBase* ifacePtr); 186 187 // Construct a smallest possible binder from the given interface. 188 // If it is remote, then its remote() will be retrieved. 189 // Otherwise, the smallest possible BnChild is found where IChild is a subclass of IType 190 // and iface is of class IChild. BnChild will be used to wrapped the given iface. 191 // Return nullptr if iface is null or any failure. 192 template <typename IType, 193 typename = std::enable_if_t<std::is_same<details::i_tag, typename IType::_hidl_tag>::value>> 194 sp<IBinder> toBinder(sp<IType> iface) { 195 IType *ifacePtr = iface.get(); 196 return getOrCreateCachedBinder(ifacePtr); 197 } 198 199 template <typename IType, typename ProxyType, typename StubType> 200 sp<IType> fromBinder(const sp<IBinder>& binderIface) { 201 using ::android::hidl::base::V1_0::IBase; 202 using ::android::hidl::base::V1_0::BnHwBase; 203 204 if (binderIface.get() == nullptr) { 205 return nullptr; 206 } 207 208 if (binderIface->localBinder() == nullptr) { 209 return new ProxyType(binderIface); 210 } 211 212 // Ensure that IBinder is BnHwBase (not JHwBinder, for instance) 213 if (!binderIface->checkSubclass(IBase::descriptor)) { 214 return new ProxyType(binderIface); 215 } 216 sp<IBase> base = static_cast<BnHwBase*>(binderIface.get())->getImpl(); 217 218 if (details::canCastInterface(base.get(), IType::descriptor)) { 219 return static_cast<IType*>(base.get()); 220 } else { 221 return nullptr; 222 } 223 } 224 225 void configureBinderRpcThreadpool(size_t maxThreads, bool callerWillJoin); 226 void joinBinderRpcThreadpool(); 227 int setupBinderPolling(); 228 status_t handleBinderPoll(); 229 230 void addPostCommandTask(const std::function<void(void)> task); 231 232 } // namespace hardware 233 } // namespace android 234 235 236 #endif // ANDROID_HIDL_BINDER_SUPPORT_H 237