blob: 35e167256da7f74f1cdbed4359b5c0db5ab0834a [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
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -070019#include <android-base/logging.h>
Martijn Coenen4ca39a02016-11-11 15:58:51 +010020#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -070021#include <cutils/properties.h>
22#include <regex>
Yifan Hong602b85a2016-10-24 13:40:01 -070023#include <utility>
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -070024#endif
25
Martijn Coenen72110162016-08-19 14:28:25 +020026namespace android {
27namespace hardware {
28
29static const char *const kEmptyString = "";
30
31hidl_string::hidl_string()
Yifan Hong602b85a2016-10-24 13:40:01 -070032 : mBuffer(kEmptyString),
Martijn Coenen72110162016-08-19 14:28:25 +020033 mSize(0),
Yifan Hong602b85a2016-10-24 13:40:01 -070034 mOwnsBuffer(false) {
Martijn Coenen72110162016-08-19 14:28:25 +020035}
36
37hidl_string::~hidl_string() {
38 clear();
39}
40
Steven Morelande03c0872016-10-24 10:43:50 -070041hidl_string::hidl_string(const char *s) : hidl_string() {
Yifan Hong602b85a2016-10-24 13:40:01 -070042 copyFrom(s, strlen(s));
Steven Morelande03c0872016-10-24 10:43:50 -070043}
44
Yifan Hong602b85a2016-10-24 13:40:01 -070045hidl_string::hidl_string(const hidl_string &other): hidl_string() {
46 copyFrom(other.c_str(), other.size());
47}
48
49hidl_string::hidl_string(const std::string &s) : hidl_string() {
50 copyFrom(s.c_str(), s.size());
51}
52
53hidl_string::hidl_string(hidl_string &&other): hidl_string() {
54 moveFrom(std::forward<hidl_string>(other));
55}
56
57hidl_string &hidl_string::operator=(hidl_string &&other) {
58 if (this != &other) {
59 clear();
60 moveFrom(std::forward<hidl_string>(other));
61 }
62 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +020063}
64
65hidl_string &hidl_string::operator=(const hidl_string &other) {
66 if (this != &other) {
Yifan Hong602b85a2016-10-24 13:40:01 -070067 clear();
68 copyFrom(other.c_str(), other.size());
Martijn Coenen72110162016-08-19 14:28:25 +020069 }
70
71 return *this;
72}
73
74hidl_string &hidl_string::operator=(const char *s) {
Yifan Hong602b85a2016-10-24 13:40:01 -070075 clear();
76 copyFrom(s, strlen(s));
77 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +020078}
79
Yifan Hong602b85a2016-10-24 13:40:01 -070080hidl_string &hidl_string::operator=(const std::string &s) {
Martijn Coenen72110162016-08-19 14:28:25 +020081 clear();
Yifan Hong602b85a2016-10-24 13:40:01 -070082 copyFrom(s.c_str(), s.size());
83 return *this;
84}
Martijn Coenen72110162016-08-19 14:28:25 +020085
Yifan Hong602b85a2016-10-24 13:40:01 -070086hidl_string::operator std::string() const {
87 return std::string(mBuffer, mSize);
88}
89
90hidl_string::operator const char *() const {
91 return mBuffer;
92}
93
94void hidl_string::copyFrom(const char *data, size_t size) {
95 // assume my resources are freed.
96
Martijn Coenen4ca39a02016-11-11 15:58:51 +010097 if (size > UINT32_MAX) {
98 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
99 }
Yifan Hong602b85a2016-10-24 13:40:01 -0700100 char *buf = (char *)malloc(size + 1);
101 memcpy(buf, data, size);
102 buf[size] = '\0';
103 mBuffer = buf;
Martijn Coenen72110162016-08-19 14:28:25 +0200104
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100105 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200106 mOwnsBuffer = true;
Yifan Hong602b85a2016-10-24 13:40:01 -0700107}
Martijn Coenen72110162016-08-19 14:28:25 +0200108
Yifan Hong602b85a2016-10-24 13:40:01 -0700109void hidl_string::moveFrom(hidl_string &&other) {
110 // assume my resources are freed.
111
112 mBuffer = other.mBuffer;
113 mSize = other.mSize;
114 mOwnsBuffer = other.mOwnsBuffer;
115
116 other.mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200117}
118
119void hidl_string::clear() {
120 if (mOwnsBuffer && (mBuffer != kEmptyString)) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100121 free(const_cast<char *>(static_cast<const char *>(mBuffer)));
Martijn Coenen72110162016-08-19 14:28:25 +0200122 }
123
Yifan Hong602b85a2016-10-24 13:40:01 -0700124 mBuffer = kEmptyString;
Martijn Coenen72110162016-08-19 14:28:25 +0200125 mSize = 0;
Yifan Hong602b85a2016-10-24 13:40:01 -0700126 mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200127}
128
129void hidl_string::setToExternal(const char *data, size_t size) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100130 if (size > UINT32_MAX) {
131 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
132 }
Martijn Coenen72110162016-08-19 14:28:25 +0200133 clear();
134
Yifan Hong602b85a2016-10-24 13:40:01 -0700135 mBuffer = data;
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100136 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200137 mOwnsBuffer = false;
138}
139
140const char *hidl_string::c_str() const {
Yifan Hong602b85a2016-10-24 13:40:01 -0700141 return mBuffer;
Martijn Coenen72110162016-08-19 14:28:25 +0200142}
143
144size_t hidl_string::size() const {
145 return mSize;
146}
147
148bool hidl_string::empty() const {
149 return mSize == 0;
150}
151
Steven Moreland5a682322016-11-11 12:32:50 -0800152const char* IBase::descriptor = "android.hardware.base@0.0::IBase";
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700153
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700154// ----------------------------------------------------------------------
155// HidlInstrumentor implementation.
156HidlInstrumentor::HidlInstrumentor(const std::string &prefix) {
157 mEnableInstrumentation = property_get_bool("hal.instrumentation.enable",
158 false);
159 registerInstrumentationCallbacks(prefix, &mInstrumentationCallbacks);
160}
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700161
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700162HidlInstrumentor:: ~HidlInstrumentor() {}
163
164void HidlInstrumentor::registerInstrumentationCallbacks(
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700165 const std::string &profilerPrefix,
166 std::vector<InstrumentationCallback> *instrumentationCallbacks) {
Dan Willemsen6365a872016-09-13 16:29:54 -0700167#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700168 std::vector<std::string> instrumentationLibPaths;
Zhuoyao Zhang8bed09f2016-10-26 18:12:47 -0700169 char instrumentation_lib_path[PROPERTY_VALUE_MAX];
170 if (property_get("hal.instrumentation.lib.path",
171 instrumentation_lib_path,
172 "") > 0) {
173 instrumentationLibPaths.push_back(instrumentation_lib_path);
174 } else {
175 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_SYSTEM);
176 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_VENDOR);
177 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_ODM);
178 }
179
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700180 for (auto path : instrumentationLibPaths) {
181 DIR *dir = opendir(path.c_str());
182 if (dir == 0) {
Steven Moreland7096f542016-11-07 11:20:33 -0800183 LOG(WARNING) << path << " does not exist. ";
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700184 return;
185 }
186
187 struct dirent *file;
188 while ((file = readdir(dir)) != NULL) {
189 if (!isInstrumentationLib(profilerPrefix, file))
190 continue;
191
192 void *handle = dlopen((path + file->d_name).c_str(), RTLD_NOW);
193 if (handle == nullptr) {
194 LOG(WARNING) << "couldn't load file: " << file->d_name
195 << " error: " << dlerror();
196 continue;
197 }
198 using cb_fun = void (*)(
199 const InstrumentationEvent,
200 const char *,
201 const char *,
202 const char *,
203 const char *,
204 std::vector<void *> *);
205 auto cb = (cb_fun)dlsym(handle, "HIDL_INSTRUMENTATION_FUNCTION");
206 if (cb == nullptr) {
207 LOG(WARNING)
208 << "couldn't find symbol: HIDL_INSTRUMENTATION_FUNCTION, "
209 "error: "
210 << dlerror();
211 continue;
212 }
213 instrumentationCallbacks->push_back(cb);
214 LOG(INFO) << "Register instrumentation callback from "
215 << file->d_name;
216 }
217 closedir(dir);
218 }
219#else
220 // No-op for user builds.
221 return;
222#endif
223}
224
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700225bool HidlInstrumentor::isInstrumentationLib(
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700226 const std::string &profiler_prefix,
227 const dirent *file) {
Dan Willemsen6365a872016-09-13 16:29:54 -0700228#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700229 if (file->d_type != DT_REG) return false;
230 std::cmatch cm;
231 std::regex e("^" + profiler_prefix + "(.*).profiler.so$");
232 if (std::regex_match(file->d_name, cm, e)) return true;
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700233#endif
234 return false;
235}
236
Martijn Coenen72110162016-08-19 14:28:25 +0200237} // namespace hardware
238} // namespace android
239
240