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() : mHandle(nullptr), mOwnsHandle(false) {
39 memset(mPad, 0, sizeof(mPad));
40 }
41
~hidl_handle()42 hidl_handle::~hidl_handle() {
43 freeHandle();
44 }
45
hidl_handle(const native_handle_t * handle)46 hidl_handle::hidl_handle(const native_handle_t* handle) : hidl_handle() {
47 mHandle = handle;
48 mOwnsHandle = false;
49 }
50
51 // copy constructor.
hidl_handle(const hidl_handle & other)52 hidl_handle::hidl_handle(const hidl_handle& other) : hidl_handle() {
53 mOwnsHandle = false;
54 *this = other;
55 }
56
57 // move constructor.
hidl_handle(hidl_handle && other)58 hidl_handle::hidl_handle(hidl_handle&& other) noexcept : hidl_handle() {
59 mOwnsHandle = false;
60 *this = std::move(other);
61 }
62
63 // assignment operators
operator =(const hidl_handle & other)64 hidl_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) {
72 PLOG(FATAL) << "Failed to clone native_handle in hidl_handle";
73 }
74 mOwnsHandle = true;
75 } else {
76 mHandle = nullptr;
77 mOwnsHandle = false;
78 }
79 return *this;
80 }
81
operator =(const native_handle_t * native_handle)82 hidl_handle &hidl_handle::operator=(const native_handle_t *native_handle) {
83 freeHandle();
84 mHandle = native_handle;
85 mOwnsHandle = false;
86 return *this;
87 }
88
operator =(hidl_handle && other)89 hidl_handle& hidl_handle::operator=(hidl_handle&& other) noexcept {
90 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
setTo(native_handle_t * handle,bool shouldOwn)100 void hidl_handle::setTo(native_handle_t* handle, bool shouldOwn) {
101 freeHandle();
102 mHandle = handle;
103 mOwnsHandle = shouldOwn;
104 }
105
operator ->() const106 const native_handle_t* hidl_handle::operator->() const {
107 return mHandle;
108 }
109
110 // implicit conversion to const native_handle_t*
operator const native_handle_t*() const111 hidl_handle::operator const native_handle_t *() const {
112 return mHandle;
113 }
114
115 // explicit conversion
getNativeHandle() const116 const native_handle_t *hidl_handle::getNativeHandle() const {
117 return mHandle;
118 }
119
freeHandle()120 void 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
137 static const char *const kEmptyString = "";
138
hidl_string()139 hidl_string::hidl_string() : mBuffer(kEmptyString), mSize(0), mOwnsBuffer(false) {
140 memset(mPad, 0, sizeof(mPad));
141 }
142
~hidl_string()143 hidl_string::~hidl_string() {
144 clear();
145 }
146
hidl_string(const char * s)147 hidl_string::hidl_string(const char *s) : hidl_string() {
148 if (s == nullptr) {
149 return;
150 }
151
152 copyFrom(s, strlen(s));
153 }
154
hidl_string(const char * s,size_t length)155 hidl_string::hidl_string(const char *s, size_t length) : hidl_string() {
156 copyFrom(s, length);
157 }
158
hidl_string(const hidl_string & other)159 hidl_string::hidl_string(const hidl_string &other): hidl_string() {
160 copyFrom(other.c_str(), other.size());
161 }
162
hidl_string(const std::string & s)163 hidl_string::hidl_string(const std::string &s) : hidl_string() {
164 copyFrom(s.c_str(), s.size());
165 }
166
hidl_string(hidl_string && other)167 hidl_string::hidl_string(hidl_string&& other) noexcept : hidl_string() {
168 moveFrom(std::forward<hidl_string>(other));
169 }
170
operator =(hidl_string && other)171 hidl_string& hidl_string::operator=(hidl_string&& other) noexcept {
172 if (this != &other) {
173 clear();
174 moveFrom(std::forward<hidl_string>(other));
175 }
176 return *this;
177 }
178
operator =(const hidl_string & other)179 hidl_string &hidl_string::operator=(const hidl_string &other) {
180 if (this != &other) {
181 clear();
182 copyFrom(other.c_str(), other.size());
183 }
184
185 return *this;
186 }
187
operator =(const char * s)188 hidl_string &hidl_string::operator=(const char *s) {
189 clear();
190
191 if (s == nullptr) {
192 return *this;
193 }
194
195 copyFrom(s, strlen(s));
196 return *this;
197 }
198
operator =(const std::string & s)199 hidl_string &hidl_string::operator=(const std::string &s) {
200 clear();
201 copyFrom(s.c_str(), s.size());
202 return *this;
203 }
204
operator std::string() const205 hidl_string::operator std::string() const {
206 return std::string(mBuffer, mSize);
207 }
208
operator <<(std::ostream & os,const hidl_string & str)209 std::ostream& operator<<(std::ostream& os, const hidl_string& str) {
210 os << str.c_str();
211 return os;
212 }
213
copyFrom(const char * data,size_t size)214 void hidl_string::copyFrom(const char *data, size_t size) {
215 // assume my resources are freed.
216
217 if (size >= UINT32_MAX) {
218 LOG(FATAL) << "string size can't exceed 2^32 bytes: " << size;
219 }
220
221 if (size == 0) {
222 mBuffer = kEmptyString;
223 mSize = 0;
224 mOwnsBuffer = false;
225 return;
226 }
227
228 char *buf = (char *)malloc(size + 1);
229 memcpy(buf, data, size);
230 buf[size] = '\0';
231 mBuffer = buf;
232
233 mSize = static_cast<uint32_t>(size);
234 mOwnsBuffer = true;
235 }
236
moveFrom(hidl_string && other)237 void hidl_string::moveFrom(hidl_string &&other) {
238 // assume my resources are freed.
239
240 mBuffer = std::move(other.mBuffer);
241 mSize = other.mSize;
242 mOwnsBuffer = other.mOwnsBuffer;
243
244 other.mOwnsBuffer = false;
245 other.clear();
246 }
247
clear()248 void hidl_string::clear() {
249 if (mOwnsBuffer && (mBuffer != kEmptyString)) {
250 free(const_cast<char *>(static_cast<const char *>(mBuffer)));
251 }
252
253 mBuffer = kEmptyString;
254 mSize = 0;
255 mOwnsBuffer = false;
256 }
257
setToExternal(const char * data,size_t size)258 void hidl_string::setToExternal(const char *data, size_t size) {
259 if (size > UINT32_MAX) {
260 LOG(FATAL) << "string size can't exceed 2^32 bytes: " << size;
261 }
262
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
270 clear();
271
272 mBuffer = data;
273 mSize = static_cast<uint32_t>(size);
274 mOwnsBuffer = false;
275 }
276
c_str() const277 const char *hidl_string::c_str() const {
278 return mBuffer;
279 }
280
size() const281 size_t hidl_string::size() const {
282 return mSize;
283 }
284
empty() const285 bool hidl_string::empty() const {
286 return mSize == 0;
287 }
288
getInstance(const hidl_memory & mem)289 sp<HidlMemory> HidlMemory::getInstance(const hidl_memory& mem) {
290 sp<HidlMemory> instance = new HidlMemory();
291 instance->hidl_memory::operator=(mem);
292 return instance;
293 }
294
getInstance(hidl_memory && mem)295 sp<HidlMemory> HidlMemory::getInstance(hidl_memory&& mem) {
296 sp<HidlMemory> instance = new HidlMemory();
297 instance->hidl_memory::operator=(std::move(mem));
298 return instance;
299 }
300
getInstance(const hidl_string & name,int fd,uint64_t size)301 sp<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
HidlMemory()317 HidlMemory::HidlMemory() : hidl_memory() {}
318
HidlMemory(const hidl_string & name,hidl_handle && handle,size_t size)319 HidlMemory::HidlMemory(const hidl_string& name, hidl_handle&& handle, size_t size)
320 : hidl_memory(name, std::move(handle), size) {}
321
322 // it's required to have at least one out-of-line method to avoid weak vtable
~HidlMemory()323 HidlMemory::~HidlMemory() {}
324
325 } // namespace hardware
326 } // namespace android
327
328
329