blob: 6f0483882fc0831aa70b17433356d6d23fbed3ba [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 Hong8e0cfc62017-02-17 10:18:54 -080025#include <vintf/HalManifest.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 {
Yifan Hong20273f92017-01-30 14:13:19 -080030vintf::Transport getTransportForFrameworkPackages(const std::string &name) {
Steven Moreland346cf512017-02-16 19:23:24 -080031 // TODO(b/34772739): move to framework vintf
Yifan Hong20273f92017-01-30 14:13:19 -080032 const static std::unordered_map<std::string, vintf::Transport> sTransports {
33 {"android.hidl.manager@1.0::IServiceManager", vintf::Transport::HWBINDER},
Steven Moreland346cf512017-02-16 19:23:24 -080034 {"android.hidl.allocator@1.0::IAllocator" , vintf::Transport::HWBINDER},
Yifan Hong20273f92017-01-30 14:13:19 -080035 {"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()) {
Steven Moreland6d8960d2017-02-23 13:19:32 -080040 LOG(ERROR) << "getTransportForFrameworkPackages: Cannot find entry "
41 << name << " in the static map. Using default transport.";
Yifan Hong20273f92017-01-30 14:13:19 -080042 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 Hong8e0cfc62017-02-17 10:18:54 -080052 const vintf::HalManifest *vm = vintf::HalManifest::Get();
Yifan Hong44c0e572017-01-20 15:41:52 -080053 if (vm == nullptr) {
Steven Moreland6d8960d2017-02-23 13:19:32 -080054 LOG(WARNING) << "getTransportForHals: No VINTF defined, using default transport for "
55 << fqName.string() << ".";
Yifan Hong20273f92017-01-30 14:13:19 -080056 return vintf::Transport::EMPTY;
57 }
Yifan Honge682a5a2017-02-13 18:14:39 +000058 vintf::Transport tr = vm->getTransport(package,
59 vintf::Version{fqName.getPackageMajorVersion(), fqName.getPackageMinorVersion()});
Yifan Hong44c0e572017-01-20 15:41:52 -080060 if (tr == vintf::Transport::EMPTY) {
Steven Moreland6d8960d2017-02-23 13:19:32 -080061 LOG(WARNING) << "getTransportForHals: Cannot find entry "
62 << package << fqName.atVersion()
63 << " in vendor interface manifest. Using default transport.";
Yifan Hong44c0e572017-01-20 15:41:52 -080064 } else {
Steven Moreland6d8960d2017-02-23 13:19:32 -080065 LOG(INFO) << "getTransportForHals: " << package << fqName.atVersion()
Yifan Hong44c0e572017-01-20 15:41:52 -080066 << " declares transport method " << to_string(tr);
Yifan Hong20273f92017-01-30 14:13:19 -080067 }
Yifan Hong44c0e572017-01-20 15:41:52 -080068 return tr;
69}
70
Yifan Hong20273f92017-01-30 14:13:19 -080071vintf::Transport getTransport(const std::string &name) {
72 FQName fqName(name);
73 if (!fqName.isValid()) {
Steven Moreland6d8960d2017-02-23 13:19:32 -080074 LOG(ERROR) << "getTransport: " << name << " is not a valid fully-qualified name.";
75 return vintf::Transport::EMPTY;
76 }
77 if (!fqName.hasVersion()) {
78 LOG(ERROR) << "getTransport: " << fqName.string()
79 << " does not specify a version. Using default transport.";
Yifan Hong20273f92017-01-30 14:13:19 -080080 return vintf::Transport::EMPTY;
81 }
82 if (fqName.inPackage("android.hidl")) {
83 return getTransportForFrameworkPackages(name);
84 }
85 return getTransportForHals(fqName);
86}
87
Martijn Coenen04b91c02017-01-19 14:14:21 +010088hidl_handle::hidl_handle() {
89 mHandle = nullptr;
90 mOwnsHandle = false;
91}
92
93hidl_handle::~hidl_handle() {
94 freeHandle();
95}
96
97hidl_handle::hidl_handle(const native_handle_t *handle) {
98 mHandle = handle;
99 mOwnsHandle = false;
100}
101
102// copy constructor.
103hidl_handle::hidl_handle(const hidl_handle &other) {
104 mOwnsHandle = false;
105 *this = other;
106}
107
108// move constructor.
109hidl_handle::hidl_handle(hidl_handle &&other) {
110 mOwnsHandle = false;
111 *this = std::move(other);
112}
113
114// assignment operators
115hidl_handle &hidl_handle::operator=(const hidl_handle &other) {
116 if (this == &other) {
117 return *this;
118 }
119 freeHandle();
120 if (other.mHandle != nullptr) {
121 mHandle = native_handle_clone(other.mHandle);
122 if (mHandle == nullptr) {
123 LOG(FATAL) << "Failed to clone native_handle in hidl_handle.";
124 }
125 mOwnsHandle = true;
126 } else {
127 mHandle = nullptr;
128 mOwnsHandle = false;
129 }
130 return *this;
131}
132
133hidl_handle &hidl_handle::operator=(const native_handle_t *native_handle) {
134 freeHandle();
135 mHandle = native_handle;
136 mOwnsHandle = false;
137 return *this;
138}
139
140hidl_handle &hidl_handle::operator=(hidl_handle &&other) {
141 if (this != &other) {
142 freeHandle();
143 mHandle = other.mHandle;
144 mOwnsHandle = other.mOwnsHandle;
145 other.mHandle = nullptr;
146 other.mOwnsHandle = false;
147 }
148 return *this;
149}
150
151void hidl_handle::setTo(native_handle_t* handle, bool shouldOwn) {
152 mHandle = handle;
153 mOwnsHandle = shouldOwn;
154}
155
156const native_handle_t* hidl_handle::operator->() const {
157 return mHandle;
158}
159
160// implicit conversion to const native_handle_t*
161hidl_handle::operator const native_handle_t *() const {
162 return mHandle;
163}
164
165// explicit conversion
166const native_handle_t *hidl_handle::getNativeHandle() const {
167 return mHandle;
168}
169
170void hidl_handle::freeHandle() {
171 if (mOwnsHandle && mHandle != nullptr) {
172 // This can only be true if:
173 // 1. Somebody called setTo() with shouldOwn=true, so we know the handle
174 // wasn't const to begin with.
175 // 2. Copy/assignment from another hidl_handle, in which case we have
176 // cloned the handle.
177 // 3. Move constructor from another hidl_handle, in which case the original
178 // hidl_handle must have been non-const as well.
179 native_handle_t *handle = const_cast<native_handle_t*>(
180 static_cast<const native_handle_t*>(mHandle));
181 native_handle_close(handle);
182 native_handle_delete(handle);
183 mHandle = nullptr;
184 }
185}
186
Martijn Coenen72110162016-08-19 14:28:25 +0200187static const char *const kEmptyString = "";
188
189hidl_string::hidl_string()
Yifan Hong602b85a2016-10-24 13:40:01 -0700190 : mBuffer(kEmptyString),
Martijn Coenen72110162016-08-19 14:28:25 +0200191 mSize(0),
Yifan Hong602b85a2016-10-24 13:40:01 -0700192 mOwnsBuffer(false) {
Martijn Coenen72110162016-08-19 14:28:25 +0200193}
194
195hidl_string::~hidl_string() {
196 clear();
197}
198
Steven Morelande03c0872016-10-24 10:43:50 -0700199hidl_string::hidl_string(const char *s) : hidl_string() {
Steven Morelanda21d84f2017-02-16 09:23:45 -0800200 if (s == nullptr) {
201 return;
202 }
203
Yifan Hong602b85a2016-10-24 13:40:01 -0700204 copyFrom(s, strlen(s));
Steven Morelande03c0872016-10-24 10:43:50 -0700205}
206
Steven Moreland53120f72017-01-12 09:39:26 -0800207hidl_string::hidl_string(const char *s, size_t length) : hidl_string() {
208 copyFrom(s, length);
209}
210
Yifan Hong602b85a2016-10-24 13:40:01 -0700211hidl_string::hidl_string(const hidl_string &other): hidl_string() {
212 copyFrom(other.c_str(), other.size());
213}
214
215hidl_string::hidl_string(const std::string &s) : hidl_string() {
216 copyFrom(s.c_str(), s.size());
217}
218
219hidl_string::hidl_string(hidl_string &&other): hidl_string() {
220 moveFrom(std::forward<hidl_string>(other));
221}
222
223hidl_string &hidl_string::operator=(hidl_string &&other) {
224 if (this != &other) {
225 clear();
226 moveFrom(std::forward<hidl_string>(other));
227 }
228 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +0200229}
230
231hidl_string &hidl_string::operator=(const hidl_string &other) {
232 if (this != &other) {
Yifan Hong602b85a2016-10-24 13:40:01 -0700233 clear();
234 copyFrom(other.c_str(), other.size());
Martijn Coenen72110162016-08-19 14:28:25 +0200235 }
236
237 return *this;
238}
239
240hidl_string &hidl_string::operator=(const char *s) {
Yifan Hong602b85a2016-10-24 13:40:01 -0700241 clear();
Steven Moreland153f87a2017-02-28 09:42:26 -0800242
243 if (s == nullptr) {
244 return *this;
245 }
246
Yifan Hong602b85a2016-10-24 13:40:01 -0700247 copyFrom(s, strlen(s));
248 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +0200249}
250
Yifan Hong602b85a2016-10-24 13:40:01 -0700251hidl_string &hidl_string::operator=(const std::string &s) {
Martijn Coenen72110162016-08-19 14:28:25 +0200252 clear();
Yifan Hong602b85a2016-10-24 13:40:01 -0700253 copyFrom(s.c_str(), s.size());
254 return *this;
255}
Martijn Coenen72110162016-08-19 14:28:25 +0200256
Yifan Hong602b85a2016-10-24 13:40:01 -0700257hidl_string::operator std::string() const {
258 return std::string(mBuffer, mSize);
259}
260
261hidl_string::operator const char *() const {
262 return mBuffer;
263}
264
265void hidl_string::copyFrom(const char *data, size_t size) {
266 // assume my resources are freed.
267
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100268 if (size > UINT32_MAX) {
269 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
270 }
Yifan Hong602b85a2016-10-24 13:40:01 -0700271 char *buf = (char *)malloc(size + 1);
272 memcpy(buf, data, size);
273 buf[size] = '\0';
274 mBuffer = buf;
Martijn Coenen72110162016-08-19 14:28:25 +0200275
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100276 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200277 mOwnsBuffer = true;
Yifan Hong602b85a2016-10-24 13:40:01 -0700278}
Martijn Coenen72110162016-08-19 14:28:25 +0200279
Yifan Hong602b85a2016-10-24 13:40:01 -0700280void hidl_string::moveFrom(hidl_string &&other) {
281 // assume my resources are freed.
282
283 mBuffer = other.mBuffer;
284 mSize = other.mSize;
285 mOwnsBuffer = other.mOwnsBuffer;
286
287 other.mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200288}
289
290void hidl_string::clear() {
291 if (mOwnsBuffer && (mBuffer != kEmptyString)) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100292 free(const_cast<char *>(static_cast<const char *>(mBuffer)));
Martijn Coenen72110162016-08-19 14:28:25 +0200293 }
294
Yifan Hong602b85a2016-10-24 13:40:01 -0700295 mBuffer = kEmptyString;
Martijn Coenen72110162016-08-19 14:28:25 +0200296 mSize = 0;
Yifan Hong602b85a2016-10-24 13:40:01 -0700297 mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200298}
299
300void hidl_string::setToExternal(const char *data, size_t size) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100301 if (size > UINT32_MAX) {
302 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
303 }
Martijn Coenen72110162016-08-19 14:28:25 +0200304 clear();
305
Yifan Hong602b85a2016-10-24 13:40:01 -0700306 mBuffer = data;
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100307 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200308 mOwnsBuffer = false;
309}
310
311const char *hidl_string::c_str() const {
Yifan Hong602b85a2016-10-24 13:40:01 -0700312 return mBuffer;
Martijn Coenen72110162016-08-19 14:28:25 +0200313}
314
315size_t hidl_string::size() const {
316 return mSize;
317}
318
319bool hidl_string::empty() const {
320 return mSize == 0;
321}
322
Martijn Coenen72110162016-08-19 14:28:25 +0200323} // namespace hardware
324} // namespace android
325
326