blob: ed3e12e0804689878d86c2a8035c91f5ac65b3a4 [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 */
16
17#include <hidl/HidlSupport.h>
18
Dan Willemsen6365a872016-09-13 16:29:54 -070019#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -070020#include <android-base/logging.h>
21#include <cutils/properties.h>
22#include <regex>
23#endif
24
Martijn Coenen72110162016-08-19 14:28:25 +020025namespace android {
26namespace hardware {
27
28static const char *const kEmptyString = "";
29
30hidl_string::hidl_string()
31 : mBuffer(const_cast<char *>(kEmptyString)),
32 mSize(0),
33 mOwnsBuffer(true) {
34}
35
36hidl_string::~hidl_string() {
37 clear();
38}
39
Steven Morelande03c0872016-10-24 10:43:50 -070040hidl_string::hidl_string(const char *s) : hidl_string() {
41 *this = s;
42}
43
Martijn Coenen72110162016-08-19 14:28:25 +020044hidl_string::hidl_string(const hidl_string &other)
45 : mBuffer(const_cast<char *>(kEmptyString)),
46 mSize(0),
47 mOwnsBuffer(true) {
48 setTo(other.c_str(), other.size());
49}
50
51hidl_string &hidl_string::operator=(const hidl_string &other) {
52 if (this != &other) {
53 setTo(other.c_str(), other.size());
54 }
55
56 return *this;
57}
58
59hidl_string &hidl_string::operator=(const char *s) {
60 return setTo(s, strlen(s));
61}
62
63hidl_string &hidl_string::setTo(const char *data, size_t size) {
64 clear();
65
66 mBuffer = (char *)malloc(size + 1);
67 memcpy(mBuffer, data, size);
68 mBuffer[size] = '\0';
69
70 mSize = size;
71 mOwnsBuffer = true;
72
73 return *this;
74}
75
76void hidl_string::clear() {
77 if (mOwnsBuffer && (mBuffer != kEmptyString)) {
78 free(mBuffer);
79 }
80
81 mBuffer = const_cast<char *>(kEmptyString);
82 mSize = 0;
83 mOwnsBuffer = true;
84}
85
86void hidl_string::setToExternal(const char *data, size_t size) {
87 clear();
88
89 mBuffer = const_cast<char *>(data);
90 mSize = size;
91 mOwnsBuffer = false;
92}
93
94const char *hidl_string::c_str() const {
95 return mBuffer ? mBuffer : "";
96}
97
98size_t hidl_string::size() const {
99 return mSize;
100}
101
102bool hidl_string::empty() const {
103 return mSize == 0;
104}
105
106status_t hidl_string::readEmbeddedFromParcel(
107 const Parcel &parcel, size_t parentHandle, size_t parentOffset) {
108 const void *ptr = parcel.readEmbeddedBuffer(
109 nullptr /* buffer_handle */,
110 parentHandle,
111 parentOffset + offsetof(hidl_string, mBuffer));
112
113 return ptr != NULL ? OK : UNKNOWN_ERROR;
114}
115
116status_t hidl_string::writeEmbeddedToParcel(
117 Parcel *parcel, size_t parentHandle, size_t parentOffset) const {
118 return parcel->writeEmbeddedBuffer(
119 mBuffer,
120 mSize + 1,
121 nullptr /* handle */,
122 parentHandle,
123 parentOffset + offsetof(hidl_string, mBuffer));
124}
125
Andreas Huberebfeb362016-08-25 13:39:05 -0700126// static
127const size_t hidl_string::kOffsetOfBuffer = offsetof(hidl_string, mBuffer);
128
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700129
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700130// ----------------------------------------------------------------------
131// HidlInstrumentor implementation.
132HidlInstrumentor::HidlInstrumentor(const std::string &prefix) {
133 mEnableInstrumentation = property_get_bool("hal.instrumentation.enable",
134 false);
135 registerInstrumentationCallbacks(prefix, &mInstrumentationCallbacks);
136}
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700137
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700138HidlInstrumentor:: ~HidlInstrumentor() {}
139
140void HidlInstrumentor::registerInstrumentationCallbacks(
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700141 const std::string &profilerPrefix,
142 std::vector<InstrumentationCallback> *instrumentationCallbacks) {
Dan Willemsen6365a872016-09-13 16:29:54 -0700143#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700144 std::vector<std::string> instrumentationLibPaths;
145 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_SYSTEM);
146 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_VENDOR);
147 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_ODM);
148 for (auto path : instrumentationLibPaths) {
149 DIR *dir = opendir(path.c_str());
150 if (dir == 0) {
151 LOG(WARNING) << path << " does not exit. ";
152 return;
153 }
154
155 struct dirent *file;
156 while ((file = readdir(dir)) != NULL) {
157 if (!isInstrumentationLib(profilerPrefix, file))
158 continue;
159
160 void *handle = dlopen((path + file->d_name).c_str(), RTLD_NOW);
161 if (handle == nullptr) {
162 LOG(WARNING) << "couldn't load file: " << file->d_name
163 << " error: " << dlerror();
164 continue;
165 }
166 using cb_fun = void (*)(
167 const InstrumentationEvent,
168 const char *,
169 const char *,
170 const char *,
171 const char *,
172 std::vector<void *> *);
173 auto cb = (cb_fun)dlsym(handle, "HIDL_INSTRUMENTATION_FUNCTION");
174 if (cb == nullptr) {
175 LOG(WARNING)
176 << "couldn't find symbol: HIDL_INSTRUMENTATION_FUNCTION, "
177 "error: "
178 << dlerror();
179 continue;
180 }
181 instrumentationCallbacks->push_back(cb);
182 LOG(INFO) << "Register instrumentation callback from "
183 << file->d_name;
184 }
185 closedir(dir);
186 }
187#else
188 // No-op for user builds.
189 return;
190#endif
191}
192
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700193bool HidlInstrumentor::isInstrumentationLib(
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700194 const std::string &profiler_prefix,
195 const dirent *file) {
Dan Willemsen6365a872016-09-13 16:29:54 -0700196#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700197 if (file->d_type != DT_REG) return false;
198 std::cmatch cm;
199 std::regex e("^" + profiler_prefix + "(.*).profiler.so$");
200 if (std::regex_match(file->d_name, cm, e)) return true;
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700201#endif
202 return false;
203}
204
Martijn Coenen72110162016-08-19 14:28:25 +0200205} // namespace hardware
206} // namespace android
207
208