blob: 61db8cc9e16704e370e6cbf843f528d3eeebad8c [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
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -070020#include <android-base/logging.h>
Yifan Hong44c0e572017-01-20 15:41:52 -080021#include <vintf/VendorManifest.h>
22#include <vintf/parse_string.h>
Martijn Coenen30791002016-12-01 15:40:46 +010023
Martijn Coenen4ca39a02016-11-11 15:58:51 +010024#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -070025#include <cutils/properties.h>
Steven Moreland337e6b62017-01-18 17:25:13 -080026#include <dlfcn.h>
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -070027#include <regex>
Yifan Hong602b85a2016-10-24 13:40:01 -070028#include <utility>
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -070029#endif
30
Martijn Coenen72110162016-08-19 14:28:25 +020031namespace android {
32namespace hardware {
33
Yifan Hong44c0e572017-01-20 15:41:52 -080034vintf::Transport getTransportFromManifest(const std::string &package) {
35 const vintf::VendorManifest *vm = vintf::VendorManifest::Get();
36 if (vm == nullptr) {
37 LOG(ERROR) << "getTransportFromManifest: Cannot find vendor interface manifest.";
38 return vintf::Transport::EMPTY;
39 }
40 vintf::Transport tr = vm->getTransport(package);
41 if (tr == vintf::Transport::EMPTY) {
42 LOG(WARNING) << "getTransportFromManifest: Cannot find entry "
43 << package << " in vendor interface manifest.";
44 } else {
45 LOG(INFO) << "getTransportFromManifest: " << package
46 << " declares transport method " << to_string(tr);
47 }
48 return tr;
49}
50
Martijn Coenen04b91c02017-01-19 14:14:21 +010051hidl_handle::hidl_handle() {
52 mHandle = nullptr;
53 mOwnsHandle = false;
54}
55
56hidl_handle::~hidl_handle() {
57 freeHandle();
58}
59
60hidl_handle::hidl_handle(const native_handle_t *handle) {
61 mHandle = handle;
62 mOwnsHandle = false;
63}
64
65// copy constructor.
66hidl_handle::hidl_handle(const hidl_handle &other) {
67 mOwnsHandle = false;
68 *this = other;
69}
70
71// move constructor.
72hidl_handle::hidl_handle(hidl_handle &&other) {
73 mOwnsHandle = false;
74 *this = std::move(other);
75}
76
77// assignment operators
78hidl_handle &hidl_handle::operator=(const hidl_handle &other) {
79 if (this == &other) {
80 return *this;
81 }
82 freeHandle();
83 if (other.mHandle != nullptr) {
84 mHandle = native_handle_clone(other.mHandle);
85 if (mHandle == nullptr) {
86 LOG(FATAL) << "Failed to clone native_handle in hidl_handle.";
87 }
88 mOwnsHandle = true;
89 } else {
90 mHandle = nullptr;
91 mOwnsHandle = false;
92 }
93 return *this;
94}
95
96hidl_handle &hidl_handle::operator=(const native_handle_t *native_handle) {
97 freeHandle();
98 mHandle = native_handle;
99 mOwnsHandle = false;
100 return *this;
101}
102
103hidl_handle &hidl_handle::operator=(hidl_handle &&other) {
104 if (this != &other) {
105 freeHandle();
106 mHandle = other.mHandle;
107 mOwnsHandle = other.mOwnsHandle;
108 other.mHandle = nullptr;
109 other.mOwnsHandle = false;
110 }
111 return *this;
112}
113
114void hidl_handle::setTo(native_handle_t* handle, bool shouldOwn) {
115 mHandle = handle;
116 mOwnsHandle = shouldOwn;
117}
118
119const native_handle_t* hidl_handle::operator->() const {
120 return mHandle;
121}
122
123// implicit conversion to const native_handle_t*
124hidl_handle::operator const native_handle_t *() const {
125 return mHandle;
126}
127
128// explicit conversion
129const native_handle_t *hidl_handle::getNativeHandle() const {
130 return mHandle;
131}
132
133void hidl_handle::freeHandle() {
134 if (mOwnsHandle && mHandle != nullptr) {
135 // This can only be true if:
136 // 1. Somebody called setTo() with shouldOwn=true, so we know the handle
137 // wasn't const to begin with.
138 // 2. Copy/assignment from another hidl_handle, in which case we have
139 // cloned the handle.
140 // 3. Move constructor from another hidl_handle, in which case the original
141 // hidl_handle must have been non-const as well.
142 native_handle_t *handle = const_cast<native_handle_t*>(
143 static_cast<const native_handle_t*>(mHandle));
144 native_handle_close(handle);
145 native_handle_delete(handle);
146 mHandle = nullptr;
147 }
148}
149
Martijn Coenen72110162016-08-19 14:28:25 +0200150static const char *const kEmptyString = "";
151
152hidl_string::hidl_string()
Yifan Hong602b85a2016-10-24 13:40:01 -0700153 : mBuffer(kEmptyString),
Martijn Coenen72110162016-08-19 14:28:25 +0200154 mSize(0),
Yifan Hong602b85a2016-10-24 13:40:01 -0700155 mOwnsBuffer(false) {
Martijn Coenen72110162016-08-19 14:28:25 +0200156}
157
158hidl_string::~hidl_string() {
159 clear();
160}
161
Steven Morelande03c0872016-10-24 10:43:50 -0700162hidl_string::hidl_string(const char *s) : hidl_string() {
Yifan Hong602b85a2016-10-24 13:40:01 -0700163 copyFrom(s, strlen(s));
Steven Morelande03c0872016-10-24 10:43:50 -0700164}
165
Steven Moreland53120f72017-01-12 09:39:26 -0800166hidl_string::hidl_string(const char *s, size_t length) : hidl_string() {
167 copyFrom(s, length);
168}
169
Yifan Hong602b85a2016-10-24 13:40:01 -0700170hidl_string::hidl_string(const hidl_string &other): hidl_string() {
171 copyFrom(other.c_str(), other.size());
172}
173
174hidl_string::hidl_string(const std::string &s) : hidl_string() {
175 copyFrom(s.c_str(), s.size());
176}
177
178hidl_string::hidl_string(hidl_string &&other): hidl_string() {
179 moveFrom(std::forward<hidl_string>(other));
180}
181
182hidl_string &hidl_string::operator=(hidl_string &&other) {
183 if (this != &other) {
184 clear();
185 moveFrom(std::forward<hidl_string>(other));
186 }
187 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +0200188}
189
190hidl_string &hidl_string::operator=(const hidl_string &other) {
191 if (this != &other) {
Yifan Hong602b85a2016-10-24 13:40:01 -0700192 clear();
193 copyFrom(other.c_str(), other.size());
Martijn Coenen72110162016-08-19 14:28:25 +0200194 }
195
196 return *this;
197}
198
199hidl_string &hidl_string::operator=(const char *s) {
Yifan Hong602b85a2016-10-24 13:40:01 -0700200 clear();
201 copyFrom(s, strlen(s));
202 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +0200203}
204
Yifan Hong602b85a2016-10-24 13:40:01 -0700205hidl_string &hidl_string::operator=(const std::string &s) {
Martijn Coenen72110162016-08-19 14:28:25 +0200206 clear();
Yifan Hong602b85a2016-10-24 13:40:01 -0700207 copyFrom(s.c_str(), s.size());
208 return *this;
209}
Martijn Coenen72110162016-08-19 14:28:25 +0200210
Steven Morelanda2a81842017-01-20 14:48:15 -0800211bool hidl_string::operator< (const hidl_string &rhs) const {
212 return strcmp(mBuffer, rhs.mBuffer) < 0;
213}
214
Yifan Hong602b85a2016-10-24 13:40:01 -0700215hidl_string::operator std::string() const {
216 return std::string(mBuffer, mSize);
217}
218
219hidl_string::operator const char *() const {
220 return mBuffer;
221}
222
223void hidl_string::copyFrom(const char *data, size_t size) {
224 // assume my resources are freed.
225
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100226 if (size > UINT32_MAX) {
227 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
228 }
Yifan Hong602b85a2016-10-24 13:40:01 -0700229 char *buf = (char *)malloc(size + 1);
230 memcpy(buf, data, size);
231 buf[size] = '\0';
232 mBuffer = buf;
Martijn Coenen72110162016-08-19 14:28:25 +0200233
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100234 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200235 mOwnsBuffer = true;
Yifan Hong602b85a2016-10-24 13:40:01 -0700236}
Martijn Coenen72110162016-08-19 14:28:25 +0200237
Yifan Hong602b85a2016-10-24 13:40:01 -0700238void hidl_string::moveFrom(hidl_string &&other) {
239 // assume my resources are freed.
240
241 mBuffer = other.mBuffer;
242 mSize = other.mSize;
243 mOwnsBuffer = other.mOwnsBuffer;
244
245 other.mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200246}
247
248void hidl_string::clear() {
249 if (mOwnsBuffer && (mBuffer != kEmptyString)) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100250 free(const_cast<char *>(static_cast<const char *>(mBuffer)));
Martijn Coenen72110162016-08-19 14:28:25 +0200251 }
252
Yifan Hong602b85a2016-10-24 13:40:01 -0700253 mBuffer = kEmptyString;
Martijn Coenen72110162016-08-19 14:28:25 +0200254 mSize = 0;
Yifan Hong602b85a2016-10-24 13:40:01 -0700255 mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200256}
257
258void hidl_string::setToExternal(const char *data, size_t size) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100259 if (size > UINT32_MAX) {
260 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
261 }
Martijn Coenen72110162016-08-19 14:28:25 +0200262 clear();
263
Yifan Hong602b85a2016-10-24 13:40:01 -0700264 mBuffer = data;
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100265 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200266 mOwnsBuffer = false;
267}
268
269const char *hidl_string::c_str() const {
Yifan Hong602b85a2016-10-24 13:40:01 -0700270 return mBuffer;
Martijn Coenen72110162016-08-19 14:28:25 +0200271}
272
273size_t hidl_string::size() const {
274 return mSize;
275}
276
277bool hidl_string::empty() const {
278 return mSize == 0;
279}
280
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700281// ----------------------------------------------------------------------
282// HidlInstrumentor implementation.
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800283HidlInstrumentor::HidlInstrumentor(const std::string &prefix)
284 : mInstrumentationLibPrefix(prefix) {
285 configureInstrumentation(false);
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700286}
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700287
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700288HidlInstrumentor:: ~HidlInstrumentor() {}
289
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800290void HidlInstrumentor::configureInstrumentation(bool log) {
291 bool enable_instrumentation = property_get_bool(
292 "hal.instrumentation.enable",
293 false);
294 if (enable_instrumentation != mEnableInstrumentation) {
295 mEnableInstrumentation = enable_instrumentation;
296 if (mEnableInstrumentation) {
297 if (log) {
298 LOG(INFO) << "Enable instrumentation.";
299 }
300 registerInstrumentationCallbacks (&mInstrumentationCallbacks);
301 } else {
302 if (log) {
303 LOG(INFO) << "Disable instrumentation.";
304 }
305 mInstrumentationCallbacks.clear();
306 }
307 }
308}
309
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700310void HidlInstrumentor::registerInstrumentationCallbacks(
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700311 std::vector<InstrumentationCallback> *instrumentationCallbacks) {
Dan Willemsen6365a872016-09-13 16:29:54 -0700312#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700313 std::vector<std::string> instrumentationLibPaths;
Zhuoyao Zhang8bed09f2016-10-26 18:12:47 -0700314 char instrumentation_lib_path[PROPERTY_VALUE_MAX];
315 if (property_get("hal.instrumentation.lib.path",
316 instrumentation_lib_path,
317 "") > 0) {
318 instrumentationLibPaths.push_back(instrumentation_lib_path);
319 } else {
320 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_SYSTEM);
321 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_VENDOR);
322 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_ODM);
323 }
324
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700325 for (auto path : instrumentationLibPaths) {
326 DIR *dir = opendir(path.c_str());
327 if (dir == 0) {
Steven Moreland7096f542016-11-07 11:20:33 -0800328 LOG(WARNING) << path << " does not exist. ";
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700329 return;
330 }
331
332 struct dirent *file;
333 while ((file = readdir(dir)) != NULL) {
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800334 if (!isInstrumentationLib(file))
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700335 continue;
336
337 void *handle = dlopen((path + file->d_name).c_str(), RTLD_NOW);
338 if (handle == nullptr) {
339 LOG(WARNING) << "couldn't load file: " << file->d_name
340 << " error: " << dlerror();
341 continue;
342 }
343 using cb_fun = void (*)(
344 const InstrumentationEvent,
345 const char *,
346 const char *,
347 const char *,
348 const char *,
349 std::vector<void *> *);
350 auto cb = (cb_fun)dlsym(handle, "HIDL_INSTRUMENTATION_FUNCTION");
351 if (cb == nullptr) {
352 LOG(WARNING)
353 << "couldn't find symbol: HIDL_INSTRUMENTATION_FUNCTION, "
354 "error: "
355 << dlerror();
356 continue;
357 }
358 instrumentationCallbacks->push_back(cb);
359 LOG(INFO) << "Register instrumentation callback from "
360 << file->d_name;
361 }
362 closedir(dir);
363 }
364#else
365 // No-op for user builds.
366 return;
367#endif
368}
369
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800370bool HidlInstrumentor::isInstrumentationLib(const dirent *file) {
Dan Willemsen6365a872016-09-13 16:29:54 -0700371#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700372 if (file->d_type != DT_REG) return false;
373 std::cmatch cm;
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800374 std::regex e("^" + mInstrumentationLibPrefix + "(.*).profiler.so$");
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700375 if (std::regex_match(file->d_name, cm, e)) return true;
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700376#endif
377 return false;
378}
379
Martijn Coenen72110162016-08-19 14:28:25 +0200380} // namespace hardware
381} // namespace android
382
383