blob: aec3fedd4f5f9ec00b47f8e319e462b65f341b5a [file] [log] [blame]
Martijn Coenen72110162016-08-19 14:28:25 +02001/*
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 */
Martijn Coenen30791002016-12-01 15:40:46 +010016#define LOG_TAG "HidlSupport"
Martijn Coenen72110162016-08-19 14:28:25 +020017
18#include <hidl/HidlSupport.h>
19
Yifan Hong20273f92017-01-30 14:13:19 -080020#include <unordered_map>
21
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -070022#include <android-base/logging.h>
Yifan Hong20273f92017-01-30 14:13:19 -080023#include <android-base/parseint.h>
Martijn Coenen30791002016-12-01 15:40:46 +010024
Martijn Coenen72110162016-08-19 14:28:25 +020025namespace android {
26namespace hardware {
27
Yifan Hong24332ef2017-03-07 16:22:19 -080028namespace details {
29bool debuggable() {
30#ifdef LIBHIDL_TARGET_DEBUGGABLE
31 return true;
32#else
33 return false;
34#endif
35}
36} // namespace details
37
Martijn Coenen04b91c02017-01-19 14:14:21 +010038hidl_handle::hidl_handle() {
39 mHandle = nullptr;
40 mOwnsHandle = false;
41}
42
43hidl_handle::~hidl_handle() {
44 freeHandle();
45}
46
47hidl_handle::hidl_handle(const native_handle_t *handle) {
48 mHandle = handle;
49 mOwnsHandle = false;
50}
51
52// copy constructor.
53hidl_handle::hidl_handle(const hidl_handle &other) {
54 mOwnsHandle = false;
55 *this = other;
56}
57
58// move constructor.
59hidl_handle::hidl_handle(hidl_handle &&other) {
60 mOwnsHandle = false;
61 *this = std::move(other);
62}
63
64// assignment operators
65hidl_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) {
Elliott Hughes0e55b452017-05-01 21:38:48 -070073 PLOG(FATAL) << "Failed to clone native_handle in hidl_handle";
Martijn Coenen04b91c02017-01-19 14:14:21 +010074 }
75 mOwnsHandle = true;
76 } else {
77 mHandle = nullptr;
78 mOwnsHandle = false;
79 }
80 return *this;
81}
82
83hidl_handle &hidl_handle::operator=(const native_handle_t *native_handle) {
84 freeHandle();
85 mHandle = native_handle;
86 mOwnsHandle = false;
87 return *this;
88}
89
90hidl_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
101void hidl_handle::setTo(native_handle_t* handle, bool shouldOwn) {
Scott Randolphca37c0e2017-02-15 16:38:46 -0800102 freeHandle();
Martijn Coenen04b91c02017-01-19 14:14:21 +0100103 mHandle = handle;
104 mOwnsHandle = shouldOwn;
105}
106
107const native_handle_t* hidl_handle::operator->() const {
108 return mHandle;
109}
110
111// implicit conversion to const native_handle_t*
112hidl_handle::operator const native_handle_t *() const {
113 return mHandle;
114}
115
116// explicit conversion
117const native_handle_t *hidl_handle::getNativeHandle() const {
118 return mHandle;
119}
120
121void 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
Martijn Coenen72110162016-08-19 14:28:25 +0200138static const char *const kEmptyString = "";
139
140hidl_string::hidl_string()
Yifan Hong602b85a2016-10-24 13:40:01 -0700141 : mBuffer(kEmptyString),
Martijn Coenen72110162016-08-19 14:28:25 +0200142 mSize(0),
Yifan Hong602b85a2016-10-24 13:40:01 -0700143 mOwnsBuffer(false) {
Martijn Coenen72110162016-08-19 14:28:25 +0200144}
145
146hidl_string::~hidl_string() {
147 clear();
148}
149
Steven Morelande03c0872016-10-24 10:43:50 -0700150hidl_string::hidl_string(const char *s) : hidl_string() {
Steven Morelanda21d84f2017-02-16 09:23:45 -0800151 if (s == nullptr) {
152 return;
153 }
154
Yifan Hong602b85a2016-10-24 13:40:01 -0700155 copyFrom(s, strlen(s));
Steven Morelande03c0872016-10-24 10:43:50 -0700156}
157
Steven Moreland53120f72017-01-12 09:39:26 -0800158hidl_string::hidl_string(const char *s, size_t length) : hidl_string() {
159 copyFrom(s, length);
160}
161
Yifan Hong602b85a2016-10-24 13:40:01 -0700162hidl_string::hidl_string(const hidl_string &other): hidl_string() {
163 copyFrom(other.c_str(), other.size());
164}
165
166hidl_string::hidl_string(const std::string &s) : hidl_string() {
167 copyFrom(s.c_str(), s.size());
168}
169
170hidl_string::hidl_string(hidl_string &&other): hidl_string() {
171 moveFrom(std::forward<hidl_string>(other));
172}
173
174hidl_string &hidl_string::operator=(hidl_string &&other) {
175 if (this != &other) {
176 clear();
177 moveFrom(std::forward<hidl_string>(other));
178 }
179 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +0200180}
181
182hidl_string &hidl_string::operator=(const hidl_string &other) {
183 if (this != &other) {
Yifan Hong602b85a2016-10-24 13:40:01 -0700184 clear();
185 copyFrom(other.c_str(), other.size());
Martijn Coenen72110162016-08-19 14:28:25 +0200186 }
187
188 return *this;
189}
190
191hidl_string &hidl_string::operator=(const char *s) {
Yifan Hong602b85a2016-10-24 13:40:01 -0700192 clear();
Steven Moreland153f87a2017-02-28 09:42:26 -0800193
194 if (s == nullptr) {
195 return *this;
196 }
197
Yifan Hong602b85a2016-10-24 13:40:01 -0700198 copyFrom(s, strlen(s));
199 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +0200200}
201
Yifan Hong602b85a2016-10-24 13:40:01 -0700202hidl_string &hidl_string::operator=(const std::string &s) {
Martijn Coenen72110162016-08-19 14:28:25 +0200203 clear();
Yifan Hong602b85a2016-10-24 13:40:01 -0700204 copyFrom(s.c_str(), s.size());
205 return *this;
206}
Martijn Coenen72110162016-08-19 14:28:25 +0200207
Yifan Hong602b85a2016-10-24 13:40:01 -0700208hidl_string::operator std::string() const {
209 return std::string(mBuffer, mSize);
210}
211
Scott Randolph0c84ab42017-04-03 14:07:14 -0700212std::ostream& operator<<(std::ostream& os, const hidl_string& str) {
213 os << str.c_str();
214 return os;
Yifan Hong602b85a2016-10-24 13:40:01 -0700215}
216
217void hidl_string::copyFrom(const char *data, size_t size) {
218 // assume my resources are freed.
219
Steven Moreland98893802017-10-24 18:12:34 -0700220 if (size >= UINT32_MAX) {
Elliott Hughes0e55b452017-05-01 21:38:48 -0700221 LOG(FATAL) << "string size can't exceed 2^32 bytes: " << size;
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100222 }
Yifan Hong602b85a2016-10-24 13:40:01 -0700223 char *buf = (char *)malloc(size + 1);
224 memcpy(buf, data, size);
225 buf[size] = '\0';
226 mBuffer = buf;
Martijn Coenen72110162016-08-19 14:28:25 +0200227
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100228 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200229 mOwnsBuffer = true;
Yifan Hong602b85a2016-10-24 13:40:01 -0700230}
Martijn Coenen72110162016-08-19 14:28:25 +0200231
Yifan Hong602b85a2016-10-24 13:40:01 -0700232void hidl_string::moveFrom(hidl_string &&other) {
233 // assume my resources are freed.
234
Hridya Valsaraju01268892017-02-27 08:48:38 -0800235 mBuffer = std::move(other.mBuffer);
Yifan Hong602b85a2016-10-24 13:40:01 -0700236 mSize = other.mSize;
237 mOwnsBuffer = other.mOwnsBuffer;
238
239 other.mOwnsBuffer = false;
Hridya Valsaraju01268892017-02-27 08:48:38 -0800240 other.clear();
Martijn Coenen72110162016-08-19 14:28:25 +0200241}
242
243void hidl_string::clear() {
244 if (mOwnsBuffer && (mBuffer != kEmptyString)) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100245 free(const_cast<char *>(static_cast<const char *>(mBuffer)));
Martijn Coenen72110162016-08-19 14:28:25 +0200246 }
247
Yifan Hong602b85a2016-10-24 13:40:01 -0700248 mBuffer = kEmptyString;
Martijn Coenen72110162016-08-19 14:28:25 +0200249 mSize = 0;
Yifan Hong602b85a2016-10-24 13:40:01 -0700250 mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200251}
252
253void hidl_string::setToExternal(const char *data, size_t size) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100254 if (size > UINT32_MAX) {
Elliott Hughes0e55b452017-05-01 21:38:48 -0700255 LOG(FATAL) << "string size can't exceed 2^32 bytes: " << size;
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100256 }
Martijn Coenen72110162016-08-19 14:28:25 +0200257 clear();
258
Yifan Hong602b85a2016-10-24 13:40:01 -0700259 mBuffer = data;
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100260 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200261 mOwnsBuffer = false;
262}
263
264const char *hidl_string::c_str() const {
Yifan Hong602b85a2016-10-24 13:40:01 -0700265 return mBuffer;
Martijn Coenen72110162016-08-19 14:28:25 +0200266}
267
268size_t hidl_string::size() const {
269 return mSize;
270}
271
272bool hidl_string::empty() const {
273 return mSize == 0;
274}
275
Howard Chen9bc35c42017-10-13 14:21:46 +0800276sp<HidlMemory> HidlMemory::getInstance(hidl_memory&& mem) {
277 sp<HidlMemory> instance = new HidlMemory();
278 *instance = std::move(mem);
279 return instance;
280}
281
282sp<HidlMemory> HidlMemory::getInstance(const hidl_string& name, int fd, uint64_t size) {
283 native_handle_t* handle = native_handle_create(1, 0);
284 if (!handle) {
285 close(fd);
286 LOG(ERROR) << "native_handle_create fails";
287 return new HidlMemory();
288 }
289 handle->data[0] = fd;
290
291 hidl_handle hidlHandle;
292 hidlHandle.setTo(handle, true /* shouldOwn */);
293
294 sp<HidlMemory> instance = new HidlMemory(name, std::move(hidlHandle), size);
295 return instance;
296}
297
298// it's required to have at least one out-of-line method to avoid weak vtable
299HidlMemory::~HidlMemory() {
300 hidl_memory::~hidl_memory();
301}
302
Martijn Coenen72110162016-08-19 14:28:25 +0200303} // namespace hardware
304} // namespace android
305
306