blob: 52370887e4be7bac34a8a4731fc35a66c557f50b [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>
24#include <regex>
Yifan Hong602b85a2016-10-24 13:40:01 -070025#include <utility>
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -070026#endif
27
Martijn Coenen72110162016-08-19 14:28:25 +020028namespace android {
29namespace hardware {
30
31static const char *const kEmptyString = "";
32
33hidl_string::hidl_string()
Yifan Hong602b85a2016-10-24 13:40:01 -070034 : mBuffer(kEmptyString),
Martijn Coenen72110162016-08-19 14:28:25 +020035 mSize(0),
Yifan Hong602b85a2016-10-24 13:40:01 -070036 mOwnsBuffer(false) {
Martijn Coenen72110162016-08-19 14:28:25 +020037}
38
39hidl_string::~hidl_string() {
40 clear();
41}
42
Steven Morelande03c0872016-10-24 10:43:50 -070043hidl_string::hidl_string(const char *s) : hidl_string() {
Yifan Hong602b85a2016-10-24 13:40:01 -070044 copyFrom(s, strlen(s));
Steven Morelande03c0872016-10-24 10:43:50 -070045}
46
Steven Moreland53120f72017-01-12 09:39:26 -080047hidl_string::hidl_string(const char *s, size_t length) : hidl_string() {
48 copyFrom(s, length);
49}
50
Yifan Hong602b85a2016-10-24 13:40:01 -070051hidl_string::hidl_string(const hidl_string &other): hidl_string() {
52 copyFrom(other.c_str(), other.size());
53}
54
55hidl_string::hidl_string(const std::string &s) : hidl_string() {
56 copyFrom(s.c_str(), s.size());
57}
58
59hidl_string::hidl_string(hidl_string &&other): hidl_string() {
60 moveFrom(std::forward<hidl_string>(other));
61}
62
63hidl_string &hidl_string::operator=(hidl_string &&other) {
64 if (this != &other) {
65 clear();
66 moveFrom(std::forward<hidl_string>(other));
67 }
68 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +020069}
70
71hidl_string &hidl_string::operator=(const hidl_string &other) {
72 if (this != &other) {
Yifan Hong602b85a2016-10-24 13:40:01 -070073 clear();
74 copyFrom(other.c_str(), other.size());
Martijn Coenen72110162016-08-19 14:28:25 +020075 }
76
77 return *this;
78}
79
80hidl_string &hidl_string::operator=(const char *s) {
Yifan Hong602b85a2016-10-24 13:40:01 -070081 clear();
82 copyFrom(s, strlen(s));
83 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +020084}
85
Yifan Hong602b85a2016-10-24 13:40:01 -070086hidl_string &hidl_string::operator=(const std::string &s) {
Martijn Coenen72110162016-08-19 14:28:25 +020087 clear();
Yifan Hong602b85a2016-10-24 13:40:01 -070088 copyFrom(s.c_str(), s.size());
89 return *this;
90}
Martijn Coenen72110162016-08-19 14:28:25 +020091
Yifan Hong602b85a2016-10-24 13:40:01 -070092hidl_string::operator std::string() const {
93 return std::string(mBuffer, mSize);
94}
95
96hidl_string::operator const char *() const {
97 return mBuffer;
98}
99
100void hidl_string::copyFrom(const char *data, size_t size) {
101 // assume my resources are freed.
102
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100103 if (size > UINT32_MAX) {
104 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
105 }
Yifan Hong602b85a2016-10-24 13:40:01 -0700106 char *buf = (char *)malloc(size + 1);
107 memcpy(buf, data, size);
108 buf[size] = '\0';
109 mBuffer = buf;
Martijn Coenen72110162016-08-19 14:28:25 +0200110
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100111 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200112 mOwnsBuffer = true;
Yifan Hong602b85a2016-10-24 13:40:01 -0700113}
Martijn Coenen72110162016-08-19 14:28:25 +0200114
Yifan Hong602b85a2016-10-24 13:40:01 -0700115void hidl_string::moveFrom(hidl_string &&other) {
116 // assume my resources are freed.
117
118 mBuffer = other.mBuffer;
119 mSize = other.mSize;
120 mOwnsBuffer = other.mOwnsBuffer;
121
122 other.mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200123}
124
125void hidl_string::clear() {
126 if (mOwnsBuffer && (mBuffer != kEmptyString)) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100127 free(const_cast<char *>(static_cast<const char *>(mBuffer)));
Martijn Coenen72110162016-08-19 14:28:25 +0200128 }
129
Yifan Hong602b85a2016-10-24 13:40:01 -0700130 mBuffer = kEmptyString;
Martijn Coenen72110162016-08-19 14:28:25 +0200131 mSize = 0;
Yifan Hong602b85a2016-10-24 13:40:01 -0700132 mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200133}
134
135void hidl_string::setToExternal(const char *data, size_t size) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100136 if (size > UINT32_MAX) {
137 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
138 }
Martijn Coenen72110162016-08-19 14:28:25 +0200139 clear();
140
Yifan Hong602b85a2016-10-24 13:40:01 -0700141 mBuffer = data;
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100142 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200143 mOwnsBuffer = false;
144}
145
146const char *hidl_string::c_str() const {
Yifan Hong602b85a2016-10-24 13:40:01 -0700147 return mBuffer;
Martijn Coenen72110162016-08-19 14:28:25 +0200148}
149
150size_t hidl_string::size() const {
151 return mSize;
152}
153
154bool hidl_string::empty() const {
155 return mSize == 0;
156}
157
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700158// ----------------------------------------------------------------------
159// HidlInstrumentor implementation.
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800160HidlInstrumentor::HidlInstrumentor(const std::string &prefix)
161 : mInstrumentationLibPrefix(prefix) {
162 configureInstrumentation(false);
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700163}
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700164
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700165HidlInstrumentor:: ~HidlInstrumentor() {}
166
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800167void HidlInstrumentor::configureInstrumentation(bool log) {
168 bool enable_instrumentation = property_get_bool(
169 "hal.instrumentation.enable",
170 false);
171 if (enable_instrumentation != mEnableInstrumentation) {
172 mEnableInstrumentation = enable_instrumentation;
173 if (mEnableInstrumentation) {
174 if (log) {
175 LOG(INFO) << "Enable instrumentation.";
176 }
177 registerInstrumentationCallbacks (&mInstrumentationCallbacks);
178 } else {
179 if (log) {
180 LOG(INFO) << "Disable instrumentation.";
181 }
182 mInstrumentationCallbacks.clear();
183 }
184 }
185}
186
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700187void HidlInstrumentor::registerInstrumentationCallbacks(
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700188 std::vector<InstrumentationCallback> *instrumentationCallbacks) {
Dan Willemsen6365a872016-09-13 16:29:54 -0700189#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700190 std::vector<std::string> instrumentationLibPaths;
Zhuoyao Zhang8bed09f2016-10-26 18:12:47 -0700191 char instrumentation_lib_path[PROPERTY_VALUE_MAX];
192 if (property_get("hal.instrumentation.lib.path",
193 instrumentation_lib_path,
194 "") > 0) {
195 instrumentationLibPaths.push_back(instrumentation_lib_path);
196 } else {
197 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_SYSTEM);
198 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_VENDOR);
199 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_ODM);
200 }
201
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700202 for (auto path : instrumentationLibPaths) {
203 DIR *dir = opendir(path.c_str());
204 if (dir == 0) {
Steven Moreland7096f542016-11-07 11:20:33 -0800205 LOG(WARNING) << path << " does not exist. ";
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700206 return;
207 }
208
209 struct dirent *file;
210 while ((file = readdir(dir)) != NULL) {
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800211 if (!isInstrumentationLib(file))
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700212 continue;
213
214 void *handle = dlopen((path + file->d_name).c_str(), RTLD_NOW);
215 if (handle == nullptr) {
216 LOG(WARNING) << "couldn't load file: " << file->d_name
217 << " error: " << dlerror();
218 continue;
219 }
220 using cb_fun = void (*)(
221 const InstrumentationEvent,
222 const char *,
223 const char *,
224 const char *,
225 const char *,
226 std::vector<void *> *);
227 auto cb = (cb_fun)dlsym(handle, "HIDL_INSTRUMENTATION_FUNCTION");
228 if (cb == nullptr) {
229 LOG(WARNING)
230 << "couldn't find symbol: HIDL_INSTRUMENTATION_FUNCTION, "
231 "error: "
232 << dlerror();
233 continue;
234 }
235 instrumentationCallbacks->push_back(cb);
236 LOG(INFO) << "Register instrumentation callback from "
237 << file->d_name;
238 }
239 closedir(dir);
240 }
241#else
242 // No-op for user builds.
243 return;
244#endif
245}
246
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800247bool HidlInstrumentor::isInstrumentationLib(const dirent *file) {
Dan Willemsen6365a872016-09-13 16:29:54 -0700248#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700249 if (file->d_type != DT_REG) return false;
250 std::cmatch cm;
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800251 std::regex e("^" + mInstrumentationLibPrefix + "(.*).profiler.so$");
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700252 if (std::regex_match(file->d_name, cm, e)) return true;
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700253#endif
254 return false;
255}
256
Martijn Coenen72110162016-08-19 14:28:25 +0200257} // namespace hardware
258} // namespace android
259
260