blob: 547f7e7c300f49287433f5b7fdead4ee636b53fb [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(
Yifan Hong37b36202017-02-28 16:04:22 -080032 const FQName &fqName, const std::string &instanceName,
33 const std::string &manifestName,
Yifan Hong64a41d52017-02-27 18:52:44 -080034 const vintf::HalManifest *vm) {
Yifan Hong44c0e572017-01-20 15:41:52 -080035 if (vm == nullptr) {
Yifan Hong64a41d52017-02-27 18:52:44 -080036 LOG(WARNING) << "getTransportFromManifest: No " << manifestName << " manifest defined, "
37 << "using default transport for " << fqName.string();
Yifan Hong20273f92017-01-30 14:13:19 -080038 return vintf::Transport::EMPTY;
39 }
Yifan Hong64a41d52017-02-27 18:52:44 -080040 vintf::Transport tr = vm->getTransport(fqName.package(),
Yifan Hong37b36202017-02-28 16:04:22 -080041 vintf::Version{fqName.getPackageMajorVersion(), fqName.getPackageMinorVersion()},
42 fqName.name(), instanceName);
Yifan Hong44c0e572017-01-20 15:41:52 -080043 if (tr == vintf::Transport::EMPTY) {
Yifan Hong64a41d52017-02-27 18:52:44 -080044 LOG(WARNING) << "getTransportFromManifest: Cannot find entry "
45 << fqName.string()
46 << " in " << manifestName << " manifest, using default transport.";
Yifan Hong44c0e572017-01-20 15:41:52 -080047 } else {
Yifan Hong64a41d52017-02-27 18:52:44 -080048 LOG(DEBUG) << "getTransportFromManifest: " << fqName.string()
49 << " declares transport method " << to_string(tr)
50 << " in " << manifestName << " manifest";
Yifan Hong20273f92017-01-30 14:13:19 -080051 }
Yifan Hong44c0e572017-01-20 15:41:52 -080052 return tr;
53}
54
Yifan Hong37b36202017-02-28 16:04:22 -080055vintf::Transport getTransport(const std::string &interfaceName, const std::string &instanceName) {
56 FQName fqName(interfaceName);
Yifan Hong20273f92017-01-30 14:13:19 -080057 if (!fqName.isValid()) {
Yifan Hong37b36202017-02-28 16:04:22 -080058 LOG(ERROR) << "getTransport: " << interfaceName << " is not a valid fully-qualified name.";
Steven Moreland6d8960d2017-02-23 13:19:32 -080059 return vintf::Transport::EMPTY;
60 }
61 if (!fqName.hasVersion()) {
62 LOG(ERROR) << "getTransport: " << fqName.string()
63 << " does not specify a version. Using default transport.";
Yifan Hong20273f92017-01-30 14:13:19 -080064 return vintf::Transport::EMPTY;
65 }
Yifan Hong37b36202017-02-28 16:04:22 -080066 if (fqName.name().empty()) {
67 LOG(ERROR) << "getTransport: " << fqName.string()
68 << " does not specify an interface name. Using default transport.";
69 return vintf::Transport::EMPTY;
70 }
Yifan Hong64a41d52017-02-27 18:52:44 -080071 // TODO(b/34772739): modify the list if other packages are added to system/manifest.xml
Yifan Hong20273f92017-01-30 14:13:19 -080072 if (fqName.inPackage("android.hidl")) {
Yifan Hong37b36202017-02-28 16:04:22 -080073 return getTransportFromManifest(fqName, instanceName, "framework",
Yifan Hong64a41d52017-02-27 18:52:44 -080074 vintf::VintfObject::GetFrameworkHalManifest());
Yifan Hong20273f92017-01-30 14:13:19 -080075 }
Yifan Hong37b36202017-02-28 16:04:22 -080076 return getTransportFromManifest(fqName, instanceName, "device",
Yifan Hong64a41d52017-02-27 18:52:44 -080077 vintf::VintfObject::GetDeviceHalManifest());
Yifan Hong20273f92017-01-30 14:13:19 -080078}
79
Yifan Hong24332ef2017-03-07 16:22:19 -080080namespace details {
81bool debuggable() {
82#ifdef LIBHIDL_TARGET_DEBUGGABLE
83 return true;
84#else
85 return false;
86#endif
87}
88} // namespace details
89
Martijn Coenen04b91c02017-01-19 14:14:21 +010090hidl_handle::hidl_handle() {
91 mHandle = nullptr;
92 mOwnsHandle = false;
93}
94
95hidl_handle::~hidl_handle() {
96 freeHandle();
97}
98
99hidl_handle::hidl_handle(const native_handle_t *handle) {
100 mHandle = handle;
101 mOwnsHandle = false;
102}
103
104// copy constructor.
105hidl_handle::hidl_handle(const hidl_handle &other) {
106 mOwnsHandle = false;
107 *this = other;
108}
109
110// move constructor.
111hidl_handle::hidl_handle(hidl_handle &&other) {
112 mOwnsHandle = false;
113 *this = std::move(other);
114}
115
116// assignment operators
117hidl_handle &hidl_handle::operator=(const hidl_handle &other) {
118 if (this == &other) {
119 return *this;
120 }
121 freeHandle();
122 if (other.mHandle != nullptr) {
123 mHandle = native_handle_clone(other.mHandle);
124 if (mHandle == nullptr) {
125 LOG(FATAL) << "Failed to clone native_handle in hidl_handle.";
126 }
127 mOwnsHandle = true;
128 } else {
129 mHandle = nullptr;
130 mOwnsHandle = false;
131 }
132 return *this;
133}
134
135hidl_handle &hidl_handle::operator=(const native_handle_t *native_handle) {
136 freeHandle();
137 mHandle = native_handle;
138 mOwnsHandle = false;
139 return *this;
140}
141
142hidl_handle &hidl_handle::operator=(hidl_handle &&other) {
143 if (this != &other) {
144 freeHandle();
145 mHandle = other.mHandle;
146 mOwnsHandle = other.mOwnsHandle;
147 other.mHandle = nullptr;
148 other.mOwnsHandle = false;
149 }
150 return *this;
151}
152
153void hidl_handle::setTo(native_handle_t* handle, bool shouldOwn) {
154 mHandle = handle;
155 mOwnsHandle = shouldOwn;
156}
157
158const native_handle_t* hidl_handle::operator->() const {
159 return mHandle;
160}
161
162// implicit conversion to const native_handle_t*
163hidl_handle::operator const native_handle_t *() const {
164 return mHandle;
165}
166
167// explicit conversion
168const native_handle_t *hidl_handle::getNativeHandle() const {
169 return mHandle;
170}
171
172void hidl_handle::freeHandle() {
173 if (mOwnsHandle && mHandle != nullptr) {
174 // This can only be true if:
175 // 1. Somebody called setTo() with shouldOwn=true, so we know the handle
176 // wasn't const to begin with.
177 // 2. Copy/assignment from another hidl_handle, in which case we have
178 // cloned the handle.
179 // 3. Move constructor from another hidl_handle, in which case the original
180 // hidl_handle must have been non-const as well.
181 native_handle_t *handle = const_cast<native_handle_t*>(
182 static_cast<const native_handle_t*>(mHandle));
183 native_handle_close(handle);
184 native_handle_delete(handle);
185 mHandle = nullptr;
186 }
187}
188
Martijn Coenen72110162016-08-19 14:28:25 +0200189static const char *const kEmptyString = "";
190
191hidl_string::hidl_string()
Yifan Hong602b85a2016-10-24 13:40:01 -0700192 : mBuffer(kEmptyString),
Martijn Coenen72110162016-08-19 14:28:25 +0200193 mSize(0),
Yifan Hong602b85a2016-10-24 13:40:01 -0700194 mOwnsBuffer(false) {
Martijn Coenen72110162016-08-19 14:28:25 +0200195}
196
197hidl_string::~hidl_string() {
198 clear();
199}
200
Steven Morelande03c0872016-10-24 10:43:50 -0700201hidl_string::hidl_string(const char *s) : hidl_string() {
Steven Morelanda21d84f2017-02-16 09:23:45 -0800202 if (s == nullptr) {
203 return;
204 }
205
Yifan Hong602b85a2016-10-24 13:40:01 -0700206 copyFrom(s, strlen(s));
Steven Morelande03c0872016-10-24 10:43:50 -0700207}
208
Steven Moreland53120f72017-01-12 09:39:26 -0800209hidl_string::hidl_string(const char *s, size_t length) : hidl_string() {
210 copyFrom(s, length);
211}
212
Yifan Hong602b85a2016-10-24 13:40:01 -0700213hidl_string::hidl_string(const hidl_string &other): hidl_string() {
214 copyFrom(other.c_str(), other.size());
215}
216
217hidl_string::hidl_string(const std::string &s) : hidl_string() {
218 copyFrom(s.c_str(), s.size());
219}
220
221hidl_string::hidl_string(hidl_string &&other): hidl_string() {
222 moveFrom(std::forward<hidl_string>(other));
223}
224
225hidl_string &hidl_string::operator=(hidl_string &&other) {
226 if (this != &other) {
227 clear();
228 moveFrom(std::forward<hidl_string>(other));
229 }
230 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +0200231}
232
233hidl_string &hidl_string::operator=(const hidl_string &other) {
234 if (this != &other) {
Yifan Hong602b85a2016-10-24 13:40:01 -0700235 clear();
236 copyFrom(other.c_str(), other.size());
Martijn Coenen72110162016-08-19 14:28:25 +0200237 }
238
239 return *this;
240}
241
242hidl_string &hidl_string::operator=(const char *s) {
Yifan Hong602b85a2016-10-24 13:40:01 -0700243 clear();
Steven Moreland153f87a2017-02-28 09:42:26 -0800244
245 if (s == nullptr) {
246 return *this;
247 }
248
Yifan Hong602b85a2016-10-24 13:40:01 -0700249 copyFrom(s, strlen(s));
250 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +0200251}
252
Yifan Hong602b85a2016-10-24 13:40:01 -0700253hidl_string &hidl_string::operator=(const std::string &s) {
Martijn Coenen72110162016-08-19 14:28:25 +0200254 clear();
Yifan Hong602b85a2016-10-24 13:40:01 -0700255 copyFrom(s.c_str(), s.size());
256 return *this;
257}
Martijn Coenen72110162016-08-19 14:28:25 +0200258
Yifan Hong602b85a2016-10-24 13:40:01 -0700259hidl_string::operator std::string() const {
260 return std::string(mBuffer, mSize);
261}
262
263hidl_string::operator const char *() const {
264 return mBuffer;
265}
266
267void hidl_string::copyFrom(const char *data, size_t size) {
268 // assume my resources are freed.
269
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100270 if (size > UINT32_MAX) {
271 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
272 }
Yifan Hong602b85a2016-10-24 13:40:01 -0700273 char *buf = (char *)malloc(size + 1);
274 memcpy(buf, data, size);
275 buf[size] = '\0';
276 mBuffer = buf;
Martijn Coenen72110162016-08-19 14:28:25 +0200277
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100278 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200279 mOwnsBuffer = true;
Yifan Hong602b85a2016-10-24 13:40:01 -0700280}
Martijn Coenen72110162016-08-19 14:28:25 +0200281
Yifan Hong602b85a2016-10-24 13:40:01 -0700282void hidl_string::moveFrom(hidl_string &&other) {
283 // assume my resources are freed.
284
Hridya Valsaraju01268892017-02-27 08:48:38 -0800285 mBuffer = std::move(other.mBuffer);
Yifan Hong602b85a2016-10-24 13:40:01 -0700286 mSize = other.mSize;
287 mOwnsBuffer = other.mOwnsBuffer;
288
289 other.mOwnsBuffer = false;
Hridya Valsaraju01268892017-02-27 08:48:38 -0800290 other.clear();
Martijn Coenen72110162016-08-19 14:28:25 +0200291}
292
293void hidl_string::clear() {
294 if (mOwnsBuffer && (mBuffer != kEmptyString)) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100295 free(const_cast<char *>(static_cast<const char *>(mBuffer)));
Martijn Coenen72110162016-08-19 14:28:25 +0200296 }
297
Yifan Hong602b85a2016-10-24 13:40:01 -0700298 mBuffer = kEmptyString;
Martijn Coenen72110162016-08-19 14:28:25 +0200299 mSize = 0;
Yifan Hong602b85a2016-10-24 13:40:01 -0700300 mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200301}
302
303void hidl_string::setToExternal(const char *data, size_t size) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100304 if (size > UINT32_MAX) {
305 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
306 }
Martijn Coenen72110162016-08-19 14:28:25 +0200307 clear();
308
Yifan Hong602b85a2016-10-24 13:40:01 -0700309 mBuffer = data;
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100310 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200311 mOwnsBuffer = false;
312}
313
314const char *hidl_string::c_str() const {
Yifan Hong602b85a2016-10-24 13:40:01 -0700315 return mBuffer;
Martijn Coenen72110162016-08-19 14:28:25 +0200316}
317
318size_t hidl_string::size() const {
319 return mSize;
320}
321
322bool hidl_string::empty() const {
323 return mSize == 0;
324}
325
Martijn Coenen72110162016-08-19 14:28:25 +0200326} // namespace hardware
327} // namespace android
328
329