blob: 57eb1e360d6943a56e48de0e20ff13860590e5f9 [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
Dan Willemsen6365a872016-09-13 16:29:54 -070021#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -070022#include <android-base/logging.h>
23#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 = "";
Yifan Hong1e265bb2016-11-08 12:33:44 -080032std::map<std::string, std::function<sp<IBinder>(void*)>> gBnConstructorMap{};
Martijn Coenen72110162016-08-19 14:28:25 +020033
34hidl_string::hidl_string()
Yifan Hong602b85a2016-10-24 13:40:01 -070035 : mBuffer(kEmptyString),
Martijn Coenen72110162016-08-19 14:28:25 +020036 mSize(0),
Yifan Hong602b85a2016-10-24 13:40:01 -070037 mOwnsBuffer(false) {
Martijn Coenen72110162016-08-19 14:28:25 +020038}
39
40hidl_string::~hidl_string() {
41 clear();
42}
43
Steven Morelande03c0872016-10-24 10:43:50 -070044hidl_string::hidl_string(const char *s) : hidl_string() {
Yifan Hong602b85a2016-10-24 13:40:01 -070045 copyFrom(s, strlen(s));
Steven Morelande03c0872016-10-24 10:43:50 -070046}
47
Yifan Hong602b85a2016-10-24 13:40:01 -070048hidl_string::hidl_string(const hidl_string &other): hidl_string() {
49 copyFrom(other.c_str(), other.size());
50}
51
52hidl_string::hidl_string(const std::string &s) : hidl_string() {
53 copyFrom(s.c_str(), s.size());
54}
55
56hidl_string::hidl_string(hidl_string &&other): hidl_string() {
57 moveFrom(std::forward<hidl_string>(other));
58}
59
60hidl_string &hidl_string::operator=(hidl_string &&other) {
61 if (this != &other) {
62 clear();
63 moveFrom(std::forward<hidl_string>(other));
64 }
65 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +020066}
67
68hidl_string &hidl_string::operator=(const hidl_string &other) {
69 if (this != &other) {
Yifan Hong602b85a2016-10-24 13:40:01 -070070 clear();
71 copyFrom(other.c_str(), other.size());
Martijn Coenen72110162016-08-19 14:28:25 +020072 }
73
74 return *this;
75}
76
77hidl_string &hidl_string::operator=(const char *s) {
Yifan Hong602b85a2016-10-24 13:40:01 -070078 clear();
79 copyFrom(s, strlen(s));
80 return *this;
Martijn Coenen72110162016-08-19 14:28:25 +020081}
82
Yifan Hong602b85a2016-10-24 13:40:01 -070083hidl_string &hidl_string::operator=(const std::string &s) {
Martijn Coenen72110162016-08-19 14:28:25 +020084 clear();
Yifan Hong602b85a2016-10-24 13:40:01 -070085 copyFrom(s.c_str(), s.size());
86 return *this;
87}
Martijn Coenen72110162016-08-19 14:28:25 +020088
Yifan Hong602b85a2016-10-24 13:40:01 -070089hidl_string::operator std::string() const {
90 return std::string(mBuffer, mSize);
91}
92
93hidl_string::operator const char *() const {
94 return mBuffer;
95}
96
97void hidl_string::copyFrom(const char *data, size_t size) {
98 // assume my resources are freed.
99
100 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
105 mSize = size;
106 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)) {
Yifan Hong602b85a2016-10-24 13:40:01 -0700121 free(const_cast<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) {
130 clear();
131
Yifan Hong602b85a2016-10-24 13:40:01 -0700132 mBuffer = data;
Martijn Coenen72110162016-08-19 14:28:25 +0200133 mSize = size;
134 mOwnsBuffer = false;
135}
136
137const char *hidl_string::c_str() const {
Yifan Hong602b85a2016-10-24 13:40:01 -0700138 return mBuffer;
Martijn Coenen72110162016-08-19 14:28:25 +0200139}
140
141size_t hidl_string::size() const {
142 return mSize;
143}
144
145bool hidl_string::empty() const {
146 return mSize == 0;
147}
148
149status_t hidl_string::readEmbeddedFromParcel(
150 const Parcel &parcel, size_t parentHandle, size_t parentOffset) {
151 const void *ptr = parcel.readEmbeddedBuffer(
152 nullptr /* buffer_handle */,
153 parentHandle,
154 parentOffset + offsetof(hidl_string, mBuffer));
155
156 return ptr != NULL ? OK : UNKNOWN_ERROR;
157}
158
159status_t hidl_string::writeEmbeddedToParcel(
160 Parcel *parcel, size_t parentHandle, size_t parentOffset) const {
161 return parcel->writeEmbeddedBuffer(
162 mBuffer,
163 mSize + 1,
164 nullptr /* handle */,
165 parentHandle,
166 parentOffset + offsetof(hidl_string, mBuffer));
167}
168
Andreas Huberebfeb362016-08-25 13:39:05 -0700169// static
170const size_t hidl_string::kOffsetOfBuffer = offsetof(hidl_string, mBuffer);
171
Yifan Honga3c31842016-10-21 10:33:14 -0700172const ::android::String16 IHidlInterfaceBase::descriptor(
173 "android.hardware@0.0::IHidlInterfaceBase");
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700174
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700175// ----------------------------------------------------------------------
176// HidlInstrumentor implementation.
177HidlInstrumentor::HidlInstrumentor(const std::string &prefix) {
178 mEnableInstrumentation = property_get_bool("hal.instrumentation.enable",
179 false);
180 registerInstrumentationCallbacks(prefix, &mInstrumentationCallbacks);
181}
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700182
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700183HidlInstrumentor:: ~HidlInstrumentor() {}
184
185void HidlInstrumentor::registerInstrumentationCallbacks(
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700186 const std::string &profilerPrefix,
187 std::vector<InstrumentationCallback> *instrumentationCallbacks) {
Dan Willemsen6365a872016-09-13 16:29:54 -0700188#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700189 std::vector<std::string> instrumentationLibPaths;
Zhuoyao Zhang8bed09f2016-10-26 18:12:47 -0700190 char instrumentation_lib_path[PROPERTY_VALUE_MAX];
191 if (property_get("hal.instrumentation.lib.path",
192 instrumentation_lib_path,
193 "") > 0) {
194 instrumentationLibPaths.push_back(instrumentation_lib_path);
195 } else {
196 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_SYSTEM);
197 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_VENDOR);
198 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_ODM);
199 }
200
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700201 for (auto path : instrumentationLibPaths) {
202 DIR *dir = opendir(path.c_str());
203 if (dir == 0) {
Steven Moreland7096f542016-11-07 11:20:33 -0800204 LOG(WARNING) << path << " does not exist. ";
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700205 return;
206 }
207
208 struct dirent *file;
209 while ((file = readdir(dir)) != NULL) {
210 if (!isInstrumentationLib(profilerPrefix, file))
211 continue;
212
213 void *handle = dlopen((path + file->d_name).c_str(), RTLD_NOW);
214 if (handle == nullptr) {
215 LOG(WARNING) << "couldn't load file: " << file->d_name
216 << " error: " << dlerror();
217 continue;
218 }
219 using cb_fun = void (*)(
220 const InstrumentationEvent,
221 const char *,
222 const char *,
223 const char *,
224 const char *,
225 std::vector<void *> *);
226 auto cb = (cb_fun)dlsym(handle, "HIDL_INSTRUMENTATION_FUNCTION");
227 if (cb == nullptr) {
228 LOG(WARNING)
229 << "couldn't find symbol: HIDL_INSTRUMENTATION_FUNCTION, "
230 "error: "
231 << dlerror();
232 continue;
233 }
234 instrumentationCallbacks->push_back(cb);
235 LOG(INFO) << "Register instrumentation callback from "
236 << file->d_name;
237 }
238 closedir(dir);
239 }
240#else
241 // No-op for user builds.
242 return;
243#endif
244}
245
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700246bool HidlInstrumentor::isInstrumentationLib(
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700247 const std::string &profiler_prefix,
248 const dirent *file) {
Dan Willemsen6365a872016-09-13 16:29:54 -0700249#ifdef LIBHIDL_TARGET_DEBUGGABLE
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700250 if (file->d_type != DT_REG) return false;
251 std::cmatch cm;
252 std::regex e("^" + profiler_prefix + "(.*).profiler.so$");
253 if (std::regex_match(file->d_name, cm, e)) return true;
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700254#endif
255 return false;
256}
257
Martijn Coenen72110162016-08-19 14:28:25 +0200258} // namespace hardware
259} // namespace android
260
261