blob: 68155cdfab0516361cf61e61d77fa13f0c093c68 [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 Hong44c0e572017-01-20 15:41:52 -080025#include <vintf/VendorManifest.h>
26#include <vintf/parse_string.h>
Martijn Coenen30791002016-12-01 15:40:46 +010027
Martijn Coenen72110162016-08-19 14:28:25 +020028namespace android {
29namespace hardware {
Yifan Hong20273f92017-01-30 14:13:19 -080030vintf::Transport getTransportForFrameworkPackages(const std::string &name) {
31 // TODO(b/34772739): check with VNDK team to see if this should be in an XML.
32 const static std::unordered_map<std::string, vintf::Transport> sTransports {
33 {"android.hidl.manager@1.0::IServiceManager", vintf::Transport::HWBINDER},
34 {"android.hidl.memory@1.0::IAllocator" , vintf::Transport::HWBINDER},
35 {"android.hidl.memory@1.0::IMapper" , vintf::Transport::PASSTHROUGH},
36 {"android.hidl.memory@1.0::IMemory" , vintf::Transport::PASSTHROUGH},
37 };
38 auto it = sTransports.find(name);
39 if (it == sTransports.end()) {
40 LOG(WARNING) << "getTransportForFrameworkPackages: Cannot find entry "
41 << name << " in the static map.";
42 return vintf::Transport::EMPTY;
43 } else {
44 LOG(INFO) << "getTransportForFrameworkPackages: " << name
45 << " declares transport method " << to_string(it->second);
46 }
47 return it->second;
48}
Martijn Coenen72110162016-08-19 14:28:25 +020049
Yifan Hong20273f92017-01-30 14:13:19 -080050vintf::Transport getTransportForHals(const FQName &fqName) {
51 const std::string package = fqName.package();
Yifan Hong44c0e572017-01-20 15:41:52 -080052 const vintf::VendorManifest *vm = vintf::VendorManifest::Get();
53 if (vm == nullptr) {
Steven Moreland01732732017-02-02 18:42:49 -080054 LOG(WARNING) << "getTransportFromManifest: Cannot find vendor interface manifest.";
Yifan Hong44c0e572017-01-20 15:41:52 -080055 return vintf::Transport::EMPTY;
56 }
Yifan Honge682a5a2017-02-13 18:14:39 +000057 if (!fqName.hasVersion()) {
Yifan Hong20273f92017-01-30 14:13:19 -080058 LOG(ERROR) << "getTransportFromManifest: " << fqName.string()
59 << " does not specify a version.";
60 return vintf::Transport::EMPTY;
61 }
Yifan Honge682a5a2017-02-13 18:14:39 +000062 vintf::Transport tr = vm->getTransport(package,
63 vintf::Version{fqName.getPackageMajorVersion(), fqName.getPackageMinorVersion()});
Yifan Hong44c0e572017-01-20 15:41:52 -080064 if (tr == vintf::Transport::EMPTY) {
65 LOG(WARNING) << "getTransportFromManifest: Cannot find entry "
Yifan Hong20273f92017-01-30 14:13:19 -080066 << package << fqName.atVersion() << " in vendor interface manifest.";
Yifan Hong44c0e572017-01-20 15:41:52 -080067 } else {
Yifan Hong20273f92017-01-30 14:13:19 -080068 LOG(INFO) << "getTransportFromManifest: " << package << fqName.atVersion()
Yifan Hong44c0e572017-01-20 15:41:52 -080069 << " declares transport method " << to_string(tr);
Yifan Hong20273f92017-01-30 14:13:19 -080070 }
Yifan Hong44c0e572017-01-20 15:41:52 -080071 return tr;
72}
73
Yifan Hong20273f92017-01-30 14:13:19 -080074vintf::Transport getTransport(const std::string &name) {
75 FQName fqName(name);
76 if (!fqName.isValid()) {
77 LOG(WARNING) << name << " is not a valid fully-qualified name.";
78 return vintf::Transport::EMPTY;
79 }
80 if (fqName.inPackage("android.hidl")) {
81 return getTransportForFrameworkPackages(name);
82 }
83 return getTransportForHals(fqName);
84}
85
Martijn Coenen04b91c02017-01-19 14:14:21 +010086hidl_handle::hidl_handle() {
87 mHandle = nullptr;
88 mOwnsHandle = false;
89}
90
91hidl_handle::~hidl_handle() {
92 freeHandle();
93}
94
95hidl_handle::hidl_handle(const native_handle_t *handle) {
96 mHandle = handle;
97 mOwnsHandle = false;
98}
99
100// copy constructor.
101hidl_handle::hidl_handle(const hidl_handle &other) {
102 mOwnsHandle = false;
103 *this = other;
104}
105
106// move constructor.
107hidl_handle::hidl_handle(hidl_handle &&other) {
108 mOwnsHandle = false;
109 *this = std::move(other);
110}
111
112// assignment operators
113hidl_handle &hidl_handle::operator=(const hidl_handle &other) {
114 if (this == &other) {
115 return *this;
116 }
117 freeHandle();
118 if (other.mHandle != nullptr) {
119 mHandle = native_handle_clone(other.mHandle);
120 if (mHandle == nullptr) {
121 LOG(FATAL) << "Failed to clone native_handle in hidl_handle.";
122 }
123 mOwnsHandle = true;
124 } else {
125 mHandle = nullptr;
126 mOwnsHandle = false;
127 }
128 return *this;
129}
130
131hidl_handle &hidl_handle::operator=(const native_handle_t *native_handle) {
132 freeHandle();
133 mHandle = native_handle;
134 mOwnsHandle = false;
135 return *this;
136}
137
138hidl_handle &hidl_handle::operator=(hidl_handle &&other) {
139 if (this != &other) {
140 freeHandle();
141 mHandle = other.mHandle;
142 mOwnsHandle = other.mOwnsHandle;
143 other.mHandle = nullptr;
144 other.mOwnsHandle = false;
145 }
146 return *this;
147}
148
149void hidl_handle::setTo(native_handle_t* handle, bool shouldOwn) {
150 mHandle = handle;
151 mOwnsHandle = shouldOwn;
152}
153
154const native_handle_t* hidl_handle::operator->() const {
155 return mHandle;
156}
157
158// implicit conversion to const native_handle_t*
159hidl_handle::operator const native_handle_t *() const {
160 return mHandle;
161}
162
163// explicit conversion
164const native_handle_t *hidl_handle::getNativeHandle() const {
165 return mHandle;
166}
167
168void hidl_handle::freeHandle() {
169 if (mOwnsHandle && mHandle != nullptr) {
170 // This can only be true if:
171 // 1. Somebody called setTo() with shouldOwn=true, so we know the handle
172 // wasn't const to begin with.
173 // 2. Copy/assignment from another hidl_handle, in which case we have
174 // cloned the handle.
175 // 3. Move constructor from another hidl_handle, in which case the original
176 // hidl_handle must have been non-const as well.
177 native_handle_t *handle = const_cast<native_handle_t*>(
178 static_cast<const native_handle_t*>(mHandle));
179 native_handle_close(handle);
180 native_handle_delete(handle);
181 mHandle = nullptr;
182 }
183}
184
Martijn Coenen72110162016-08-19 14:28:25 +0200185static const char *const kEmptyString = "";
186
187hidl_string::hidl_string()
Yifan Hong602b85a2016-10-24 13:40:01 -0700188 : mBuffer(kEmptyString),
Martijn Coenen72110162016-08-19 14:28:25 +0200189 mSize(0),
Yifan Hong602b85a2016-10-24 13:40:01 -0700190 mOwnsBuffer(false) {
Martijn Coenen72110162016-08-19 14:28:25 +0200191}
192
193hidl_string::~hidl_string() {
194 clear();
195}
196
Steven Morelande03c0872016-10-24 10:43:50 -0700197hidl_string::hidl_string(const char *s) : hidl_string() {
Steven Morelanda21d84f2017-02-16 09:23:45 -0800198 if (s == nullptr) {
199 return;
200 }
201
Yifan Hong602b85a2016-10-24 13:40:01 -0700202 copyFrom(s, strlen(s));
Steven Morelande03c0872016-10-24 10:43:50 -0700203}
204
Steven Moreland53120f72017-01-12 09:39:26 -0800205hidl_string::hidl_string(const char *s, size_t length) : hidl_string() {
206 copyFrom(s, length);
207}
208
Yifan Hong602b85a2016-10-24 13:40:01 -0700209hidl_string::hidl_string(const hidl_string &other): hidl_string() {
210 copyFrom(other.c_str(), other.size());
211}
212
213hidl_string::hidl_string(const std::string &s) : hidl_string() {
214 copyFrom(s.c_str(), s.size());
215}
216
217hidl_string::hidl_string(hidl_string &&other): hidl_string() {
218 moveFrom(std::forward<hidl_string>(other));
219}
220
221hidl_string &hidl_string::operator=(hidl_string &&other) {
222 if (this != &other) {
223 clear();
224 moveFrom(std::forward<hidl_string>(other));
225 }
226 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +0200227}
228
229hidl_string &hidl_string::operator=(const hidl_string &other) {
230 if (this != &other) {
Yifan Hong602b85a2016-10-24 13:40:01 -0700231 clear();
232 copyFrom(other.c_str(), other.size());
Martijn Coenen72110162016-08-19 14:28:25 +0200233 }
234
235 return *this;
236}
237
238hidl_string &hidl_string::operator=(const char *s) {
Yifan Hong602b85a2016-10-24 13:40:01 -0700239 clear();
240 copyFrom(s, strlen(s));
241 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +0200242}
243
Yifan Hong602b85a2016-10-24 13:40:01 -0700244hidl_string &hidl_string::operator=(const std::string &s) {
Martijn Coenen72110162016-08-19 14:28:25 +0200245 clear();
Yifan Hong602b85a2016-10-24 13:40:01 -0700246 copyFrom(s.c_str(), s.size());
247 return *this;
248}
Martijn Coenen72110162016-08-19 14:28:25 +0200249
Yifan Hong602b85a2016-10-24 13:40:01 -0700250hidl_string::operator std::string() const {
251 return std::string(mBuffer, mSize);
252}
253
254hidl_string::operator const char *() const {
255 return mBuffer;
256}
257
258void hidl_string::copyFrom(const char *data, size_t size) {
259 // assume my resources are freed.
260
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100261 if (size > UINT32_MAX) {
262 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
263 }
Yifan Hong602b85a2016-10-24 13:40:01 -0700264 char *buf = (char *)malloc(size + 1);
265 memcpy(buf, data, size);
266 buf[size] = '\0';
267 mBuffer = buf;
Martijn Coenen72110162016-08-19 14:28:25 +0200268
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100269 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200270 mOwnsBuffer = true;
Yifan Hong602b85a2016-10-24 13:40:01 -0700271}
Martijn Coenen72110162016-08-19 14:28:25 +0200272
Yifan Hong602b85a2016-10-24 13:40:01 -0700273void hidl_string::moveFrom(hidl_string &&other) {
274 // assume my resources are freed.
275
276 mBuffer = other.mBuffer;
277 mSize = other.mSize;
278 mOwnsBuffer = other.mOwnsBuffer;
279
280 other.mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200281}
282
283void hidl_string::clear() {
284 if (mOwnsBuffer && (mBuffer != kEmptyString)) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100285 free(const_cast<char *>(static_cast<const char *>(mBuffer)));
Martijn Coenen72110162016-08-19 14:28:25 +0200286 }
287
Yifan Hong602b85a2016-10-24 13:40:01 -0700288 mBuffer = kEmptyString;
Martijn Coenen72110162016-08-19 14:28:25 +0200289 mSize = 0;
Yifan Hong602b85a2016-10-24 13:40:01 -0700290 mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200291}
292
293void hidl_string::setToExternal(const char *data, size_t size) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100294 if (size > UINT32_MAX) {
295 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
296 }
Martijn Coenen72110162016-08-19 14:28:25 +0200297 clear();
298
Yifan Hong602b85a2016-10-24 13:40:01 -0700299 mBuffer = data;
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100300 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200301 mOwnsBuffer = false;
302}
303
304const char *hidl_string::c_str() const {
Yifan Hong602b85a2016-10-24 13:40:01 -0700305 return mBuffer;
Martijn Coenen72110162016-08-19 14:28:25 +0200306}
307
308size_t hidl_string::size() const {
309 return mSize;
310}
311
312bool hidl_string::empty() const {
313 return mSize == 0;
314}
315
Martijn Coenen72110162016-08-19 14:28:25 +0200316} // namespace hardware
317} // namespace android
318
319