blob: 0103d14d820c996d556b4530ea7b8fb1ae66a40a [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
Yifan Hong602b85a2016-10-24 13:40:01 -070047hidl_string::hidl_string(const hidl_string &other): hidl_string() {
48 copyFrom(other.c_str(), other.size());
49}
50
51hidl_string::hidl_string(const std::string &s) : hidl_string() {
52 copyFrom(s.c_str(), s.size());
53}
54
55hidl_string::hidl_string(hidl_string &&other): hidl_string() {
56 moveFrom(std::forward<hidl_string>(other));
57}
58
59hidl_string &hidl_string::operator=(hidl_string &&other) {
60 if (this != &other) {
61 clear();
62 moveFrom(std::forward<hidl_string>(other));
63 }
64 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +020065}
66
67hidl_string &hidl_string::operator=(const hidl_string &other) {
68 if (this != &other) {
Yifan Hong602b85a2016-10-24 13:40:01 -070069 clear();
70 copyFrom(other.c_str(), other.size());
Martijn Coenen72110162016-08-19 14:28:25 +020071 }
72
73 return *this;
74}
75
76hidl_string &hidl_string::operator=(const char *s) {
Yifan Hong602b85a2016-10-24 13:40:01 -070077 clear();
78 copyFrom(s, strlen(s));
79 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +020080}
81
Yifan Hong602b85a2016-10-24 13:40:01 -070082hidl_string &hidl_string::operator=(const std::string &s) {
Martijn Coenen72110162016-08-19 14:28:25 +020083 clear();
Yifan Hong602b85a2016-10-24 13:40:01 -070084 copyFrom(s.c_str(), s.size());
85 return *this;
86}
Martijn Coenen72110162016-08-19 14:28:25 +020087
Yifan Hong602b85a2016-10-24 13:40:01 -070088hidl_string::operator std::string() const {
89 return std::string(mBuffer, mSize);
90}
91
92hidl_string::operator const char *() const {
93 return mBuffer;
94}
95
96void hidl_string::copyFrom(const char *data, size_t size) {
97 // assume my resources are freed.
98
Martijn Coenen4ca39a02016-11-11 15:58:51 +010099 if (size > UINT32_MAX) {
100 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
101 }
Yifan Hong602b85a2016-10-24 13:40:01 -0700102 char *buf = (char *)malloc(size + 1);
103 memcpy(buf, data, size);
104 buf[size] = '\0';
105 mBuffer = buf;
Martijn Coenen72110162016-08-19 14:28:25 +0200106
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100107 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200108 mOwnsBuffer = true;
Yifan Hong602b85a2016-10-24 13:40:01 -0700109}
Martijn Coenen72110162016-08-19 14:28:25 +0200110
Yifan Hong602b85a2016-10-24 13:40:01 -0700111void hidl_string::moveFrom(hidl_string &&other) {
112 // assume my resources are freed.
113
114 mBuffer = other.mBuffer;
115 mSize = other.mSize;
116 mOwnsBuffer = other.mOwnsBuffer;
117
118 other.mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200119}
120
121void hidl_string::clear() {
122 if (mOwnsBuffer && (mBuffer != kEmptyString)) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100123 free(const_cast<char *>(static_cast<const char *>(mBuffer)));
Martijn Coenen72110162016-08-19 14:28:25 +0200124 }
125
Yifan Hong602b85a2016-10-24 13:40:01 -0700126 mBuffer = kEmptyString;
Martijn Coenen72110162016-08-19 14:28:25 +0200127 mSize = 0;
Yifan Hong602b85a2016-10-24 13:40:01 -0700128 mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200129}
130
131void hidl_string::setToExternal(const char *data, size_t size) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100132 if (size > UINT32_MAX) {
133 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
134 }
Martijn Coenen72110162016-08-19 14:28:25 +0200135 clear();
136
Yifan Hong602b85a2016-10-24 13:40:01 -0700137 mBuffer = data;
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100138 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200139 mOwnsBuffer = false;
140}
141
142const char *hidl_string::c_str() const {
Yifan Hong602b85a2016-10-24 13:40:01 -0700143 return mBuffer;
Martijn Coenen72110162016-08-19 14:28:25 +0200144}
145
146size_t hidl_string::size() const {
147 return mSize;
148}
149
150bool hidl_string::empty() const {
151 return mSize == 0;
152}
153
Steven Moreland5a682322016-11-11 12:32:50 -0800154const char* IBase::descriptor = "android.hardware.base@0.0::IBase";
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700155
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700156// ----------------------------------------------------------------------
157// HidlInstrumentor implementation.
158HidlInstrumentor::HidlInstrumentor(const std::string &prefix) {
159 mEnableInstrumentation = property_get_bool("hal.instrumentation.enable",
160 false);
161 registerInstrumentationCallbacks(prefix, &mInstrumentationCallbacks);
162}
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700163
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700164HidlInstrumentor:: ~HidlInstrumentor() {}
165
166void HidlInstrumentor::registerInstrumentationCallbacks(
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700167 const std::string &profilerPrefix,
168 std::vector<InstrumentationCallback> *instrumentationCallbacks) {
Dan Willemsen6365a872016-09-13 16:29:54 -0700169#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700170 std::vector<std::string> instrumentationLibPaths;
Zhuoyao Zhang8bed09f2016-10-26 18:12:47 -0700171 char instrumentation_lib_path[PROPERTY_VALUE_MAX];
172 if (property_get("hal.instrumentation.lib.path",
173 instrumentation_lib_path,
174 "") > 0) {
175 instrumentationLibPaths.push_back(instrumentation_lib_path);
176 } else {
177 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_SYSTEM);
178 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_VENDOR);
179 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_ODM);
180 }
181
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700182 for (auto path : instrumentationLibPaths) {
183 DIR *dir = opendir(path.c_str());
184 if (dir == 0) {
Steven Moreland7096f542016-11-07 11:20:33 -0800185 LOG(WARNING) << path << " does not exist. ";
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700186 return;
187 }
188
189 struct dirent *file;
190 while ((file = readdir(dir)) != NULL) {
191 if (!isInstrumentationLib(profilerPrefix, file))
192 continue;
193
194 void *handle = dlopen((path + file->d_name).c_str(), RTLD_NOW);
195 if (handle == nullptr) {
196 LOG(WARNING) << "couldn't load file: " << file->d_name
197 << " error: " << dlerror();
198 continue;
199 }
200 using cb_fun = void (*)(
201 const InstrumentationEvent,
202 const char *,
203 const char *,
204 const char *,
205 const char *,
206 std::vector<void *> *);
207 auto cb = (cb_fun)dlsym(handle, "HIDL_INSTRUMENTATION_FUNCTION");
208 if (cb == nullptr) {
209 LOG(WARNING)
210 << "couldn't find symbol: HIDL_INSTRUMENTATION_FUNCTION, "
211 "error: "
212 << dlerror();
213 continue;
214 }
215 instrumentationCallbacks->push_back(cb);
216 LOG(INFO) << "Register instrumentation callback from "
217 << file->d_name;
218 }
219 closedir(dir);
220 }
221#else
222 // No-op for user builds.
223 return;
224#endif
225}
226
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700227bool HidlInstrumentor::isInstrumentationLib(
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700228 const std::string &profiler_prefix,
229 const dirent *file) {
Dan Willemsen6365a872016-09-13 16:29:54 -0700230#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700231 if (file->d_type != DT_REG) return false;
232 std::cmatch cm;
233 std::regex e("^" + profiler_prefix + "(.*).profiler.so$");
234 if (std::regex_match(file->d_name, cm, e)) return true;
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700235#endif
236 return false;
237}
238
Martijn Coenen72110162016-08-19 14:28:25 +0200239} // namespace hardware
240} // namespace android
241
242