blob: ef82775ca8dbcf31c80961ab46150c10064ad1e0 [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>
Martijn Coenen30791002016-12-01 15:40:46 +010021
Martijn Coenen4ca39a02016-11-11 15:58:51 +010022#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -070023#include <cutils/properties.h>
Steven Moreland337e6b62017-01-18 17:25:13 -080024#include <dlfcn.h>
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -070025#include <regex>
Yifan Hong602b85a2016-10-24 13:40:01 -070026#include <utility>
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -070027#endif
28
Martijn Coenen72110162016-08-19 14:28:25 +020029namespace android {
30namespace hardware {
31
32static const char *const kEmptyString = "";
33
34hidl_string::hidl_string()
Yifan Hong602b85a2016-10-24 13:40:01 -070035 : mBuffer(kEmptyString),
Martijn Coenen72110162016-08-19 14:28:25 +020036 mSize(0),
Yifan Hong602b85a2016-10-24 13:40:01 -070037 mOwnsBuffer(false) {
Martijn Coenen72110162016-08-19 14:28:25 +020038}
39
40hidl_string::~hidl_string() {
41 clear();
42}
43
Steven Morelande03c0872016-10-24 10:43:50 -070044hidl_string::hidl_string(const char *s) : hidl_string() {
Yifan Hong602b85a2016-10-24 13:40:01 -070045 copyFrom(s, strlen(s));
Steven Morelande03c0872016-10-24 10:43:50 -070046}
47
Steven Moreland53120f72017-01-12 09:39:26 -080048hidl_string::hidl_string(const char *s, size_t length) : hidl_string() {
49 copyFrom(s, length);
50}
51
Yifan Hong602b85a2016-10-24 13:40:01 -070052hidl_string::hidl_string(const hidl_string &other): hidl_string() {
53 copyFrom(other.c_str(), other.size());
54}
55
56hidl_string::hidl_string(const std::string &s) : hidl_string() {
57 copyFrom(s.c_str(), s.size());
58}
59
60hidl_string::hidl_string(hidl_string &&other): hidl_string() {
61 moveFrom(std::forward<hidl_string>(other));
62}
63
64hidl_string &hidl_string::operator=(hidl_string &&other) {
65 if (this != &other) {
66 clear();
67 moveFrom(std::forward<hidl_string>(other));
68 }
69 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +020070}
71
72hidl_string &hidl_string::operator=(const hidl_string &other) {
73 if (this != &other) {
Yifan Hong602b85a2016-10-24 13:40:01 -070074 clear();
75 copyFrom(other.c_str(), other.size());
Martijn Coenen72110162016-08-19 14:28:25 +020076 }
77
78 return *this;
79}
80
81hidl_string &hidl_string::operator=(const char *s) {
Yifan Hong602b85a2016-10-24 13:40:01 -070082 clear();
83 copyFrom(s, strlen(s));
84 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +020085}
86
Yifan Hong602b85a2016-10-24 13:40:01 -070087hidl_string &hidl_string::operator=(const std::string &s) {
Martijn Coenen72110162016-08-19 14:28:25 +020088 clear();
Yifan Hong602b85a2016-10-24 13:40:01 -070089 copyFrom(s.c_str(), s.size());
90 return *this;
91}
Martijn Coenen72110162016-08-19 14:28:25 +020092
Steven Morelanda2a81842017-01-20 14:48:15 -080093bool hidl_string::operator< (const hidl_string &rhs) const {
94 return strcmp(mBuffer, rhs.mBuffer) < 0;
95}
96
Yifan Hong602b85a2016-10-24 13:40:01 -070097hidl_string::operator std::string() const {
98 return std::string(mBuffer, mSize);
99}
100
101hidl_string::operator const char *() const {
102 return mBuffer;
103}
104
105void hidl_string::copyFrom(const char *data, size_t size) {
106 // assume my resources are freed.
107
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100108 if (size > UINT32_MAX) {
109 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
110 }
Yifan Hong602b85a2016-10-24 13:40:01 -0700111 char *buf = (char *)malloc(size + 1);
112 memcpy(buf, data, size);
113 buf[size] = '\0';
114 mBuffer = buf;
Martijn Coenen72110162016-08-19 14:28:25 +0200115
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100116 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200117 mOwnsBuffer = true;
Yifan Hong602b85a2016-10-24 13:40:01 -0700118}
Martijn Coenen72110162016-08-19 14:28:25 +0200119
Yifan Hong602b85a2016-10-24 13:40:01 -0700120void hidl_string::moveFrom(hidl_string &&other) {
121 // assume my resources are freed.
122
123 mBuffer = other.mBuffer;
124 mSize = other.mSize;
125 mOwnsBuffer = other.mOwnsBuffer;
126
127 other.mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200128}
129
130void hidl_string::clear() {
131 if (mOwnsBuffer && (mBuffer != kEmptyString)) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100132 free(const_cast<char *>(static_cast<const char *>(mBuffer)));
Martijn Coenen72110162016-08-19 14:28:25 +0200133 }
134
Yifan Hong602b85a2016-10-24 13:40:01 -0700135 mBuffer = kEmptyString;
Martijn Coenen72110162016-08-19 14:28:25 +0200136 mSize = 0;
Yifan Hong602b85a2016-10-24 13:40:01 -0700137 mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200138}
139
140void hidl_string::setToExternal(const char *data, size_t size) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100141 if (size > UINT32_MAX) {
142 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
143 }
Martijn Coenen72110162016-08-19 14:28:25 +0200144 clear();
145
Yifan Hong602b85a2016-10-24 13:40:01 -0700146 mBuffer = data;
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100147 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200148 mOwnsBuffer = false;
149}
150
151const char *hidl_string::c_str() const {
Yifan Hong602b85a2016-10-24 13:40:01 -0700152 return mBuffer;
Martijn Coenen72110162016-08-19 14:28:25 +0200153}
154
155size_t hidl_string::size() const {
156 return mSize;
157}
158
159bool hidl_string::empty() const {
160 return mSize == 0;
161}
162
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700163// ----------------------------------------------------------------------
164// HidlInstrumentor implementation.
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800165HidlInstrumentor::HidlInstrumentor(const std::string &prefix)
166 : mInstrumentationLibPrefix(prefix) {
167 configureInstrumentation(false);
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700168}
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700169
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700170HidlInstrumentor:: ~HidlInstrumentor() {}
171
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800172void HidlInstrumentor::configureInstrumentation(bool log) {
173 bool enable_instrumentation = property_get_bool(
174 "hal.instrumentation.enable",
175 false);
176 if (enable_instrumentation != mEnableInstrumentation) {
177 mEnableInstrumentation = enable_instrumentation;
178 if (mEnableInstrumentation) {
179 if (log) {
180 LOG(INFO) << "Enable instrumentation.";
181 }
182 registerInstrumentationCallbacks (&mInstrumentationCallbacks);
183 } else {
184 if (log) {
185 LOG(INFO) << "Disable instrumentation.";
186 }
187 mInstrumentationCallbacks.clear();
188 }
189 }
190}
191
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700192void HidlInstrumentor::registerInstrumentationCallbacks(
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700193 std::vector<InstrumentationCallback> *instrumentationCallbacks) {
Dan Willemsen6365a872016-09-13 16:29:54 -0700194#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700195 std::vector<std::string> instrumentationLibPaths;
Zhuoyao Zhang8bed09f2016-10-26 18:12:47 -0700196 char instrumentation_lib_path[PROPERTY_VALUE_MAX];
197 if (property_get("hal.instrumentation.lib.path",
198 instrumentation_lib_path,
199 "") > 0) {
200 instrumentationLibPaths.push_back(instrumentation_lib_path);
201 } else {
202 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_SYSTEM);
203 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_VENDOR);
204 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_ODM);
205 }
206
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700207 for (auto path : instrumentationLibPaths) {
208 DIR *dir = opendir(path.c_str());
209 if (dir == 0) {
Steven Moreland7096f542016-11-07 11:20:33 -0800210 LOG(WARNING) << path << " does not exist. ";
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700211 return;
212 }
213
214 struct dirent *file;
215 while ((file = readdir(dir)) != NULL) {
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800216 if (!isInstrumentationLib(file))
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700217 continue;
218
219 void *handle = dlopen((path + file->d_name).c_str(), RTLD_NOW);
220 if (handle == nullptr) {
221 LOG(WARNING) << "couldn't load file: " << file->d_name
222 << " error: " << dlerror();
223 continue;
224 }
225 using cb_fun = void (*)(
226 const InstrumentationEvent,
227 const char *,
228 const char *,
229 const char *,
230 const char *,
231 std::vector<void *> *);
232 auto cb = (cb_fun)dlsym(handle, "HIDL_INSTRUMENTATION_FUNCTION");
233 if (cb == nullptr) {
234 LOG(WARNING)
235 << "couldn't find symbol: HIDL_INSTRUMENTATION_FUNCTION, "
236 "error: "
237 << dlerror();
238 continue;
239 }
240 instrumentationCallbacks->push_back(cb);
241 LOG(INFO) << "Register instrumentation callback from "
242 << file->d_name;
243 }
244 closedir(dir);
245 }
246#else
247 // No-op for user builds.
248 return;
249#endif
250}
251
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800252bool HidlInstrumentor::isInstrumentationLib(const dirent *file) {
Dan Willemsen6365a872016-09-13 16:29:54 -0700253#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700254 if (file->d_type != DT_REG) return false;
255 std::cmatch cm;
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800256 std::regex e("^" + mInstrumentationLibPrefix + "(.*).profiler.so$");
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700257 if (std::regex_match(file->d_name, cm, e)) return true;
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700258#endif
259 return false;
260}
261
Martijn Coenen72110162016-08-19 14:28:25 +0200262} // namespace hardware
263} // namespace android
264
265