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 memset(this, 0, sizeof(*this));
40 // mHandle = nullptr;
41 // mOwnsHandle = false;
42 }
43
~hidl_handle()44 hidl_handle::~hidl_handle() {
45 freeHandle();
46 }
47
hidl_handle(const native_handle_t * handle)48 hidl_handle::hidl_handle(const native_handle_t* handle) : hidl_handle() {
49 mHandle = handle;
50 mOwnsHandle = false;
51 }
52
53 // copy constructor.
hidl_handle(const hidl_handle & other)54 hidl_handle::hidl_handle(const hidl_handle& other) : hidl_handle() {
55 mOwnsHandle = false;
56 *this = other;
57 }
58
59 // move constructor.
hidl_handle(hidl_handle && other)60 hidl_handle::hidl_handle(hidl_handle&& other) noexcept : hidl_handle() {
61 mOwnsHandle = false;
62 *this = std::move(other);
63 }
64
65 // assignment operators
operator =(const hidl_handle & other)66 hidl_handle &hidl_handle::operator=(const hidl_handle &other) {
67 if (this == &other) {
68 return *this;
69 }
70 freeHandle();
71 if (other.mHandle != nullptr) {
72 mHandle = native_handle_clone(other.mHandle);
73 if (mHandle == nullptr) {
74 PLOG(FATAL) << "Failed to clone native_handle in hidl_handle";
75 }
76 mOwnsHandle = true;
77 } else {
78 mHandle = nullptr;
79 mOwnsHandle = false;
80 }
81 return *this;
82 }
83
operator =(const native_handle_t * native_handle)84 hidl_handle &hidl_handle::operator=(const native_handle_t *native_handle) {
85 freeHandle();
86 mHandle = native_handle;
87 mOwnsHandle = false;
88 return *this;
89 }
90
operator =(hidl_handle && other)91 hidl_handle& hidl_handle::operator=(hidl_handle&& other) noexcept {
92 if (this != &other) {
93 freeHandle();
94 mHandle = other.mHandle;
95 mOwnsHandle = other.mOwnsHandle;
96 other.mHandle = nullptr;
97 other.mOwnsHandle = false;
98 }
99 return *this;
100 }
101
setTo(native_handle_t * handle,bool shouldOwn)102 void hidl_handle::setTo(native_handle_t* handle, bool shouldOwn) {
103 freeHandle();
104 mHandle = handle;
105 mOwnsHandle = shouldOwn;
106 }
107
operator ->() const108 const native_handle_t* hidl_handle::operator->() const {
109 return mHandle;
110 }
111
112 // implicit conversion to const native_handle_t*
operator const native_handle_t*() const113 hidl_handle::operator const native_handle_t *() const {
114 return mHandle;
115 }
116
117 // explicit conversion
getNativeHandle() const118 const native_handle_t *hidl_handle::getNativeHandle() const {
119 return mHandle;
120 }
121
freeHandle()122 void hidl_handle::freeHandle() {
123 if (mOwnsHandle && mHandle != nullptr) {
124 // This can only be true if:
125 // 1. Somebody called setTo() with shouldOwn=true, so we know the handle
126 // wasn't const to begin with.
127 // 2. Copy/assignment from another hidl_handle, in which case we have
128 // cloned the handle.
129 // 3. Move constructor from another hidl_handle, in which case the original
130 // hidl_handle must have been non-const as well.
131 native_handle_t *handle = const_cast<native_handle_t*>(
132 static_cast<const native_handle_t*>(mHandle));
133 native_handle_close(handle);
134 native_handle_delete(handle);
135 mHandle = nullptr;
136 }
137 }
138
139 static const char *const kEmptyString = "";
140
hidl_string()141 hidl_string::hidl_string() {
142 memset(this, 0, sizeof(*this));
143 // mSize is zero
144 // mOwnsBuffer is false
145 mBuffer = kEmptyString;
146 }
147
~hidl_string()148 hidl_string::~hidl_string() {
149 clear();
150 }
151
hidl_string(const char * s)152 hidl_string::hidl_string(const char *s) : hidl_string() {
153 if (s == nullptr) {
154 return;
155 }
156
157 copyFrom(s, strlen(s));
158 }
159
hidl_string(const char * s,size_t length)160 hidl_string::hidl_string(const char *s, size_t length) : hidl_string() {
161 copyFrom(s, length);
162 }
163
hidl_string(const hidl_string & other)164 hidl_string::hidl_string(const hidl_string &other): hidl_string() {
165 copyFrom(other.c_str(), other.size());
166 }
167
hidl_string(const std::string & s)168 hidl_string::hidl_string(const std::string &s) : hidl_string() {
169 copyFrom(s.c_str(), s.size());
170 }
171
hidl_string(hidl_string && other)172 hidl_string::hidl_string(hidl_string&& other) noexcept : hidl_string() {
173 moveFrom(std::forward<hidl_string>(other));
174 }
175
operator =(hidl_string && other)176 hidl_string& hidl_string::operator=(hidl_string&& other) noexcept {
177 if (this != &other) {
178 clear();
179 moveFrom(std::forward<hidl_string>(other));
180 }
181 return *this;
182 }
183
operator =(const hidl_string & other)184 hidl_string &hidl_string::operator=(const hidl_string &other) {
185 if (this != &other) {
186 clear();
187 copyFrom(other.c_str(), other.size());
188 }
189
190 return *this;
191 }
192
operator =(const char * s)193 hidl_string &hidl_string::operator=(const char *s) {
194 clear();
195
196 if (s == nullptr) {
197 return *this;
198 }
199
200 copyFrom(s, strlen(s));
201 return *this;
202 }
203
operator =(const std::string & s)204 hidl_string &hidl_string::operator=(const std::string &s) {
205 clear();
206 copyFrom(s.c_str(), s.size());
207 return *this;
208 }
209
operator std::string() const210 hidl_string::operator std::string() const {
211 return std::string(mBuffer, mSize);
212 }
213
operator <<(std::ostream & os,const hidl_string & str)214 std::ostream& operator<<(std::ostream& os, const hidl_string& str) {
215 os << str.c_str();
216 return os;
217 }
218
copyFrom(const char * data,size_t size)219 void hidl_string::copyFrom(const char *data, size_t size) {
220 // assume my resources are freed.
221
222 if (size >= UINT32_MAX) {
223 LOG(FATAL) << "string size can't exceed 2^32 bytes: " << size;
224 }
225 char *buf = (char *)malloc(size + 1);
226 memcpy(buf, data, size);
227 buf[size] = '\0';
228 mBuffer = buf;
229
230 mSize = static_cast<uint32_t>(size);
231 mOwnsBuffer = true;
232 }
233
moveFrom(hidl_string && other)234 void hidl_string::moveFrom(hidl_string &&other) {
235 // assume my resources are freed.
236
237 mBuffer = std::move(other.mBuffer);
238 mSize = other.mSize;
239 mOwnsBuffer = other.mOwnsBuffer;
240
241 other.mOwnsBuffer = false;
242 other.clear();
243 }
244
clear()245 void hidl_string::clear() {
246 if (mOwnsBuffer && (mBuffer != kEmptyString)) {
247 free(const_cast<char *>(static_cast<const char *>(mBuffer)));
248 }
249
250 mBuffer = kEmptyString;
251 mSize = 0;
252 mOwnsBuffer = false;
253 }
254
setToExternal(const char * data,size_t size)255 void hidl_string::setToExternal(const char *data, size_t size) {
256 if (size > UINT32_MAX) {
257 LOG(FATAL) << "string size can't exceed 2^32 bytes: " << size;
258 }
259
260 // When the binder driver copies this data into its buffer, it must
261 // have a zero byte there because the remote process will have a pointer
262 // directly into the read-only binder buffer. If we manually copy the
263 // data now to add a zero, then we lose the efficiency of this method.
264 // Checking here (it's also checked in the parceling code later).
265 CHECK(data[size] == '\0');
266
267 clear();
268
269 mBuffer = data;
270 mSize = static_cast<uint32_t>(size);
271 mOwnsBuffer = false;
272 }
273
c_str() const274 const char *hidl_string::c_str() const {
275 return mBuffer;
276 }
277
size() const278 size_t hidl_string::size() const {
279 return mSize;
280 }
281
empty() const282 bool hidl_string::empty() const {
283 return mSize == 0;
284 }
285
getInstance(const hidl_memory & mem)286 sp<HidlMemory> HidlMemory::getInstance(const hidl_memory& mem) {
287 sp<HidlMemory> instance = new HidlMemory();
288 instance->hidl_memory::operator=(mem);
289 return instance;
290 }
291
getInstance(hidl_memory && mem)292 sp<HidlMemory> HidlMemory::getInstance(hidl_memory&& mem) {
293 sp<HidlMemory> instance = new HidlMemory();
294 instance->hidl_memory::operator=(std::move(mem));
295 return instance;
296 }
297
getInstance(const hidl_string & name,int fd,uint64_t size)298 sp<HidlMemory> HidlMemory::getInstance(const hidl_string& name, int fd, uint64_t size) {
299 native_handle_t* handle = native_handle_create(1, 0);
300 if (!handle) {
301 close(fd);
302 LOG(ERROR) << "native_handle_create fails";
303 return new HidlMemory();
304 }
305 handle->data[0] = fd;
306
307 hidl_handle hidlHandle;
308 hidlHandle.setTo(handle, true /* shouldOwn */);
309
310 sp<HidlMemory> instance = new HidlMemory(name, std::move(hidlHandle), size);
311 return instance;
312 }
313
HidlMemory()314 HidlMemory::HidlMemory() : hidl_memory() {}
315
HidlMemory(const hidl_string & name,hidl_handle && handle,size_t size)316 HidlMemory::HidlMemory(const hidl_string& name, hidl_handle&& handle, size_t size)
317 : hidl_memory(name, std::move(handle), size) {}
318
319 // it's required to have at least one out-of-line method to avoid weak vtable
~HidlMemory()320 HidlMemory::~HidlMemory() {}
321
322 } // namespace hardware
323 } // namespace android
324
325
326