blob: a89e88b2e43efa958b7d82aaa12497dcac212292 [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 Hongfba24952017-01-20 15:41:52 -080021#include <vintf/VendorManifest.h>
Martijn Coenen30791002016-12-01 15:40:46 +010022
Martijn Coenen4ca39a02016-11-11 15:58:51 +010023#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -070024#include <cutils/properties.h>
Steven Moreland337e6b62017-01-18 17:25:13 -080025#include <dlfcn.h>
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -070026#include <regex>
Yifan Hong602b85a2016-10-24 13:40:01 -070027#include <utility>
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -070028#endif
29
Martijn Coenen72110162016-08-19 14:28:25 +020030namespace android {
31namespace hardware {
32
Yifan Hongfba24952017-01-20 15:41:52 -080033vintf::Transport getTransportFromManifest(const std::string &iface) {
34 const vintf::VendorManifest *vm = vintf::VendorManifest::Get();
35 if (vm == nullptr) {
36 LOG(ERROR) << "Cannot find vendor interface manifest.";
37 return vintf::Transport::EMPTY;
38 }
39 auto it = vm->hals.find(iface);
40 if (it == vm->hals.end()) {
41 LOG(ERROR) << "Vendor interface manifest does not contain entry for " << iface;
42 return vintf::Transport::EMPTY;
43 }
44 return it->second.transport;
45}
46
Martijn Coenen72110162016-08-19 14:28:25 +020047static const char *const kEmptyString = "";
48
49hidl_string::hidl_string()
Yifan Hong602b85a2016-10-24 13:40:01 -070050 : mBuffer(kEmptyString),
Martijn Coenen72110162016-08-19 14:28:25 +020051 mSize(0),
Yifan Hong602b85a2016-10-24 13:40:01 -070052 mOwnsBuffer(false) {
Martijn Coenen72110162016-08-19 14:28:25 +020053}
54
55hidl_string::~hidl_string() {
56 clear();
57}
58
Steven Morelande03c0872016-10-24 10:43:50 -070059hidl_string::hidl_string(const char *s) : hidl_string() {
Yifan Hong602b85a2016-10-24 13:40:01 -070060 copyFrom(s, strlen(s));
Steven Morelande03c0872016-10-24 10:43:50 -070061}
62
Steven Moreland53120f72017-01-12 09:39:26 -080063hidl_string::hidl_string(const char *s, size_t length) : hidl_string() {
64 copyFrom(s, length);
65}
66
Yifan Hong602b85a2016-10-24 13:40:01 -070067hidl_string::hidl_string(const hidl_string &other): hidl_string() {
68 copyFrom(other.c_str(), other.size());
69}
70
71hidl_string::hidl_string(const std::string &s) : hidl_string() {
72 copyFrom(s.c_str(), s.size());
73}
74
75hidl_string::hidl_string(hidl_string &&other): hidl_string() {
76 moveFrom(std::forward<hidl_string>(other));
77}
78
79hidl_string &hidl_string::operator=(hidl_string &&other) {
80 if (this != &other) {
81 clear();
82 moveFrom(std::forward<hidl_string>(other));
83 }
84 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +020085}
86
87hidl_string &hidl_string::operator=(const hidl_string &other) {
88 if (this != &other) {
Yifan Hong602b85a2016-10-24 13:40:01 -070089 clear();
90 copyFrom(other.c_str(), other.size());
Martijn Coenen72110162016-08-19 14:28:25 +020091 }
92
93 return *this;
94}
95
96hidl_string &hidl_string::operator=(const char *s) {
Yifan Hong602b85a2016-10-24 13:40:01 -070097 clear();
98 copyFrom(s, strlen(s));
99 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +0200100}
101
Yifan Hong602b85a2016-10-24 13:40:01 -0700102hidl_string &hidl_string::operator=(const std::string &s) {
Martijn Coenen72110162016-08-19 14:28:25 +0200103 clear();
Yifan Hong602b85a2016-10-24 13:40:01 -0700104 copyFrom(s.c_str(), s.size());
105 return *this;
106}
Martijn Coenen72110162016-08-19 14:28:25 +0200107
Steven Morelanda2a81842017-01-20 14:48:15 -0800108bool hidl_string::operator< (const hidl_string &rhs) const {
109 return strcmp(mBuffer, rhs.mBuffer) < 0;
110}
111
Yifan Hong602b85a2016-10-24 13:40:01 -0700112hidl_string::operator std::string() const {
113 return std::string(mBuffer, mSize);
114}
115
116hidl_string::operator const char *() const {
117 return mBuffer;
118}
119
120void hidl_string::copyFrom(const char *data, size_t size) {
121 // assume my resources are freed.
122
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100123 if (size > UINT32_MAX) {
124 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
125 }
Yifan Hong602b85a2016-10-24 13:40:01 -0700126 char *buf = (char *)malloc(size + 1);
127 memcpy(buf, data, size);
128 buf[size] = '\0';
129 mBuffer = buf;
Martijn Coenen72110162016-08-19 14:28:25 +0200130
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100131 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200132 mOwnsBuffer = true;
Yifan Hong602b85a2016-10-24 13:40:01 -0700133}
Martijn Coenen72110162016-08-19 14:28:25 +0200134
Yifan Hong602b85a2016-10-24 13:40:01 -0700135void hidl_string::moveFrom(hidl_string &&other) {
136 // assume my resources are freed.
137
138 mBuffer = other.mBuffer;
139 mSize = other.mSize;
140 mOwnsBuffer = other.mOwnsBuffer;
141
142 other.mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200143}
144
145void hidl_string::clear() {
146 if (mOwnsBuffer && (mBuffer != kEmptyString)) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100147 free(const_cast<char *>(static_cast<const char *>(mBuffer)));
Martijn Coenen72110162016-08-19 14:28:25 +0200148 }
149
Yifan Hong602b85a2016-10-24 13:40:01 -0700150 mBuffer = kEmptyString;
Martijn Coenen72110162016-08-19 14:28:25 +0200151 mSize = 0;
Yifan Hong602b85a2016-10-24 13:40:01 -0700152 mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200153}
154
155void hidl_string::setToExternal(const char *data, size_t size) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100156 if (size > UINT32_MAX) {
157 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
158 }
Martijn Coenen72110162016-08-19 14:28:25 +0200159 clear();
160
Yifan Hong602b85a2016-10-24 13:40:01 -0700161 mBuffer = data;
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100162 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200163 mOwnsBuffer = false;
164}
165
166const char *hidl_string::c_str() const {
Yifan Hong602b85a2016-10-24 13:40:01 -0700167 return mBuffer;
Martijn Coenen72110162016-08-19 14:28:25 +0200168}
169
170size_t hidl_string::size() const {
171 return mSize;
172}
173
174bool hidl_string::empty() const {
175 return mSize == 0;
176}
177
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700178// ----------------------------------------------------------------------
179// HidlInstrumentor implementation.
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800180HidlInstrumentor::HidlInstrumentor(const std::string &prefix)
181 : mInstrumentationLibPrefix(prefix) {
182 configureInstrumentation(false);
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700183}
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700184
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700185HidlInstrumentor:: ~HidlInstrumentor() {}
186
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800187void HidlInstrumentor::configureInstrumentation(bool log) {
188 bool enable_instrumentation = property_get_bool(
189 "hal.instrumentation.enable",
190 false);
191 if (enable_instrumentation != mEnableInstrumentation) {
192 mEnableInstrumentation = enable_instrumentation;
193 if (mEnableInstrumentation) {
194 if (log) {
195 LOG(INFO) << "Enable instrumentation.";
196 }
197 registerInstrumentationCallbacks (&mInstrumentationCallbacks);
198 } else {
199 if (log) {
200 LOG(INFO) << "Disable instrumentation.";
201 }
202 mInstrumentationCallbacks.clear();
203 }
204 }
205}
206
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700207void HidlInstrumentor::registerInstrumentationCallbacks(
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700208 std::vector<InstrumentationCallback> *instrumentationCallbacks) {
Dan Willemsen6365a872016-09-13 16:29:54 -0700209#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700210 std::vector<std::string> instrumentationLibPaths;
Zhuoyao Zhang8bed09f2016-10-26 18:12:47 -0700211 char instrumentation_lib_path[PROPERTY_VALUE_MAX];
212 if (property_get("hal.instrumentation.lib.path",
213 instrumentation_lib_path,
214 "") > 0) {
215 instrumentationLibPaths.push_back(instrumentation_lib_path);
216 } else {
217 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_SYSTEM);
218 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_VENDOR);
219 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_ODM);
220 }
221
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700222 for (auto path : instrumentationLibPaths) {
223 DIR *dir = opendir(path.c_str());
224 if (dir == 0) {
Steven Moreland7096f542016-11-07 11:20:33 -0800225 LOG(WARNING) << path << " does not exist. ";
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700226 return;
227 }
228
229 struct dirent *file;
230 while ((file = readdir(dir)) != NULL) {
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800231 if (!isInstrumentationLib(file))
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700232 continue;
233
234 void *handle = dlopen((path + file->d_name).c_str(), RTLD_NOW);
235 if (handle == nullptr) {
236 LOG(WARNING) << "couldn't load file: " << file->d_name
237 << " error: " << dlerror();
238 continue;
239 }
240 using cb_fun = void (*)(
241 const InstrumentationEvent,
242 const char *,
243 const char *,
244 const char *,
245 const char *,
246 std::vector<void *> *);
247 auto cb = (cb_fun)dlsym(handle, "HIDL_INSTRUMENTATION_FUNCTION");
248 if (cb == nullptr) {
249 LOG(WARNING)
250 << "couldn't find symbol: HIDL_INSTRUMENTATION_FUNCTION, "
251 "error: "
252 << dlerror();
253 continue;
254 }
255 instrumentationCallbacks->push_back(cb);
256 LOG(INFO) << "Register instrumentation callback from "
257 << file->d_name;
258 }
259 closedir(dir);
260 }
261#else
262 // No-op for user builds.
263 return;
264#endif
265}
266
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800267bool HidlInstrumentor::isInstrumentationLib(const dirent *file) {
Dan Willemsen6365a872016-09-13 16:29:54 -0700268#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700269 if (file->d_type != DT_REG) return false;
270 std::cmatch cm;
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800271 std::regex e("^" + mInstrumentationLibPrefix + "(.*).profiler.so$");
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700272 if (std::regex_match(file->d_name, cm, e)) return true;
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700273#endif
274 return false;
275}
276
Martijn Coenen72110162016-08-19 14:28:25 +0200277} // namespace hardware
278} // namespace android
279
280