blob: 78faa2fc05c82ceb4f915802ea22f83b07261b99 [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
Steven Morelandf0dd1602019-04-26 14:51:24 -070038hidl_handle::hidl_handle() : mHandle(nullptr), mOwnsHandle(false) {
39 memset(mPad, 0, sizeof(mPad));
Martijn Coenen04b91c02017-01-19 14:14:21 +010040}
41
42hidl_handle::~hidl_handle() {
43 freeHandle();
44}
45
Steven Moreland5cc16912019-04-18 12:54:56 -070046hidl_handle::hidl_handle(const native_handle_t* handle) : hidl_handle() {
Martijn Coenen04b91c02017-01-19 14:14:21 +010047 mHandle = handle;
48 mOwnsHandle = false;
49}
50
51// copy constructor.
Steven Moreland5cc16912019-04-18 12:54:56 -070052hidl_handle::hidl_handle(const hidl_handle& other) : hidl_handle() {
Martijn Coenen04b91c02017-01-19 14:14:21 +010053 mOwnsHandle = false;
54 *this = other;
55}
56
57// move constructor.
Steven Moreland5cc16912019-04-18 12:54:56 -070058hidl_handle::hidl_handle(hidl_handle&& other) noexcept : hidl_handle() {
Martijn Coenen04b91c02017-01-19 14:14:21 +010059 mOwnsHandle = false;
60 *this = std::move(other);
61}
62
63// assignment operators
64hidl_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) {
Elliott Hughes0e55b452017-05-01 21:38:48 -070072 PLOG(FATAL) << "Failed to clone native_handle in hidl_handle";
Martijn Coenen04b91c02017-01-19 14:14:21 +010073 }
74 mOwnsHandle = true;
75 } else {
76 mHandle = nullptr;
77 mOwnsHandle = false;
78 }
79 return *this;
80}
81
82hidl_handle &hidl_handle::operator=(const native_handle_t *native_handle) {
83 freeHandle();
84 mHandle = native_handle;
85 mOwnsHandle = false;
86 return *this;
87}
88
Chih-Hung Hsieh3833f202018-09-25 12:03:06 -070089hidl_handle& hidl_handle::operator=(hidl_handle&& other) noexcept {
Martijn Coenen04b91c02017-01-19 14:14:21 +010090 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
100void hidl_handle::setTo(native_handle_t* handle, bool shouldOwn) {
Scott Randolphca37c0e2017-02-15 16:38:46 -0800101 freeHandle();
Martijn Coenen04b91c02017-01-19 14:14:21 +0100102 mHandle = handle;
103 mOwnsHandle = shouldOwn;
104}
105
106const native_handle_t* hidl_handle::operator->() const {
107 return mHandle;
108}
109
110// implicit conversion to const native_handle_t*
111hidl_handle::operator const native_handle_t *() const {
112 return mHandle;
113}
114
115// explicit conversion
116const native_handle_t *hidl_handle::getNativeHandle() const {
117 return mHandle;
118}
119
120void 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
Martijn Coenen72110162016-08-19 14:28:25 +0200137static const char *const kEmptyString = "";
138
Steven Morelandf0dd1602019-04-26 14:51:24 -0700139hidl_string::hidl_string() : mBuffer(kEmptyString), mSize(0), mOwnsBuffer(false) {
140 memset(mPad, 0, sizeof(mPad));
Martijn Coenen72110162016-08-19 14:28:25 +0200141}
142
143hidl_string::~hidl_string() {
144 clear();
145}
146
Steven Morelande03c0872016-10-24 10:43:50 -0700147hidl_string::hidl_string(const char *s) : hidl_string() {
Steven Morelanda21d84f2017-02-16 09:23:45 -0800148 if (s == nullptr) {
149 return;
150 }
151
Yifan Hong602b85a2016-10-24 13:40:01 -0700152 copyFrom(s, strlen(s));
Steven Morelande03c0872016-10-24 10:43:50 -0700153}
154
Steven Moreland53120f72017-01-12 09:39:26 -0800155hidl_string::hidl_string(const char *s, size_t length) : hidl_string() {
156 copyFrom(s, length);
157}
158
Yifan Hong602b85a2016-10-24 13:40:01 -0700159hidl_string::hidl_string(const hidl_string &other): hidl_string() {
160 copyFrom(other.c_str(), other.size());
161}
162
163hidl_string::hidl_string(const std::string &s) : hidl_string() {
164 copyFrom(s.c_str(), s.size());
165}
166
Chih-Hung Hsieh3833f202018-09-25 12:03:06 -0700167hidl_string::hidl_string(hidl_string&& other) noexcept : hidl_string() {
Yifan Hong602b85a2016-10-24 13:40:01 -0700168 moveFrom(std::forward<hidl_string>(other));
169}
170
Chih-Hung Hsieh3833f202018-09-25 12:03:06 -0700171hidl_string& hidl_string::operator=(hidl_string&& other) noexcept {
Yifan Hong602b85a2016-10-24 13:40:01 -0700172 if (this != &other) {
173 clear();
174 moveFrom(std::forward<hidl_string>(other));
175 }
176 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +0200177}
178
179hidl_string &hidl_string::operator=(const hidl_string &other) {
180 if (this != &other) {
Yifan Hong602b85a2016-10-24 13:40:01 -0700181 clear();
182 copyFrom(other.c_str(), other.size());
Martijn Coenen72110162016-08-19 14:28:25 +0200183 }
184
185 return *this;
186}
187
188hidl_string &hidl_string::operator=(const char *s) {
Yifan Hong602b85a2016-10-24 13:40:01 -0700189 clear();
Steven Moreland153f87a2017-02-28 09:42:26 -0800190
191 if (s == nullptr) {
192 return *this;
193 }
194
Yifan Hong602b85a2016-10-24 13:40:01 -0700195 copyFrom(s, strlen(s));
196 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +0200197}
198
Yifan Hong602b85a2016-10-24 13:40:01 -0700199hidl_string &hidl_string::operator=(const std::string &s) {
Martijn Coenen72110162016-08-19 14:28:25 +0200200 clear();
Yifan Hong602b85a2016-10-24 13:40:01 -0700201 copyFrom(s.c_str(), s.size());
202 return *this;
203}
Martijn Coenen72110162016-08-19 14:28:25 +0200204
Yifan Hong602b85a2016-10-24 13:40:01 -0700205hidl_string::operator std::string() const {
206 return std::string(mBuffer, mSize);
207}
208
Scott Randolph0c84ab42017-04-03 14:07:14 -0700209std::ostream& operator<<(std::ostream& os, const hidl_string& str) {
210 os << str.c_str();
211 return os;
Yifan Hong602b85a2016-10-24 13:40:01 -0700212}
213
214void hidl_string::copyFrom(const char *data, size_t size) {
215 // assume my resources are freed.
216
Steven Moreland98893802017-10-24 18:12:34 -0700217 if (size >= UINT32_MAX) {
Elliott Hughes0e55b452017-05-01 21:38:48 -0700218 LOG(FATAL) << "string size can't exceed 2^32 bytes: " << size;
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100219 }
Steven Morelande5b0df22021-03-29 17:28:48 +0000220
221 if (size == 0) {
222 mBuffer = kEmptyString;
223 mSize = 0;
224 mOwnsBuffer = false;
225 return;
226 }
227
Yifan Hong602b85a2016-10-24 13:40:01 -0700228 char *buf = (char *)malloc(size + 1);
229 memcpy(buf, data, size);
230 buf[size] = '\0';
231 mBuffer = buf;
Martijn Coenen72110162016-08-19 14:28:25 +0200232
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100233 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200234 mOwnsBuffer = true;
Yifan Hong602b85a2016-10-24 13:40:01 -0700235}
Martijn Coenen72110162016-08-19 14:28:25 +0200236
Yifan Hong602b85a2016-10-24 13:40:01 -0700237void hidl_string::moveFrom(hidl_string &&other) {
238 // assume my resources are freed.
239
Hridya Valsaraju01268892017-02-27 08:48:38 -0800240 mBuffer = std::move(other.mBuffer);
Yifan Hong602b85a2016-10-24 13:40:01 -0700241 mSize = other.mSize;
242 mOwnsBuffer = other.mOwnsBuffer;
243
244 other.mOwnsBuffer = false;
Hridya Valsaraju01268892017-02-27 08:48:38 -0800245 other.clear();
Martijn Coenen72110162016-08-19 14:28:25 +0200246}
247
248void hidl_string::clear() {
249 if (mOwnsBuffer && (mBuffer != kEmptyString)) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100250 free(const_cast<char *>(static_cast<const char *>(mBuffer)));
Martijn Coenen72110162016-08-19 14:28:25 +0200251 }
252
Yifan Hong602b85a2016-10-24 13:40:01 -0700253 mBuffer = kEmptyString;
Martijn Coenen72110162016-08-19 14:28:25 +0200254 mSize = 0;
Yifan Hong602b85a2016-10-24 13:40:01 -0700255 mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200256}
257
258void hidl_string::setToExternal(const char *data, size_t size) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100259 if (size > UINT32_MAX) {
Elliott Hughes0e55b452017-05-01 21:38:48 -0700260 LOG(FATAL) << "string size can't exceed 2^32 bytes: " << size;
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100261 }
Steven Moreland57c6fcb2018-03-06 11:31:33 -0800262
263 // When the binder driver copies this data into its buffer, it must
264 // have a zero byte there because the remote process will have a pointer
265 // directly into the read-only binder buffer. If we manually copy the
266 // data now to add a zero, then we lose the efficiency of this method.
267 // Checking here (it's also checked in the parceling code later).
268 CHECK(data[size] == '\0');
269
Martijn Coenen72110162016-08-19 14:28:25 +0200270 clear();
271
Yifan Hong602b85a2016-10-24 13:40:01 -0700272 mBuffer = data;
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100273 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200274 mOwnsBuffer = false;
275}
276
277const char *hidl_string::c_str() const {
Yifan Hong602b85a2016-10-24 13:40:01 -0700278 return mBuffer;
Martijn Coenen72110162016-08-19 14:28:25 +0200279}
280
281size_t hidl_string::size() const {
282 return mSize;
283}
284
285bool hidl_string::empty() const {
286 return mSize == 0;
287}
288
Howard Chen8e42f5a2017-11-09 13:58:28 +0800289sp<HidlMemory> HidlMemory::getInstance(const hidl_memory& mem) {
290 sp<HidlMemory> instance = new HidlMemory();
291 instance->hidl_memory::operator=(mem);
292 return instance;
293}
294
Howard Chen9bc35c42017-10-13 14:21:46 +0800295sp<HidlMemory> HidlMemory::getInstance(hidl_memory&& mem) {
296 sp<HidlMemory> instance = new HidlMemory();
Howard Chen8e42f5a2017-11-09 13:58:28 +0800297 instance->hidl_memory::operator=(std::move(mem));
Howard Chen9bc35c42017-10-13 14:21:46 +0800298 return instance;
299}
300
301sp<HidlMemory> HidlMemory::getInstance(const hidl_string& name, int fd, uint64_t size) {
302 native_handle_t* handle = native_handle_create(1, 0);
303 if (!handle) {
304 close(fd);
305 LOG(ERROR) << "native_handle_create fails";
306 return new HidlMemory();
307 }
308 handle->data[0] = fd;
309
310 hidl_handle hidlHandle;
311 hidlHandle.setTo(handle, true /* shouldOwn */);
312
313 sp<HidlMemory> instance = new HidlMemory(name, std::move(hidlHandle), size);
314 return instance;
315}
316
Howard Chen8e42f5a2017-11-09 13:58:28 +0800317HidlMemory::HidlMemory() : hidl_memory() {}
318
319HidlMemory::HidlMemory(const hidl_string& name, hidl_handle&& handle, size_t size)
320 : hidl_memory(name, std::move(handle), size) {}
321
Howard Chen9bc35c42017-10-13 14:21:46 +0800322// it's required to have at least one out-of-line method to avoid weak vtable
Alec Edgingtonaf789482018-06-14 21:03:14 +0100323HidlMemory::~HidlMemory() {}
Howard Chen9bc35c42017-10-13 14:21:46 +0800324
Martijn Coenen72110162016-08-19 14:28:25 +0200325} // namespace hardware
326} // namespace android
327
328