blob: 37d4b9f49311a58a8d8d24aabc713e9d42385e14 [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#ifndef DLIBHIDL_TARGET_BUILD_VARIANT_USER
20#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
40hidl_string::hidl_string(const hidl_string &other)
41 : mBuffer(const_cast<char *>(kEmptyString)),
42 mSize(0),
43 mOwnsBuffer(true) {
44 setTo(other.c_str(), other.size());
45}
46
47hidl_string &hidl_string::operator=(const hidl_string &other) {
48 if (this != &other) {
49 setTo(other.c_str(), other.size());
50 }
51
52 return *this;
53}
54
55hidl_string &hidl_string::operator=(const char *s) {
56 return setTo(s, strlen(s));
57}
58
59hidl_string &hidl_string::setTo(const char *data, size_t size) {
60 clear();
61
62 mBuffer = (char *)malloc(size + 1);
63 memcpy(mBuffer, data, size);
64 mBuffer[size] = '\0';
65
66 mSize = size;
67 mOwnsBuffer = true;
68
69 return *this;
70}
71
72void hidl_string::clear() {
73 if (mOwnsBuffer && (mBuffer != kEmptyString)) {
74 free(mBuffer);
75 }
76
77 mBuffer = const_cast<char *>(kEmptyString);
78 mSize = 0;
79 mOwnsBuffer = true;
80}
81
82void hidl_string::setToExternal(const char *data, size_t size) {
83 clear();
84
85 mBuffer = const_cast<char *>(data);
86 mSize = size;
87 mOwnsBuffer = false;
88}
89
90const char *hidl_string::c_str() const {
91 return mBuffer ? mBuffer : "";
92}
93
94size_t hidl_string::size() const {
95 return mSize;
96}
97
98bool hidl_string::empty() const {
99 return mSize == 0;
100}
101
102status_t hidl_string::readEmbeddedFromParcel(
103 const Parcel &parcel, size_t parentHandle, size_t parentOffset) {
104 const void *ptr = parcel.readEmbeddedBuffer(
105 nullptr /* buffer_handle */,
106 parentHandle,
107 parentOffset + offsetof(hidl_string, mBuffer));
108
109 return ptr != NULL ? OK : UNKNOWN_ERROR;
110}
111
112status_t hidl_string::writeEmbeddedToParcel(
113 Parcel *parcel, size_t parentHandle, size_t parentOffset) const {
114 return parcel->writeEmbeddedBuffer(
115 mBuffer,
116 mSize + 1,
117 nullptr /* handle */,
118 parentHandle,
119 parentOffset + offsetof(hidl_string, mBuffer));
120}
121
Andreas Huberebfeb362016-08-25 13:39:05 -0700122// static
123const size_t hidl_string::kOffsetOfBuffer = offsetof(hidl_string, mBuffer);
124
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700125
126
127void registerInstrumentationCallbacks(
128 const std::string &profilerPrefix,
129 std::vector<InstrumentationCallback> *instrumentationCallbacks) {
130#ifndef DLIBHIDL_TARGET_BUILD_VARIANT_USER
131 std::vector<std::string> instrumentationLibPaths;
132 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_SYSTEM);
133 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_VENDOR);
134 instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_ODM);
135 for (auto path : instrumentationLibPaths) {
136 DIR *dir = opendir(path.c_str());
137 if (dir == 0) {
138 LOG(WARNING) << path << " does not exit. ";
139 return;
140 }
141
142 struct dirent *file;
143 while ((file = readdir(dir)) != NULL) {
144 if (!isInstrumentationLib(profilerPrefix, file))
145 continue;
146
147 void *handle = dlopen((path + file->d_name).c_str(), RTLD_NOW);
148 if (handle == nullptr) {
149 LOG(WARNING) << "couldn't load file: " << file->d_name
150 << " error: " << dlerror();
151 continue;
152 }
153 using cb_fun = void (*)(
154 const InstrumentationEvent,
155 const char *,
156 const char *,
157 const char *,
158 const char *,
159 std::vector<void *> *);
160 auto cb = (cb_fun)dlsym(handle, "HIDL_INSTRUMENTATION_FUNCTION");
161 if (cb == nullptr) {
162 LOG(WARNING)
163 << "couldn't find symbol: HIDL_INSTRUMENTATION_FUNCTION, "
164 "error: "
165 << dlerror();
166 continue;
167 }
168 instrumentationCallbacks->push_back(cb);
169 LOG(INFO) << "Register instrumentation callback from "
170 << file->d_name;
171 }
172 closedir(dir);
173 }
174#else
175 // No-op for user builds.
176 return;
177#endif
178}
179
180bool isInstrumentationLib(
181 const std::string &profiler_prefix,
182 const dirent *file) {
183#ifndef DLIBHIDL_TARGET_BUILD_VARIANT_USER
184 if (file->d_type != DT_REG) return false;
185 std::cmatch cm;
186 std::regex e("^" + profiler_prefix + "(.*).profiler.so$");
187 if (std::regex_match(file->d_name, cm, e)) return true;
188#else
189#endif
190 return false;
191}
192
Martijn Coenen72110162016-08-19 14:28:25 +0200193} // namespace hardware
194} // namespace android
195
196