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 {
debuggable()29 bool debuggable() {
30 #ifdef LIBHIDL_TARGET_DEBUGGABLE
31 return true;
32 #else
33 return false;
34 #endif
35 }
36 } // namespace details
37
hidl_handle()38 hidl_handle::hidl_handle() {
39 mHandle = nullptr;
40 mOwnsHandle = false;
41 }
42
~hidl_handle()43 hidl_handle::~hidl_handle() {
44 freeHandle();
45 }
46
hidl_handle(const native_handle_t * handle)47 hidl_handle::hidl_handle(const native_handle_t *handle) {
48 mHandle = handle;
49 mOwnsHandle = false;
50 }
51
52 // copy constructor.
hidl_handle(const hidl_handle & other)53 hidl_handle::hidl_handle(const hidl_handle &other) {
54 mOwnsHandle = false;
55 *this = other;
56 }
57
58 // move constructor.
hidl_handle(hidl_handle && other)59 hidl_handle::hidl_handle(hidl_handle &&other) {
60 mOwnsHandle = false;
61 *this = std::move(other);
62 }
63
64 // assignment operators
operator =(const hidl_handle & other)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
operator =(const native_handle_t * native_handle)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
operator =(hidl_handle && other)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
setTo(native_handle_t * handle,bool shouldOwn)101 void hidl_handle::setTo(native_handle_t* handle, bool shouldOwn) {
102 freeHandle();
103 mHandle = handle;
104 mOwnsHandle = shouldOwn;
105 }
106
operator ->() const107 const native_handle_t* hidl_handle::operator->() const {
108 return mHandle;
109 }
110
111 // implicit conversion to const native_handle_t*
operator const native_handle_t*() const112 hidl_handle::operator const native_handle_t *() const {
113 return mHandle;
114 }
115
116 // explicit conversion
getNativeHandle() const117 const native_handle_t *hidl_handle::getNativeHandle() const {
118 return mHandle;
119 }
120
freeHandle()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
hidl_string()140 hidl_string::hidl_string()
141 : mBuffer(kEmptyString),
142 mSize(0),
143 mOwnsBuffer(false) {
144 }
145
~hidl_string()146 hidl_string::~hidl_string() {
147 clear();
148 }
149
hidl_string(const char * s)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
hidl_string(const char * s,size_t length)158 hidl_string::hidl_string(const char *s, size_t length) : hidl_string() {
159 copyFrom(s, length);
160 }
161
hidl_string(const hidl_string & other)162 hidl_string::hidl_string(const hidl_string &other): hidl_string() {
163 copyFrom(other.c_str(), other.size());
164 }
165
hidl_string(const std::string & s)166 hidl_string::hidl_string(const std::string &s) : hidl_string() {
167 copyFrom(s.c_str(), s.size());
168 }
169
hidl_string(hidl_string && other)170 hidl_string::hidl_string(hidl_string &&other): hidl_string() {
171 moveFrom(std::forward<hidl_string>(other));
172 }
173
operator =(hidl_string && other)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
operator =(const hidl_string & other)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
operator =(const char * s)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
operator =(const std::string & s)202 hidl_string &hidl_string::operator=(const std::string &s) {
203 clear();
204 copyFrom(s.c_str(), s.size());
205 return *this;
206 }
207
operator std::string() const208 hidl_string::operator std::string() const {
209 return std::string(mBuffer, mSize);
210 }
211
operator <<(std::ostream & os,const hidl_string & str)212 std::ostream& operator<<(std::ostream& os, const hidl_string& str) {
213 os << str.c_str();
214 return os;
215 }
216
copyFrom(const char * data,size_t size)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
moveFrom(hidl_string && other)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
clear()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
setToExternal(const char * data,size_t size)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
c_str() const264 const char *hidl_string::c_str() const {
265 return mBuffer;
266 }
267
size() const268 size_t hidl_string::size() const {
269 return mSize;
270 }
271
empty() const272 bool hidl_string::empty() const {
273 return mSize == 0;
274 }
275
276 } // namespace hardware
277 } // namespace android
278
279
280