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() { 39 mHandle = nullptr; 40 mOwnsHandle = false; 41 } 42 43 hidl_handle::~hidl_handle() { 44 freeHandle(); 45 } 46 47 hidl_handle::hidl_handle(const native_handle_t *handle) { 48 mHandle = handle; 49 mOwnsHandle = false; 50 } 51 52 // copy constructor. 53 hidl_handle::hidl_handle(const hidl_handle &other) { 54 mOwnsHandle = false; 55 *this = other; 56 } 57 58 // move constructor. 59 hidl_handle::hidl_handle(hidl_handle &&other) { 60 mOwnsHandle = false; 61 *this = std::move(other); 62 } 63 64 // assignment operators 65 hidl_handle &hidl_handle::operator=(const hidl_handle &other) { 66 if (this == &other) { 67 return *this; 68 } 69 freeHandle(); 70 if (other.mHandle != nullptr) { 71 mHandle = native_handle_clone(other.mHandle); 72 if (mHandle == nullptr) { 73 LOG(FATAL) << "Failed to clone native_handle in hidl_handle."; 74 } 75 mOwnsHandle = true; 76 } else { 77 mHandle = nullptr; 78 mOwnsHandle = false; 79 } 80 return *this; 81 } 82 83 hidl_handle &hidl_handle::operator=(const native_handle_t *native_handle) { 84 freeHandle(); 85 mHandle = native_handle; 86 mOwnsHandle = false; 87 return *this; 88 } 89 90 hidl_handle &hidl_handle::operator=(hidl_handle &&other) { 91 if (this != &other) { 92 freeHandle(); 93 mHandle = other.mHandle; 94 mOwnsHandle = other.mOwnsHandle; 95 other.mHandle = nullptr; 96 other.mOwnsHandle = false; 97 } 98 return *this; 99 } 100 101 void hidl_handle::setTo(native_handle_t* handle, bool shouldOwn) { 102 freeHandle(); 103 mHandle = handle; 104 mOwnsHandle = shouldOwn; 105 } 106 107 const native_handle_t* hidl_handle::operator->() const { 108 return mHandle; 109 } 110 111 // implicit conversion to const native_handle_t* 112 hidl_handle::operator const native_handle_t *() const { 113 return mHandle; 114 } 115 116 // explicit conversion 117 const native_handle_t *hidl_handle::getNativeHandle() const { 118 return mHandle; 119 } 120 121 void hidl_handle::freeHandle() { 122 if (mOwnsHandle && mHandle != nullptr) { 123 // This can only be true if: 124 // 1. Somebody called setTo() with shouldOwn=true, so we know the handle 125 // wasn't const to begin with. 126 // 2. Copy/assignment from another hidl_handle, in which case we have 127 // cloned the handle. 128 // 3. Move constructor from another hidl_handle, in which case the original 129 // hidl_handle must have been non-const as well. 130 native_handle_t *handle = const_cast<native_handle_t*>( 131 static_cast<const native_handle_t*>(mHandle)); 132 native_handle_close(handle); 133 native_handle_delete(handle); 134 mHandle = nullptr; 135 } 136 } 137 138 static const char *const kEmptyString = ""; 139 140 hidl_string::hidl_string() 141 : mBuffer(kEmptyString), 142 mSize(0), 143 mOwnsBuffer(false) { 144 } 145 146 hidl_string::~hidl_string() { 147 clear(); 148 } 149 150 hidl_string::hidl_string(const char *s) : hidl_string() { 151 if (s == nullptr) { 152 return; 153 } 154 155 copyFrom(s, strlen(s)); 156 } 157 158 hidl_string::hidl_string(const char *s, size_t length) : hidl_string() { 159 copyFrom(s, length); 160 } 161 162 hidl_string::hidl_string(const hidl_string &other): hidl_string() { 163 copyFrom(other.c_str(), other.size()); 164 } 165 166 hidl_string::hidl_string(const std::string &s) : hidl_string() { 167 copyFrom(s.c_str(), s.size()); 168 } 169 170 hidl_string::hidl_string(hidl_string &&other): hidl_string() { 171 moveFrom(std::forward<hidl_string>(other)); 172 } 173 174 hidl_string &hidl_string::operator=(hidl_string &&other) { 175 if (this != &other) { 176 clear(); 177 moveFrom(std::forward<hidl_string>(other)); 178 } 179 return *this; 180 } 181 182 hidl_string &hidl_string::operator=(const hidl_string &other) { 183 if (this != &other) { 184 clear(); 185 copyFrom(other.c_str(), other.size()); 186 } 187 188 return *this; 189 } 190 191 hidl_string &hidl_string::operator=(const char *s) { 192 clear(); 193 194 if (s == nullptr) { 195 return *this; 196 } 197 198 copyFrom(s, strlen(s)); 199 return *this; 200 } 201 202 hidl_string &hidl_string::operator=(const std::string &s) { 203 clear(); 204 copyFrom(s.c_str(), s.size()); 205 return *this; 206 } 207 208 hidl_string::operator std::string() const { 209 return std::string(mBuffer, mSize); 210 } 211 212 std::ostream& operator<<(std::ostream& os, const hidl_string& str) { 213 os << str.c_str(); 214 return os; 215 } 216 217 void hidl_string::copyFrom(const char *data, size_t size) { 218 // assume my resources are freed. 219 220 if (size > UINT32_MAX) { 221 LOG(FATAL) << "string size can't exceed 2^32 bytes."; 222 } 223 char *buf = (char *)malloc(size + 1); 224 memcpy(buf, data, size); 225 buf[size] = '\0'; 226 mBuffer = buf; 227 228 mSize = static_cast<uint32_t>(size); 229 mOwnsBuffer = true; 230 } 231 232 void hidl_string::moveFrom(hidl_string &&other) { 233 // assume my resources are freed. 234 235 mBuffer = std::move(other.mBuffer); 236 mSize = other.mSize; 237 mOwnsBuffer = other.mOwnsBuffer; 238 239 other.mOwnsBuffer = false; 240 other.clear(); 241 } 242 243 void hidl_string::clear() { 244 if (mOwnsBuffer && (mBuffer != kEmptyString)) { 245 free(const_cast<char *>(static_cast<const char *>(mBuffer))); 246 } 247 248 mBuffer = kEmptyString; 249 mSize = 0; 250 mOwnsBuffer = false; 251 } 252 253 void hidl_string::setToExternal(const char *data, size_t size) { 254 if (size > UINT32_MAX) { 255 LOG(FATAL) << "string size can't exceed 2^32 bytes."; 256 } 257 clear(); 258 259 mBuffer = data; 260 mSize = static_cast<uint32_t>(size); 261 mOwnsBuffer = false; 262 } 263 264 const char *hidl_string::c_str() const { 265 return mBuffer; 266 } 267 268 size_t hidl_string::size() const { 269 return mSize; 270 } 271 272 bool hidl_string::empty() const { 273 return mSize == 0; 274 } 275 276 } // namespace hardware 277 } // namespace android 278 279 280