blob: 593380bd6d1025d7ea427ff5e9835f38528bdfed [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 Coenen72110162016-08-19 14:28:25 +020051static const char *const kEmptyString = "";
52
53hidl_string::hidl_string()
Yifan Hong602b85a2016-10-24 13:40:01 -070054 : mBuffer(kEmptyString),
Martijn Coenen72110162016-08-19 14:28:25 +020055 mSize(0),
Yifan Hong602b85a2016-10-24 13:40:01 -070056 mOwnsBuffer(false) {
Martijn Coenen72110162016-08-19 14:28:25 +020057}
58
59hidl_string::~hidl_string() {
60 clear();
61}
62
Steven Morelande03c0872016-10-24 10:43:50 -070063hidl_string::hidl_string(const char *s) : hidl_string() {
Yifan Hong602b85a2016-10-24 13:40:01 -070064 copyFrom(s, strlen(s));
Steven Morelande03c0872016-10-24 10:43:50 -070065}
66
Steven Moreland53120f72017-01-12 09:39:26 -080067hidl_string::hidl_string(const char *s, size_t length) : hidl_string() {
68 copyFrom(s, length);
69}
70
Yifan Hong602b85a2016-10-24 13:40:01 -070071hidl_string::hidl_string(const hidl_string &other): hidl_string() {
72 copyFrom(other.c_str(), other.size());
73}
74
75hidl_string::hidl_string(const std::string &s) : hidl_string() {
76 copyFrom(s.c_str(), s.size());
77}
78
79hidl_string::hidl_string(hidl_string &&other): hidl_string() {
80 moveFrom(std::forward<hidl_string>(other));
81}
82
83hidl_string &hidl_string::operator=(hidl_string &&other) {
84 if (this != &other) {
85 clear();
86 moveFrom(std::forward<hidl_string>(other));
87 }
88 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +020089}
90
91hidl_string &hidl_string::operator=(const hidl_string &other) {
92 if (this != &other) {
Yifan Hong602b85a2016-10-24 13:40:01 -070093 clear();
94 copyFrom(other.c_str(), other.size());
Martijn Coenen72110162016-08-19 14:28:25 +020095 }
96
97 return *this;
98}
99
100hidl_string &hidl_string::operator=(const char *s) {
Yifan Hong602b85a2016-10-24 13:40:01 -0700101 clear();
102 copyFrom(s, strlen(s));
103 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +0200104}
105
Yifan Hong602b85a2016-10-24 13:40:01 -0700106hidl_string &hidl_string::operator=(const std::string &s) {
Martijn Coenen72110162016-08-19 14:28:25 +0200107 clear();
Yifan Hong602b85a2016-10-24 13:40:01 -0700108 copyFrom(s.c_str(), s.size());
109 return *this;
110}
Martijn Coenen72110162016-08-19 14:28:25 +0200111
Steven Morelanda2a81842017-01-20 14:48:15 -0800112bool hidl_string::operator< (const hidl_string &rhs) const {
113 return strcmp(mBuffer, rhs.mBuffer) < 0;
114}
115
Yifan Hong602b85a2016-10-24 13:40:01 -0700116hidl_string::operator std::string() const {
117 return std::string(mBuffer, mSize);
118}
119
120hidl_string::operator const char *() const {
121 return mBuffer;
122}
123
124void hidl_string::copyFrom(const char *data, size_t size) {
125 // assume my resources are freed.
126
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100127 if (size > UINT32_MAX) {
128 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
129 }
Yifan Hong602b85a2016-10-24 13:40:01 -0700130 char *buf = (char *)malloc(size + 1);
131 memcpy(buf, data, size);
132 buf[size] = '\0';
133 mBuffer = buf;
Martijn Coenen72110162016-08-19 14:28:25 +0200134
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100135 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200136 mOwnsBuffer = true;
Yifan Hong602b85a2016-10-24 13:40:01 -0700137}
Martijn Coenen72110162016-08-19 14:28:25 +0200138
Yifan Hong602b85a2016-10-24 13:40:01 -0700139void hidl_string::moveFrom(hidl_string &&other) {
140 // assume my resources are freed.
141
142 mBuffer = other.mBuffer;
143 mSize = other.mSize;
144 mOwnsBuffer = other.mOwnsBuffer;
145
146 other.mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200147}
148
149void hidl_string::clear() {
150 if (mOwnsBuffer && (mBuffer != kEmptyString)) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100151 free(const_cast<char *>(static_cast<const char *>(mBuffer)));
Martijn Coenen72110162016-08-19 14:28:25 +0200152 }
153
Yifan Hong602b85a2016-10-24 13:40:01 -0700154 mBuffer = kEmptyString;
Martijn Coenen72110162016-08-19 14:28:25 +0200155 mSize = 0;
Yifan Hong602b85a2016-10-24 13:40:01 -0700156 mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200157}
158
159void hidl_string::setToExternal(const char *data, size_t size) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100160 if (size > UINT32_MAX) {
161 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
162 }
Martijn Coenen72110162016-08-19 14:28:25 +0200163 clear();
164
Yifan Hong602b85a2016-10-24 13:40:01 -0700165 mBuffer = data;
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100166 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200167 mOwnsBuffer = false;
168}
169
170const char *hidl_string::c_str() const {
Yifan Hong602b85a2016-10-24 13:40:01 -0700171 return mBuffer;
Martijn Coenen72110162016-08-19 14:28:25 +0200172}
173
174size_t hidl_string::size() const {
175 return mSize;
176}
177
178bool hidl_string::empty() const {
179 return mSize == 0;
180}
181
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700182// ----------------------------------------------------------------------
183// HidlInstrumentor implementation.
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800184HidlInstrumentor::HidlInstrumentor(const std::string &prefix)
185 : mInstrumentationLibPrefix(prefix) {
186 configureInstrumentation(false);
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700187}
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700188
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700189HidlInstrumentor:: ~HidlInstrumentor() {}
190
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800191void HidlInstrumentor::configureInstrumentation(bool log) {
192 bool enable_instrumentation = property_get_bool(
193 "hal.instrumentation.enable",
194 false);
195 if (enable_instrumentation != mEnableInstrumentation) {
196 mEnableInstrumentation = enable_instrumentation;
197 if (mEnableInstrumentation) {
198 if (log) {
199 LOG(INFO) << "Enable instrumentation.";
200 }
201 registerInstrumentationCallbacks (&mInstrumentationCallbacks);
202 } else {
203 if (log) {
204 LOG(INFO) << "Disable instrumentation.";
205 }
206 mInstrumentationCallbacks.clear();
207 }
208 }
209}
210
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700211void HidlInstrumentor::registerInstrumentationCallbacks(
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700212 std::vector<InstrumentationCallback> *instrumentationCallbacks) {
Dan Willemsen6365a872016-09-13 16:29:54 -0700213#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700214 std::vector<std::string> instrumentationLibPaths;
Zhuoyao Zhang8bed09f2016-10-26 18:12:47 -0700215 char instrumentation_lib_path[PROPERTY_VALUE_MAX];
216 if (property_get("hal.instrumentation.lib.path",
217 instrumentation_lib_path,
218 "") > 0) {
219 instrumentationLibPaths.push_back(instrumentation_lib_path);
220 } else {
221 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_SYSTEM);
222 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_VENDOR);
223 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_ODM);
224 }
225
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700226 for (auto path : instrumentationLibPaths) {
227 DIR *dir = opendir(path.c_str());
228 if (dir == 0) {
Steven Moreland7096f542016-11-07 11:20:33 -0800229 LOG(WARNING) << path << " does not exist. ";
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700230 return;
231 }
232
233 struct dirent *file;
234 while ((file = readdir(dir)) != NULL) {
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800235 if (!isInstrumentationLib(file))
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700236 continue;
237
238 void *handle = dlopen((path + file->d_name).c_str(), RTLD_NOW);
239 if (handle == nullptr) {
240 LOG(WARNING) << "couldn't load file: " << file->d_name
241 << " error: " << dlerror();
242 continue;
243 }
244 using cb_fun = void (*)(
245 const InstrumentationEvent,
246 const char *,
247 const char *,
248 const char *,
249 const char *,
250 std::vector<void *> *);
251 auto cb = (cb_fun)dlsym(handle, "HIDL_INSTRUMENTATION_FUNCTION");
252 if (cb == nullptr) {
253 LOG(WARNING)
254 << "couldn't find symbol: HIDL_INSTRUMENTATION_FUNCTION, "
255 "error: "
256 << dlerror();
257 continue;
258 }
259 instrumentationCallbacks->push_back(cb);
260 LOG(INFO) << "Register instrumentation callback from "
261 << file->d_name;
262 }
263 closedir(dir);
264 }
265#else
266 // No-op for user builds.
267 return;
268#endif
269}
270
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800271bool HidlInstrumentor::isInstrumentationLib(const dirent *file) {
Dan Willemsen6365a872016-09-13 16:29:54 -0700272#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700273 if (file->d_type != DT_REG) return false;
274 std::cmatch cm;
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800275 std::regex e("^" + mInstrumentationLibPrefix + "(.*).profiler.so$");
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700276 if (std::regex_match(file->d_name, cm, e)) return true;
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700277#endif
278 return false;
279}
280
Martijn Coenen72110162016-08-19 14:28:25 +0200281} // namespace hardware
282} // namespace android
283
284