You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
279 lines
6.4 KiB
279 lines
6.4 KiB
/* |
|
* 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. |
|
*/ |
|
#define LOG_TAG "HidlSupport" |
|
|
|
#include <hidl/HidlSupport.h> |
|
|
|
#include <unordered_map> |
|
|
|
#include <android-base/logging.h> |
|
#include <android-base/parseint.h> |
|
|
|
namespace android { |
|
namespace hardware { |
|
|
|
namespace details { |
|
bool debuggable() { |
|
#ifdef LIBHIDL_TARGET_DEBUGGABLE |
|
return true; |
|
#else |
|
return false; |
|
#endif |
|
} |
|
} // namespace details |
|
|
|
hidl_handle::hidl_handle() { |
|
mHandle = nullptr; |
|
mOwnsHandle = false; |
|
} |
|
|
|
hidl_handle::~hidl_handle() { |
|
freeHandle(); |
|
} |
|
|
|
hidl_handle::hidl_handle(const native_handle_t *handle) { |
|
mHandle = handle; |
|
mOwnsHandle = false; |
|
} |
|
|
|
// copy constructor. |
|
hidl_handle::hidl_handle(const hidl_handle &other) { |
|
mOwnsHandle = false; |
|
*this = other; |
|
} |
|
|
|
// move constructor. |
|
hidl_handle::hidl_handle(hidl_handle &&other) { |
|
mOwnsHandle = false; |
|
*this = std::move(other); |
|
} |
|
|
|
// assignment operators |
|
hidl_handle &hidl_handle::operator=(const hidl_handle &other) { |
|
if (this == &other) { |
|
return *this; |
|
} |
|
freeHandle(); |
|
if (other.mHandle != nullptr) { |
|
mHandle = native_handle_clone(other.mHandle); |
|
if (mHandle == nullptr) { |
|
PLOG(FATAL) << "Failed to clone native_handle in hidl_handle"; |
|
} |
|
mOwnsHandle = true; |
|
} else { |
|
mHandle = nullptr; |
|
mOwnsHandle = false; |
|
} |
|
return *this; |
|
} |
|
|
|
hidl_handle &hidl_handle::operator=(const native_handle_t *native_handle) { |
|
freeHandle(); |
|
mHandle = native_handle; |
|
mOwnsHandle = false; |
|
return *this; |
|
} |
|
|
|
hidl_handle &hidl_handle::operator=(hidl_handle &&other) { |
|
if (this != &other) { |
|
freeHandle(); |
|
mHandle = other.mHandle; |
|
mOwnsHandle = other.mOwnsHandle; |
|
other.mHandle = nullptr; |
|
other.mOwnsHandle = false; |
|
} |
|
return *this; |
|
} |
|
|
|
void hidl_handle::setTo(native_handle_t* handle, bool shouldOwn) { |
|
freeHandle(); |
|
mHandle = handle; |
|
mOwnsHandle = shouldOwn; |
|
} |
|
|
|
const native_handle_t* hidl_handle::operator->() const { |
|
return mHandle; |
|
} |
|
|
|
// implicit conversion to const native_handle_t* |
|
hidl_handle::operator const native_handle_t *() const { |
|
return mHandle; |
|
} |
|
|
|
// explicit conversion |
|
const native_handle_t *hidl_handle::getNativeHandle() const { |
|
return mHandle; |
|
} |
|
|
|
void hidl_handle::freeHandle() { |
|
if (mOwnsHandle && mHandle != nullptr) { |
|
// This can only be true if: |
|
// 1. Somebody called setTo() with shouldOwn=true, so we know the handle |
|
// wasn't const to begin with. |
|
// 2. Copy/assignment from another hidl_handle, in which case we have |
|
// cloned the handle. |
|
// 3. Move constructor from another hidl_handle, in which case the original |
|
// hidl_handle must have been non-const as well. |
|
native_handle_t *handle = const_cast<native_handle_t*>( |
|
static_cast<const native_handle_t*>(mHandle)); |
|
native_handle_close(handle); |
|
native_handle_delete(handle); |
|
mHandle = nullptr; |
|
} |
|
} |
|
|
|
static const char *const kEmptyString = ""; |
|
|
|
hidl_string::hidl_string() |
|
: mBuffer(kEmptyString), |
|
mSize(0), |
|
mOwnsBuffer(false) { |
|
} |
|
|
|
hidl_string::~hidl_string() { |
|
clear(); |
|
} |
|
|
|
hidl_string::hidl_string(const char *s) : hidl_string() { |
|
if (s == nullptr) { |
|
return; |
|
} |
|
|
|
copyFrom(s, strlen(s)); |
|
} |
|
|
|
hidl_string::hidl_string(const char *s, size_t length) : hidl_string() { |
|
copyFrom(s, length); |
|
} |
|
|
|
hidl_string::hidl_string(const hidl_string &other): hidl_string() { |
|
copyFrom(other.c_str(), other.size()); |
|
} |
|
|
|
hidl_string::hidl_string(const std::string &s) : hidl_string() { |
|
copyFrom(s.c_str(), s.size()); |
|
} |
|
|
|
hidl_string::hidl_string(hidl_string &&other): hidl_string() { |
|
moveFrom(std::forward<hidl_string>(other)); |
|
} |
|
|
|
hidl_string &hidl_string::operator=(hidl_string &&other) { |
|
if (this != &other) { |
|
clear(); |
|
moveFrom(std::forward<hidl_string>(other)); |
|
} |
|
return *this; |
|
} |
|
|
|
hidl_string &hidl_string::operator=(const hidl_string &other) { |
|
if (this != &other) { |
|
clear(); |
|
copyFrom(other.c_str(), other.size()); |
|
} |
|
|
|
return *this; |
|
} |
|
|
|
hidl_string &hidl_string::operator=(const char *s) { |
|
clear(); |
|
|
|
if (s == nullptr) { |
|
return *this; |
|
} |
|
|
|
copyFrom(s, strlen(s)); |
|
return *this; |
|
} |
|
|
|
hidl_string &hidl_string::operator=(const std::string &s) { |
|
clear(); |
|
copyFrom(s.c_str(), s.size()); |
|
return *this; |
|
} |
|
|
|
hidl_string::operator std::string() const { |
|
return std::string(mBuffer, mSize); |
|
} |
|
|
|
std::ostream& operator<<(std::ostream& os, const hidl_string& str) { |
|
os << str.c_str(); |
|
return os; |
|
} |
|
|
|
void hidl_string::copyFrom(const char *data, size_t size) { |
|
// assume my resources are freed. |
|
|
|
if (size > UINT32_MAX) { |
|
LOG(FATAL) << "string size can't exceed 2^32 bytes: " << size; |
|
} |
|
char *buf = (char *)malloc(size + 1); |
|
memcpy(buf, data, size); |
|
buf[size] = '\0'; |
|
mBuffer = buf; |
|
|
|
mSize = static_cast<uint32_t>(size); |
|
mOwnsBuffer = true; |
|
} |
|
|
|
void hidl_string::moveFrom(hidl_string &&other) { |
|
// assume my resources are freed. |
|
|
|
mBuffer = std::move(other.mBuffer); |
|
mSize = other.mSize; |
|
mOwnsBuffer = other.mOwnsBuffer; |
|
|
|
other.mOwnsBuffer = false; |
|
other.clear(); |
|
} |
|
|
|
void hidl_string::clear() { |
|
if (mOwnsBuffer && (mBuffer != kEmptyString)) { |
|
free(const_cast<char *>(static_cast<const char *>(mBuffer))); |
|
} |
|
|
|
mBuffer = kEmptyString; |
|
mSize = 0; |
|
mOwnsBuffer = false; |
|
} |
|
|
|
void hidl_string::setToExternal(const char *data, size_t size) { |
|
if (size > UINT32_MAX) { |
|
LOG(FATAL) << "string size can't exceed 2^32 bytes: " << size; |
|
} |
|
clear(); |
|
|
|
mBuffer = data; |
|
mSize = static_cast<uint32_t>(size); |
|
mOwnsBuffer = false; |
|
} |
|
|
|
const char *hidl_string::c_str() const { |
|
return mBuffer; |
|
} |
|
|
|
size_t hidl_string::size() const { |
|
return mSize; |
|
} |
|
|
|
bool hidl_string::empty() const { |
|
return mSize == 0; |
|
} |
|
|
|
} // namespace hardware |
|
} // namespace android |
|
|
|
|
|
|