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 #define LOG_TAG "HidlSupport" 17 18 #include <hidl/HidlSupport.h> 19 20 #include <unordered_map> 21 22 #include <android-base/logging.h> 23 #include <android-base/parseint.h> 24 25 namespace android { 26 namespace hardware { 27 28 namespace details { 29 bool debuggable() { 30 #ifdef LIBHIDL_TARGET_DEBUGGABLE 31 return true; 32 #else 33 return false; 34 #endif 35 } 36 } // namespace details 37 38 hidl_handle::hidl_handle() : mHandle(nullptr), mOwnsHandle(false) { 39 memset(mPad, 0, sizeof(mPad)); 40 } 41 42 hidl_handle::~hidl_handle() { 43 freeHandle(); 44 } 45 46 hidl_handle::hidl_handle(const native_handle_t* handle) : hidl_handle() { 47 mHandle = handle; 48 mOwnsHandle = false; 49 } 50 51 // copy constructor. 52 hidl_handle::hidl_handle(const hidl_handle& other) : hidl_handle() { 53 mOwnsHandle = false; 54 *this = other; 55 } 56 57 // move constructor. 58 hidl_handle::hidl_handle(hidl_handle&& other) noexcept : hidl_handle() { 59 mOwnsHandle = false; 60 *this = std::move(other); 61 } 62 63 // assignment operators 64 hidl_handle &hidl_handle::operator=(const hidl_handle &other) { 65 if (this == &other) { 66 return *this; 67 } 68 freeHandle(); 69 if (other.mHandle != nullptr) { 70 mHandle = native_handle_clone(other.mHandle); 71 if (mHandle == nullptr) { 72 PLOG(FATAL) << "Failed to clone native_handle in hidl_handle"; 73 } 74 mOwnsHandle = true; 75 } else { 76 mHandle = nullptr; 77 mOwnsHandle = false; 78 } 79 return *this; 80 } 81 82 hidl_handle &hidl_handle::operator=(const native_handle_t *native_handle) { 83 freeHandle(); 84 mHandle = native_handle; 85 mOwnsHandle = false; 86 return *this; 87 } 88 89 hidl_handle& hidl_handle::operator=(hidl_handle&& other) noexcept { 90 if (this != &other) { 91 freeHandle(); 92 mHandle = other.mHandle; 93 mOwnsHandle = other.mOwnsHandle; 94 other.mHandle = nullptr; 95 other.mOwnsHandle = false; 96 } 97 return *this; 98 } 99 100 void hidl_handle::setTo(native_handle_t* handle, bool shouldOwn) { 101 freeHandle(); 102 mHandle = handle; 103 mOwnsHandle = shouldOwn; 104 } 105 106 const native_handle_t* hidl_handle::operator->() const { 107 return mHandle; 108 } 109 110 // implicit conversion to const native_handle_t* 111 hidl_handle::operator const native_handle_t *() const { 112 return mHandle; 113 } 114 115 // explicit conversion 116 const native_handle_t *hidl_handle::getNativeHandle() const { 117 return mHandle; 118 } 119 120 void hidl_handle::freeHandle() { 121 if (mOwnsHandle && mHandle != nullptr) { 122 // This can only be true if: 123 // 1. Somebody called setTo() with shouldOwn=true, so we know the handle 124 // wasn't const to begin with. 125 // 2. Copy/assignment from another hidl_handle, in which case we have 126 // cloned the handle. 127 // 3. Move constructor from another hidl_handle, in which case the original 128 // hidl_handle must have been non-const as well. 129 native_handle_t *handle = const_cast<native_handle_t*>( 130 static_cast<const native_handle_t*>(mHandle)); 131 native_handle_close(handle); 132 native_handle_delete(handle); 133 mHandle = nullptr; 134 } 135 } 136 137 static const char *const kEmptyString = ""; 138 139 hidl_string::hidl_string() : mBuffer(kEmptyString), mSize(0), mOwnsBuffer(false) { 140 memset(mPad, 0, sizeof(mPad)); 141 } 142 143 hidl_string::~hidl_string() { 144 clear(); 145 } 146 147 hidl_string::hidl_string(const char *s) : hidl_string() { 148 if (s == nullptr) { 149 return; 150 } 151 152 copyFrom(s, strlen(s)); 153 } 154 155 hidl_string::hidl_string(const char *s, size_t length) : hidl_string() { 156 copyFrom(s, length); 157 } 158 159 hidl_string::hidl_string(const hidl_string &other): hidl_string() { 160 copyFrom(other.c_str(), other.size()); 161 } 162 163 hidl_string::hidl_string(const std::string &s) : hidl_string() { 164 copyFrom(s.c_str(), s.size()); 165 } 166 167 hidl_string::hidl_string(hidl_string&& other) noexcept : hidl_string() { 168 moveFrom(std::forward<hidl_string>(other)); 169 } 170 171 hidl_string& hidl_string::operator=(hidl_string&& other) noexcept { 172 if (this != &other) { 173 clear(); 174 moveFrom(std::forward<hidl_string>(other)); 175 } 176 return *this; 177 } 178 179 hidl_string &hidl_string::operator=(const hidl_string &other) { 180 if (this != &other) { 181 clear(); 182 copyFrom(other.c_str(), other.size()); 183 } 184 185 return *this; 186 } 187 188 hidl_string &hidl_string::operator=(const char *s) { 189 clear(); 190 191 if (s == nullptr) { 192 return *this; 193 } 194 195 copyFrom(s, strlen(s)); 196 return *this; 197 } 198 199 hidl_string &hidl_string::operator=(const std::string &s) { 200 clear(); 201 copyFrom(s.c_str(), s.size()); 202 return *this; 203 } 204 205 hidl_string::operator std::string() const { 206 return std::string(mBuffer, mSize); 207 } 208 209 std::ostream& operator<<(std::ostream& os, const hidl_string& str) { 210 os << str.c_str(); 211 return os; 212 } 213 214 void hidl_string::copyFrom(const char *data, size_t size) { 215 // assume my resources are freed. 216 217 if (size >= UINT32_MAX) { 218 LOG(FATAL) << "string size can't exceed 2^32 bytes: " << size; 219 } 220 221 if (size == 0) { 222 mBuffer = kEmptyString; 223 mSize = 0; 224 mOwnsBuffer = false; 225 return; 226 } 227 228 char *buf = (char *)malloc(size + 1); 229 memcpy(buf, data, size); 230 buf[size] = '\0'; 231 mBuffer = buf; 232 233 mSize = static_cast<uint32_t>(size); 234 mOwnsBuffer = true; 235 } 236 237 void hidl_string::moveFrom(hidl_string &&other) { 238 // assume my resources are freed. 239 240 mBuffer = std::move(other.mBuffer); 241 mSize = other.mSize; 242 mOwnsBuffer = other.mOwnsBuffer; 243 244 other.mOwnsBuffer = false; 245 other.clear(); 246 } 247 248 void hidl_string::clear() { 249 if (mOwnsBuffer && (mBuffer != kEmptyString)) { 250 free(const_cast<char *>(static_cast<const char *>(mBuffer))); 251 } 252 253 mBuffer = kEmptyString; 254 mSize = 0; 255 mOwnsBuffer = false; 256 } 257 258 void hidl_string::setToExternal(const char *data, size_t size) { 259 if (size > UINT32_MAX) { 260 LOG(FATAL) << "string size can't exceed 2^32 bytes: " << size; 261 } 262 263 // When the binder driver copies this data into its buffer, it must 264 // have a zero byte there because the remote process will have a pointer 265 // directly into the read-only binder buffer. If we manually copy the 266 // data now to add a zero, then we lose the efficiency of this method. 267 // Checking here (it's also checked in the parceling code later). 268 CHECK(data[size] == '\0'); 269 270 clear(); 271 272 mBuffer = data; 273 mSize = static_cast<uint32_t>(size); 274 mOwnsBuffer = false; 275 } 276 277 const char *hidl_string::c_str() const { 278 return mBuffer; 279 } 280 281 size_t hidl_string::size() const { 282 return mSize; 283 } 284 285 bool hidl_string::empty() const { 286 return mSize == 0; 287 } 288 289 sp<HidlMemory> HidlMemory::getInstance(const hidl_memory& mem) { 290 sp<HidlMemory> instance = new HidlMemory(); 291 instance->hidl_memory::operator=(mem); 292 return instance; 293 } 294 295 sp<HidlMemory> HidlMemory::getInstance(hidl_memory&& mem) { 296 sp<HidlMemory> instance = new HidlMemory(); 297 instance->hidl_memory::operator=(std::move(mem)); 298 return instance; 299 } 300 301 sp<HidlMemory> HidlMemory::getInstance(const hidl_string& name, int fd, uint64_t size) { 302 native_handle_t* handle = native_handle_create(1, 0); 303 if (!handle) { 304 close(fd); 305 LOG(ERROR) << "native_handle_create fails"; 306 return new HidlMemory(); 307 } 308 handle->data[0] = fd; 309 310 hidl_handle hidlHandle; 311 hidlHandle.setTo(handle, true /* shouldOwn */); 312 313 sp<HidlMemory> instance = new HidlMemory(name, std::move(hidlHandle), size); 314 return instance; 315 } 316 317 HidlMemory::HidlMemory() : hidl_memory() {} 318 319 HidlMemory::HidlMemory(const hidl_string& name, hidl_handle&& handle, size_t size) 320 : hidl_memory(name, std::move(handle), size) {} 321 322 // it's required to have at least one out-of-line method to avoid weak vtable 323 HidlMemory::~HidlMemory() {} 324 325 } // namespace hardware 326 } // namespace android 327 328 329