blob: 1d87d4cc352a61a19623fdb6fe48f303774fd714 [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
Steven Moreland7096f542016-11-07 11:20:33 -080017#define LOG_TAG "HidlSupport"
18
Martijn Coenen72110162016-08-19 14:28:25 +020019#include <hidl/HidlSupport.h>
20
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -070021#include <android-base/logging.h>
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
Martijn Coenen4ca39a02016-11-11 15:58:51 +010031namespace details {
32
33void hidl_log_base::logAlwaysFatal(const char *message) {
34 LOG(FATAL) << message;
35}
36
37} // namespace details
38
Martijn Coenen72110162016-08-19 14:28:25 +020039static const char *const kEmptyString = "";
40
41hidl_string::hidl_string()
Yifan Hong602b85a2016-10-24 13:40:01 -070042 : mBuffer(kEmptyString),
Martijn Coenen72110162016-08-19 14:28:25 +020043 mSize(0),
Yifan Hong602b85a2016-10-24 13:40:01 -070044 mOwnsBuffer(false) {
Martijn Coenen72110162016-08-19 14:28:25 +020045}
46
47hidl_string::~hidl_string() {
48 clear();
49}
50
Steven Morelande03c0872016-10-24 10:43:50 -070051hidl_string::hidl_string(const char *s) : hidl_string() {
Yifan Hong602b85a2016-10-24 13:40:01 -070052 copyFrom(s, strlen(s));
Steven Morelande03c0872016-10-24 10:43:50 -070053}
54
Yifan Hong602b85a2016-10-24 13:40:01 -070055hidl_string::hidl_string(const hidl_string &other): hidl_string() {
56 copyFrom(other.c_str(), other.size());
57}
58
59hidl_string::hidl_string(const std::string &s) : hidl_string() {
60 copyFrom(s.c_str(), s.size());
61}
62
63hidl_string::hidl_string(hidl_string &&other): hidl_string() {
64 moveFrom(std::forward<hidl_string>(other));
65}
66
67hidl_string &hidl_string::operator=(hidl_string &&other) {
68 if (this != &other) {
69 clear();
70 moveFrom(std::forward<hidl_string>(other));
71 }
72 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +020073}
74
75hidl_string &hidl_string::operator=(const hidl_string &other) {
76 if (this != &other) {
Yifan Hong602b85a2016-10-24 13:40:01 -070077 clear();
78 copyFrom(other.c_str(), other.size());
Martijn Coenen72110162016-08-19 14:28:25 +020079 }
80
81 return *this;
82}
83
84hidl_string &hidl_string::operator=(const char *s) {
Yifan Hong602b85a2016-10-24 13:40:01 -070085 clear();
86 copyFrom(s, strlen(s));
87 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +020088}
89
Yifan Hong602b85a2016-10-24 13:40:01 -070090hidl_string &hidl_string::operator=(const std::string &s) {
Martijn Coenen72110162016-08-19 14:28:25 +020091 clear();
Yifan Hong602b85a2016-10-24 13:40:01 -070092 copyFrom(s.c_str(), s.size());
93 return *this;
94}
Martijn Coenen72110162016-08-19 14:28:25 +020095
Yifan Hong602b85a2016-10-24 13:40:01 -070096hidl_string::operator std::string() const {
97 return std::string(mBuffer, mSize);
98}
99
100hidl_string::operator const char *() const {
101 return mBuffer;
102}
103
104void hidl_string::copyFrom(const char *data, size_t size) {
105 // assume my resources are freed.
106
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100107 if (size > UINT32_MAX) {
108 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
109 }
Yifan Hong602b85a2016-10-24 13:40:01 -0700110 char *buf = (char *)malloc(size + 1);
111 memcpy(buf, data, size);
112 buf[size] = '\0';
113 mBuffer = buf;
Martijn Coenen72110162016-08-19 14:28:25 +0200114
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100115 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200116 mOwnsBuffer = true;
Yifan Hong602b85a2016-10-24 13:40:01 -0700117}
Martijn Coenen72110162016-08-19 14:28:25 +0200118
Yifan Hong602b85a2016-10-24 13:40:01 -0700119void hidl_string::moveFrom(hidl_string &&other) {
120 // assume my resources are freed.
121
122 mBuffer = other.mBuffer;
123 mSize = other.mSize;
124 mOwnsBuffer = other.mOwnsBuffer;
125
126 other.mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200127}
128
129void hidl_string::clear() {
130 if (mOwnsBuffer && (mBuffer != kEmptyString)) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100131 free(const_cast<char *>(static_cast<const char *>(mBuffer)));
Martijn Coenen72110162016-08-19 14:28:25 +0200132 }
133
Yifan Hong602b85a2016-10-24 13:40:01 -0700134 mBuffer = kEmptyString;
Martijn Coenen72110162016-08-19 14:28:25 +0200135 mSize = 0;
Yifan Hong602b85a2016-10-24 13:40:01 -0700136 mOwnsBuffer = false;
Martijn Coenen72110162016-08-19 14:28:25 +0200137}
138
139void hidl_string::setToExternal(const char *data, size_t size) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100140 if (size > UINT32_MAX) {
141 LOG(FATAL) << "string size can't exceed 2^32 bytes.";
142 }
Martijn Coenen72110162016-08-19 14:28:25 +0200143 clear();
144
Yifan Hong602b85a2016-10-24 13:40:01 -0700145 mBuffer = data;
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100146 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200147 mOwnsBuffer = false;
148}
149
150const char *hidl_string::c_str() const {
Yifan Hong602b85a2016-10-24 13:40:01 -0700151 return mBuffer;
Martijn Coenen72110162016-08-19 14:28:25 +0200152}
153
154size_t hidl_string::size() const {
155 return mSize;
156}
157
158bool hidl_string::empty() const {
159 return mSize == 0;
160}
161
Steven Moreland5a682322016-11-11 12:32:50 -0800162const char* IBase::descriptor = "android.hardware.base@0.0::IBase";
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700163
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700164// ----------------------------------------------------------------------
165// HidlInstrumentor implementation.
166HidlInstrumentor::HidlInstrumentor(const std::string &prefix) {
167 mEnableInstrumentation = property_get_bool("hal.instrumentation.enable",
168 false);
169 registerInstrumentationCallbacks(prefix, &mInstrumentationCallbacks);
170}
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700171
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700172HidlInstrumentor:: ~HidlInstrumentor() {}
173
174void HidlInstrumentor::registerInstrumentationCallbacks(
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700175 const std::string &profilerPrefix,
176 std::vector<InstrumentationCallback> *instrumentationCallbacks) {
Dan Willemsen6365a872016-09-13 16:29:54 -0700177#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700178 std::vector<std::string> instrumentationLibPaths;
Zhuoyao Zhang8bed09f2016-10-26 18:12:47 -0700179 char instrumentation_lib_path[PROPERTY_VALUE_MAX];
180 if (property_get("hal.instrumentation.lib.path",
181 instrumentation_lib_path,
182 "") > 0) {
183 instrumentationLibPaths.push_back(instrumentation_lib_path);
184 } else {
185 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_SYSTEM);
186 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_VENDOR);
187 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_ODM);
188 }
189
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700190 for (auto path : instrumentationLibPaths) {
191 DIR *dir = opendir(path.c_str());
192 if (dir == 0) {
Steven Moreland7096f542016-11-07 11:20:33 -0800193 LOG(WARNING) << path << " does not exist. ";
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700194 return;
195 }
196
197 struct dirent *file;
198 while ((file = readdir(dir)) != NULL) {
199 if (!isInstrumentationLib(profilerPrefix, file))
200 continue;
201
202 void *handle = dlopen((path + file->d_name).c_str(), RTLD_NOW);
203 if (handle == nullptr) {
204 LOG(WARNING) << "couldn't load file: " << file->d_name
205 << " error: " << dlerror();
206 continue;
207 }
208 using cb_fun = void (*)(
209 const InstrumentationEvent,
210 const char *,
211 const char *,
212 const char *,
213 const char *,
214 std::vector<void *> *);
215 auto cb = (cb_fun)dlsym(handle, "HIDL_INSTRUMENTATION_FUNCTION");
216 if (cb == nullptr) {
217 LOG(WARNING)
218 << "couldn't find symbol: HIDL_INSTRUMENTATION_FUNCTION, "
219 "error: "
220 << dlerror();
221 continue;
222 }
223 instrumentationCallbacks->push_back(cb);
224 LOG(INFO) << "Register instrumentation callback from "
225 << file->d_name;
226 }
227 closedir(dir);
228 }
229#else
230 // No-op for user builds.
231 return;
232#endif
233}
234
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700235bool HidlInstrumentor::isInstrumentationLib(
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700236 const std::string &profiler_prefix,
237 const dirent *file) {
Dan Willemsen6365a872016-09-13 16:29:54 -0700238#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700239 if (file->d_type != DT_REG) return false;
240 std::cmatch cm;
241 std::regex e("^" + profiler_prefix + "(.*).profiler.so$");
242 if (std::regex_match(file->d_name, cm, e)) return true;
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700243#endif
244 return false;
245}
246
Martijn Coenen72110162016-08-19 14:28:25 +0200247} // namespace hardware
248} // namespace android
249
250