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