blob: 37f40c442db2f24777d76106147ebc70861104ca [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>
24#include <hidl-util/FQName.h>
Yifan Hong64a41d52017-02-27 18:52:44 -080025#include <vintf/VintfObject.h>
Yifan Hong44c0e572017-01-20 15:41:52 -080026#include <vintf/parse_string.h>
Martijn Coenen30791002016-12-01 15:40:46 +010027
Martijn Coenen72110162016-08-19 14:28:25 +020028namespace android {
29namespace hardware {
30
Yifan Hong64a41d52017-02-27 18:52:44 -080031vintf::Transport getTransportFromManifest(
32 const FQName &fqName, const std::string &manifestName,
33 const vintf::HalManifest *vm) {
Yifan Hong44c0e572017-01-20 15:41:52 -080034 if (vm == nullptr) {
Yifan Hong64a41d52017-02-27 18:52:44 -080035 LOG(WARNING) << "getTransportFromManifest: No " << manifestName << " manifest defined, "
36 << "using default transport for " << fqName.string();
Yifan Hong20273f92017-01-30 14:13:19 -080037 return vintf::Transport::EMPTY;
38 }
Yifan Hong64a41d52017-02-27 18:52:44 -080039 vintf::Transport tr = vm->getTransport(fqName.package(),
Yifan Honge682a5a2017-02-13 18:14:39 +000040 vintf::Version{fqName.getPackageMajorVersion(), fqName.getPackageMinorVersion()});
Yifan Hong44c0e572017-01-20 15:41:52 -080041 if (tr == vintf::Transport::EMPTY) {
Yifan Hong64a41d52017-02-27 18:52:44 -080042 LOG(WARNING) << "getTransportFromManifest: Cannot find entry "
43 << fqName.string()
44 << " in " << manifestName << " manifest, using default transport.";
Yifan Hong44c0e572017-01-20 15:41:52 -080045 } else {
Yifan Hong64a41d52017-02-27 18:52:44 -080046 LOG(DEBUG) << "getTransportFromManifest: " << fqName.string()
47 << " declares transport method " << to_string(tr)
48 << " in " << manifestName << " manifest";
Yifan Hong20273f92017-01-30 14:13:19 -080049 }
Yifan Hong44c0e572017-01-20 15:41:52 -080050 return tr;
51}
52
Yifan Hong20273f92017-01-30 14:13:19 -080053vintf::Transport getTransport(const std::string &name) {
54 FQName fqName(name);
55 if (!fqName.isValid()) {
Steven Moreland6d8960d2017-02-23 13:19:32 -080056 LOG(ERROR) << "getTransport: " << name << " is not a valid fully-qualified name.";
57 return vintf::Transport::EMPTY;
58 }
59 if (!fqName.hasVersion()) {
60 LOG(ERROR) << "getTransport: " << fqName.string()
61 << " does not specify a version. Using default transport.";
Yifan Hong20273f92017-01-30 14:13:19 -080062 return vintf::Transport::EMPTY;
63 }
Yifan Hong64a41d52017-02-27 18:52:44 -080064 // TODO(b/34772739): modify the list if other packages are added to system/manifest.xml
Yifan Hong20273f92017-01-30 14:13:19 -080065 if (fqName.inPackage("android.hidl")) {
Yifan Hong64a41d52017-02-27 18:52:44 -080066 return getTransportFromManifest(fqName, "framework",
67 vintf::VintfObject::GetFrameworkHalManifest());
Yifan Hong20273f92017-01-30 14:13:19 -080068 }
Yifan Hong64a41d52017-02-27 18:52:44 -080069 return getTransportFromManifest(fqName, "device",
70 vintf::VintfObject::GetDeviceHalManifest());
Yifan Hong20273f92017-01-30 14:13:19 -080071}
72
Martijn Coenen04b91c02017-01-19 14:14:21 +010073hidl_handle::hidl_handle() {
74 mHandle = nullptr;
75 mOwnsHandle = false;
76}
77
78hidl_handle::~hidl_handle() {
79 freeHandle();
80}
81
82hidl_handle::hidl_handle(const native_handle_t *handle) {
83 mHandle = handle;
84 mOwnsHandle = false;
85}
86
87// copy constructor.
88hidl_handle::hidl_handle(const hidl_handle &other) {
89 mOwnsHandle = false;
90 *this = other;
91}
92
93// move constructor.
94hidl_handle::hidl_handle(hidl_handle &&other) {
95 mOwnsHandle = false;
96 *this = std::move(other);
97}
98
99// assignment operators
100hidl_handle &hidl_handle::operator=(const hidl_handle &other) {
101 if (this == &other) {
102 return *this;
103 }
104 freeHandle();
105 if (other.mHandle != nullptr) {
106 mHandle = native_handle_clone(other.mHandle);
107 if (mHandle == nullptr) {
108 LOG(FATAL) << "Failed to clone native_handle in hidl_handle.";
109 }
110 mOwnsHandle = true;
111 } else {
112 mHandle = nullptr;
113 mOwnsHandle = false;
114 }
115 return *this;
116}
117
118hidl_handle &hidl_handle::operator=(const native_handle_t *native_handle) {
119 freeHandle();
120 mHandle = native_handle;
121 mOwnsHandle = false;
122 return *this;
123}
124
125hidl_handle &hidl_handle::operator=(hidl_handle &&other) {
126 if (this != &other) {
127 freeHandle();
128 mHandle = other.mHandle;
129 mOwnsHandle = other.mOwnsHandle;
130 other.mHandle = nullptr;
131 other.mOwnsHandle = false;
132 }
133 return *this;
134}
135
136void hidl_handle::setTo(native_handle_t* handle, bool shouldOwn) {
137 mHandle = handle;
138 mOwnsHandle = shouldOwn;
139}
140
141const native_handle_t* hidl_handle::operator->() const {
142 return mHandle;
143}
144
145// implicit conversion to const native_handle_t*
146hidl_handle::operator const native_handle_t *() const {
147 return mHandle;
148}
149
150// explicit conversion
151const native_handle_t *hidl_handle::getNativeHandle() const {
152 return mHandle;
153}
154
155void hidl_handle::freeHandle() {
156 if (mOwnsHandle && mHandle != nullptr) {
157 // This can only be true if:
158 // 1. Somebody called setTo() with shouldOwn=true, so we know the handle
159 // wasn't const to begin with.
160 // 2. Copy/assignment from another hidl_handle, in which case we have
161 // cloned the handle.
162 // 3. Move constructor from another hidl_handle, in which case the original
163 // hidl_handle must have been non-const as well.
164 native_handle_t *handle = const_cast<native_handle_t*>(
165 static_cast<const native_handle_t*>(mHandle));
166 native_handle_close(handle);
167 native_handle_delete(handle);
168 mHandle = nullptr;
169 }
170}
171
Martijn Coenen72110162016-08-19 14:28:25 +0200172static const char *const kEmptyString = "";
173
174hidl_string::hidl_string()
Yifan Hong602b85a2016-10-24 13:40:01 -0700175 : mBuffer(kEmptyString),
Martijn Coenen72110162016-08-19 14:28:25 +0200176 mSize(0),
Yifan Hong602b85a2016-10-24 13:40:01 -0700177 mOwnsBuffer(false) {
Martijn Coenen72110162016-08-19 14:28:25 +0200178}
179
180hidl_string::~hidl_string() {
181 clear();
182}
183
Steven Morelande03c0872016-10-24 10:43:50 -0700184hidl_string::hidl_string(const char *s) : hidl_string() {
Steven Morelanda21d84f2017-02-16 09:23:45 -0800185 if (s == nullptr) {
186 return;
187 }
188
Yifan Hong602b85a2016-10-24 13:40:01 -0700189 copyFrom(s, strlen(s));
Steven Morelande03c0872016-10-24 10:43:50 -0700190}
191
Steven Moreland53120f72017-01-12 09:39:26 -0800192hidl_string::hidl_string(const char *s, size_t length) : hidl_string() {
193 copyFrom(s, length);
194}
195
Yifan Hong602b85a2016-10-24 13:40:01 -0700196hidl_string::hidl_string(const hidl_string &other): hidl_string() {
197 copyFrom(other.c_str(), other.size());
198}
199
200hidl_string::hidl_string(const std::string &s) : hidl_string() {
201 copyFrom(s.c_str(), s.size());
202}
203
204hidl_string::hidl_string(hidl_string &&other): hidl_string() {
205 moveFrom(std::forward<hidl_string>(other));
206}
207
208hidl_string &hidl_string::operator=(hidl_string &&other) {
209 if (this != &other) {
210 clear();
211 moveFrom(std::forward<hidl_string>(other));
212 }
213 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +0200214}
215
216hidl_string &hidl_string::operator=(const hidl_string &other) {
217 if (this != &other) {
Yifan Hong602b85a2016-10-24 13:40:01 -0700218 clear();
219 copyFrom(other.c_str(), other.size());
Martijn Coenen72110162016-08-19 14:28:25 +0200220 }
221
222 return *this;
223}
224
225hidl_string &hidl_string::operator=(const char *s) {
Yifan Hong602b85a2016-10-24 13:40:01 -0700226 clear();
Steven Moreland153f87a2017-02-28 09:42:26 -0800227
228 if (s == nullptr) {
229 return *this;
230 }
231
Yifan Hong602b85a2016-10-24 13:40:01 -0700232 copyFrom(s, strlen(s));
233 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +0200234}
235
Yifan Hong602b85a2016-10-24 13:40:01 -0700236hidl_string &hidl_string::operator=(const std::string &s) {
Martijn Coenen72110162016-08-19 14:28:25 +0200237 clear();
Yifan Hong602b85a2016-10-24 13:40:01 -0700238 copyFrom(s.c_str(), s.size());
239 return *this;
240}
Martijn Coenen72110162016-08-19 14:28:25 +0200241
Yifan Hong602b85a2016-10-24 13:40:01 -0700242hidl_string::operator std::string() const {
243 return std::string(mBuffer, mSize);
244}
245
246hidl_string::operator const char *() const {
247 return mBuffer;
248}
249
250void hidl_string::copyFrom(const char *data, size_t size) {
251 // assume my resources are freed.
252
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100253 if (size > UINT32_MAX) {
254 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
255 }
Yifan Hong602b85a2016-10-24 13:40:01 -0700256 char *buf = (char *)malloc(size + 1);
257 memcpy(buf, data, size);
258 buf[size] = '\0';
259 mBuffer = buf;
Martijn Coenen72110162016-08-19 14:28:25 +0200260
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100261 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200262 mOwnsBuffer = true;
Yifan Hong602b85a2016-10-24 13:40:01 -0700263}
Martijn Coenen72110162016-08-19 14:28:25 +0200264
Yifan Hong602b85a2016-10-24 13:40:01 -0700265void hidl_string::moveFrom(hidl_string &&other) {
266 // assume my resources are freed.
267
Hridya Valsaraju01268892017-02-27 08:48:38 -0800268 mBuffer = std::move(other.mBuffer);
Yifan Hong602b85a2016-10-24 13:40:01 -0700269 mSize = other.mSize;
270 mOwnsBuffer = other.mOwnsBuffer;
271
272 other.mOwnsBuffer = false;
Hridya Valsaraju01268892017-02-27 08:48:38 -0800273 other.clear();
Martijn Coenen72110162016-08-19 14:28:25 +0200274}
275
276void hidl_string::clear() {
277 if (mOwnsBuffer && (mBuffer != kEmptyString)) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100278 free(const_cast<char *>(static_cast<const char *>(mBuffer)));
Martijn Coenen72110162016-08-19 14:28:25 +0200279 }
280
Yifan Hong602b85a2016-10-24 13:40:01 -0700281 mBuffer = kEmptyString;
Martijn Coenen72110162016-08-19 14:28:25 +0200282 mSize = 0;
Yifan Hong602b85a2016-10-24 13:40:01 -0700283 mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200284}
285
286void hidl_string::setToExternal(const char *data, size_t size) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100287 if (size > UINT32_MAX) {
288 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
289 }
Martijn Coenen72110162016-08-19 14:28:25 +0200290 clear();
291
Yifan Hong602b85a2016-10-24 13:40:01 -0700292 mBuffer = data;
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100293 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200294 mOwnsBuffer = false;
295}
296
297const char *hidl_string::c_str() const {
Yifan Hong602b85a2016-10-24 13:40:01 -0700298 return mBuffer;
Martijn Coenen72110162016-08-19 14:28:25 +0200299}
300
301size_t hidl_string::size() const {
302 return mSize;
303}
304
305bool hidl_string::empty() const {
306 return mSize == 0;
307}
308
Martijn Coenen72110162016-08-19 14:28:25 +0200309} // namespace hardware
310} // namespace android
311
312