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 char *buf = (char *)malloc(size + 1); 221 memcpy(buf, data, size); 222 buf[size] = '\0'; 223 mBuffer = buf; 224 225 mSize = static_cast<uint32_t>(size); 226 mOwnsBuffer = true; 227 } 228 229 void hidl_string::moveFrom(hidl_string &&other) { 230 // assume my resources are freed. 231 232 mBuffer = std::move(other.mBuffer); 233 mSize = other.mSize; 234 mOwnsBuffer = other.mOwnsBuffer; 235 236 other.mOwnsBuffer = false; 237 other.clear(); 238 } 239 240 void hidl_string::clear() { 241 if (mOwnsBuffer && (mBuffer != kEmptyString)) { 242 free(const_cast<char *>(static_cast<const char *>(mBuffer))); 243 } 244 245 mBuffer = kEmptyString; 246 mSize = 0; 247 mOwnsBuffer = false; 248 } 249 250 void hidl_string::setToExternal(const char *data, size_t size) { 251 if (size > UINT32_MAX) { 252 LOG(FATAL) << "string size can't exceed 2^32 bytes: " << size; 253 } 254 255 // When the binder driver copies this data into its buffer, it must 256 // have a zero byte there because the remote process will have a pointer 257 // directly into the read-only binder buffer. If we manually copy the 258 // data now to add a zero, then we lose the efficiency of this method. 259 // Checking here (it's also checked in the parceling code later). 260 CHECK(data[size] == '\0'); 261 262 clear(); 263 264 mBuffer = data; 265 mSize = static_cast<uint32_t>(size); 266 mOwnsBuffer = false; 267 } 268 269 const char *hidl_string::c_str() const { 270 return mBuffer; 271 } 272 273 size_t hidl_string::size() const { 274 return mSize; 275 } 276 277 bool hidl_string::empty() const { 278 return mSize == 0; 279 } 280 281 sp<HidlMemory> HidlMemory::getInstance(const hidl_memory& mem) { 282 sp<HidlMemory> instance = new HidlMemory(); 283 instance->hidl_memory::operator=(mem); 284 return instance; 285 } 286 287 sp<HidlMemory> HidlMemory::getInstance(hidl_memory&& mem) { 288 sp<HidlMemory> instance = new HidlMemory(); 289 instance->hidl_memory::operator=(std::move(mem)); 290 return instance; 291 } 292 293 sp<HidlMemory> HidlMemory::getInstance(const hidl_string& name, int fd, uint64_t size) { 294 native_handle_t* handle = native_handle_create(1, 0); 295 if (!handle) { 296 close(fd); 297 LOG(ERROR) << "native_handle_create fails"; 298 return new HidlMemory(); 299 } 300 handle->data[0] = fd; 301 302 hidl_handle hidlHandle; 303 hidlHandle.setTo(handle, true /* shouldOwn */); 304 305 sp<HidlMemory> instance = new HidlMemory(name, std::move(hidlHandle), size); 306 return instance; 307 } 308 309 HidlMemory::HidlMemory() : hidl_memory() {} 310 311 HidlMemory::HidlMemory(const hidl_string& name, hidl_handle&& handle, size_t size) 312 : hidl_memory(name, std::move(handle), size) {} 313 314 // it's required to have at least one out-of-line method to avoid weak vtable 315 HidlMemory::~HidlMemory() {} 316 317 } // namespace hardware 318 } // namespace android 319 320 321