blob: 791c3b3b229f53da8a4bb0dd6486cfc576ad6b8d [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#ifndef ANDROID_HIDL_SUPPORT_H
18#define ANDROID_HIDL_SUPPORT_H
19
Iliyan Malchev692070a2016-09-12 16:30:44 -070020#include <algorithm>
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -070021#include <dirent.h>
Steven Morelandbdf26662016-09-02 11:03:15 -070022#include <dlfcn.h>
Martijn Coenen72110162016-08-19 14:28:25 +020023#include <hwbinder/Parcel.h>
Iliyan Malchev692070a2016-09-12 16:30:44 -070024#include <utils/Errors.h>
25#include <utils/RefBase.h>
26#include <utils/StrongPointer.h>
Martijn Coenen72110162016-08-19 14:28:25 +020027
28namespace android {
29namespace hardware {
30
31struct hidl_string {
32 hidl_string();
33 ~hidl_string();
34
35 hidl_string(const hidl_string &);
36 hidl_string &operator=(const hidl_string &);
37
38 const char *c_str() const;
39 size_t size() const;
40 bool empty() const;
41
42 hidl_string &operator=(const char *s);
43 void clear();
44
45 // Reference an external char array. Ownership is _not_ transferred.
46 // Caller is responsible for ensuring that underlying memory is valid
47 // for the lifetime of this hidl_string.
48 void setToExternal(const char *data, size_t size);
49
50 status_t readEmbeddedFromParcel(
51 const Parcel &parcel, size_t parentHandle, size_t parentOffset);
52
53 status_t writeEmbeddedToParcel(
54 Parcel *parcel, size_t parentHandle, size_t parentOffset) const;
55
Andreas Huberebfeb362016-08-25 13:39:05 -070056 // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
57 static const size_t kOffsetOfBuffer;
58
Martijn Coenen72110162016-08-19 14:28:25 +020059private:
60 char *mBuffer;
61 size_t mSize; // NOT including the terminating '\0'.
62 bool mOwnsBuffer;
63
64 hidl_string &setTo(const char *data, size_t size);
65};
66
67template<typename T>
68struct hidl_vec {
69 hidl_vec()
70 : mBuffer(NULL),
71 mSize(0),
72 mOwnsBuffer(true) {
73 }
74
75 hidl_vec(const hidl_vec<T> &other)
76 : mBuffer(NULL),
77 mSize(0),
78 mOwnsBuffer(true) {
79 *this = other;
80 }
81
82 ~hidl_vec() {
83 if (mOwnsBuffer) {
84 delete[] mBuffer;
85 }
86 mBuffer = NULL;
87 }
88
89 // Reference an existing array _WITHOUT_ taking ownership. It is the
90 // caller's responsibility to ensure that the underlying memory stays
91 // valid for the lifetime of this hidl_vec.
92 void setToExternal(T *data, size_t size) {
93 if (mOwnsBuffer) {
94 delete [] mBuffer;
95 }
96 mBuffer = data;
97 mSize = size;
98 mOwnsBuffer = false;
99 }
100
101 hidl_vec &operator=(const hidl_vec &other) {
102 if (this != &other) {
103 if (mOwnsBuffer) {
104 delete[] mBuffer;
105 }
106 mBuffer = NULL;
107 mSize = other.mSize;
108 mOwnsBuffer = true;
109 if (mSize > 0) {
110 mBuffer = new T[mSize];
111 for (size_t i = 0; i < mSize; ++i) {
112 mBuffer[i] = other.mBuffer[i];
113 }
114 }
115 }
116
117 return *this;
118 }
119
120 size_t size() const {
121 return mSize;
122 }
123
124 T &operator[](size_t index) {
125 return mBuffer[index];
126 }
127
128 const T &operator[](size_t index) const {
129 return mBuffer[index];
130 }
131
132 void resize(size_t size) {
133 T *newBuffer = new T[size];
134
135 for (size_t i = 0; i < std::min(size, mSize); ++i) {
136 newBuffer[i] = mBuffer[i];
137 }
138
139 if (mOwnsBuffer) {
140 delete[] mBuffer;
141 }
142 mBuffer = newBuffer;
143
144 mSize = size;
145 mOwnsBuffer = true;
146 }
147
148 status_t readEmbeddedFromParcel(
149 const Parcel &parcel,
150 size_t parentHandle,
151 size_t parentOffset,
152 size_t *handle);
153
154 status_t writeEmbeddedToParcel(
155 Parcel *parcel,
156 size_t parentHandle,
157 size_t parentOffset,
158 size_t *handle) const;
159
160private:
161 T *mBuffer;
162 size_t mSize;
163 bool mOwnsBuffer;
164};
165
166template<typename T>
167status_t hidl_vec<T>::readEmbeddedFromParcel(
168 const Parcel &parcel,
169 size_t parentHandle,
170 size_t parentOffset,
171 size_t *handle) {
172 const void *ptr = parcel.readEmbeddedBuffer(
173 handle,
174 parentHandle,
175 parentOffset + offsetof(hidl_vec<T>, mBuffer));
176
177 return ptr != NULL ? OK : UNKNOWN_ERROR;
178}
179
180template<typename T>
181status_t hidl_vec<T>::writeEmbeddedToParcel(
182 Parcel *parcel,
183 size_t parentHandle,
184 size_t parentOffset,
185 size_t *handle) const {
186 return parcel->writeEmbeddedBuffer(
187 mBuffer,
188 sizeof(T) * mSize,
189 handle,
190 parentHandle,
191 parentOffset + offsetof(hidl_vec<T>, mBuffer));
192}
193
194// ----------------------------------------------------------------------
195// Version functions
196struct hidl_version {
197public:
Martijn Coenen097a7672016-09-08 16:56:41 +0200198 constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {};
Martijn Coenen72110162016-08-19 14:28:25 +0200199
200 bool operator==(const hidl_version& other) {
201 return (mMajor == other.get_major() && mMinor == other.get_minor());
202 }
Martijn Coenenc28f1152016-08-22 14:06:56 +0200203
Martijn Coenen097a7672016-09-08 16:56:41 +0200204 constexpr uint16_t get_major() const { return mMajor; }
205 constexpr uint16_t get_minor() const { return mMinor; }
Martijn Coenen72110162016-08-19 14:28:25 +0200206
207 android::status_t writeToParcel(android::hardware::Parcel& parcel) const {
208 return parcel.writeUint32((uint32_t) mMajor << 16 | mMinor);
209 }
210
211 static hidl_version* readFromParcel(const android::hardware::Parcel& parcel) {
212 uint32_t version;
213 android::status_t status = parcel.readUint32(&version);
214 if (status != OK) {
215 return nullptr;
216 } else {
217 return new hidl_version(version >> 16, version & 0xFFFF);
218 }
219 }
220
221private:
222 uint16_t mMajor;
223 uint16_t mMinor;
224};
225
226inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
227 return hidl_version(major,minor);
228}
229
Steven Morelandbdf26662016-09-02 11:03:15 -0700230#if defined(__LP64__)
231#define HAL_LIBRARY_PATH_SYSTEM "/system/lib64/hw/"
232#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib64/hw/"
233#define HAL_LIBRARY_PATH_ODM "/odm/lib64/hw/"
234#else
235#define HAL_LIBRARY_PATH_SYSTEM "/system/lib/hw/"
236#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib/hw/"
237#define HAL_LIBRARY_PATH_ODM "/odm/lib/hw/"
238#endif
239
Martijn Coenenc28f1152016-08-22 14:06:56 +0200240#define DECLARE_REGISTER_AND_GET_SERVICE(INTERFACE) \
241 static ::android::sp<I##INTERFACE> getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700242 const std::string &serviceName, bool getStub=false); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700243 status_t registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200244 const std::string &serviceName); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200245
Steven Morelandbdf26662016-09-02 11:03:15 -0700246#define IMPLEMENT_REGISTER_AND_GET_SERVICE(INTERFACE, LIB) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200247 ::android::sp<I##INTERFACE> I##INTERFACE::getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700248 const std::string &serviceName, bool getStub) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200249 { \
250 sp<I##INTERFACE> iface; \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700251 const struct timespec DELAY {1,0}; \
252 unsigned retries = 3; \
253 if (!getStub) { \
254 do { \
255 const sp<IServiceManager> sm = defaultServiceManager(); \
256 if (sm != nullptr) { \
257 sp<IBinder> binderIface = \
258 sm->checkService(String16(serviceName.c_str()), \
259 I##INTERFACE::version); \
260 iface = IHw##INTERFACE::asInterface(binderIface); \
261 } \
262 if (iface != nullptr) { \
263 return iface; \
264 } \
265 TEMP_FAILURE_RETRY(nanosleep(&DELAY, nullptr)); \
266 } while (retries--); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700267 } \
268 int dlMode = RTLD_LAZY; \
269 void *handle = dlopen(HAL_LIBRARY_PATH_ODM LIB, dlMode); \
270 if (handle == nullptr) { \
271 handle = dlopen(HAL_LIBRARY_PATH_VENDOR LIB, dlMode); \
272 } \
273 if (handle == nullptr) { \
274 handle = dlopen(HAL_LIBRARY_PATH_SYSTEM LIB, dlMode); \
275 } \
276 if (handle == nullptr) { \
277 return iface; \
278 } \
279 I##INTERFACE* (*generator)(const char* name); \
280 *(void **)(&generator) = dlsym(handle, "HIDL_FETCH_I"#INTERFACE); \
281 if (generator) { \
Martijn Coenenf7a651d2016-09-08 13:38:12 +0200282 iface = (*generator)(serviceName.c_str()); \
Steven Moreland7391bc32016-09-14 10:31:48 -0700283 if (iface != nullptr) { \
284 iface = new Bs##INTERFACE(iface); \
285 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700286 } \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200287 return iface; \
288 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700289 status_t I##INTERFACE::registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200290 const std::string &serviceName) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200291 { \
292 sp<Bn##INTERFACE> binderIface = new Bn##INTERFACE(this); \
293 const sp<IServiceManager> sm = defaultServiceManager(); \
Martijn Coenen097a7672016-09-08 16:56:41 +0200294 return sm->addService(String16(serviceName.c_str()), binderIface, \
295 I##INTERFACE::version); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200296 }
297
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700298// ----------------------------------------------------------------------
299// Hidl instrumentation utilities.
300
301// Event that triggers the instrumentation. e.g. enter of an API call on
302// the server/client side, exit of an API call on the server/client side etc.
303enum InstrumentationEvent {
304 SERVER_API_ENTRY = 0,
305 SERVER_API_EXIT,
306 CLIENT_API_ENTRY,
307 CLIENT_API_EXIT,
308 SYNC_CALLBACK_ENTRY,
309 SYNC_CALLBACK_EXIT,
310 ASYNC_CALLBACK_ENTRY,
311 ASYNC_CALLBACK_EXIT,
312};
313
314// Signature of the instrumentation callback function.
315using InstrumentationCallback = std::function<void(
316 const InstrumentationEvent event,
317 const char *package,
318 const char *version,
319 const char *interface,
320 const char *method,
321 std::vector<void *> *args)>;
322
323// Function that lookup and dynamically loads the hidl instrumentation libraries
324// and registers the instrumentation callback functions.
325//
326// The instrumentation libraries should be stored under any of the following
327// directories: HAL_LIBRARY_PATH_SYSTEM, HAL_LIBRARY_PATH_VENDOR and
328// HAL_LIBRARY_PATH_ODM. The name of instrumentation libraries should follow
329// pattern: ^profilerPrefix(.*).profiler.so$
330//
331// Each instrumentation library is expected to implement the instrumentation
332// function called HIDL_INSTRUMENTATION_FUNCTION.
333//
334// A no-op for user build.
335void registerInstrumentationCallbacks(
336 const std::string &profilerPrefix,
337 std::vector<InstrumentationCallback> *instrumentationCallbacks);
338
339// Utility function to determine whether a give file is a instrumentation
340// library (i.e. the file name follow the expected pattern).
341bool isInstrumentationLib(
342 const std::string &profilerPrefix,
343 const dirent *file);
344
Martijn Coenen72110162016-08-19 14:28:25 +0200345} // namespace hardware
346} // namespace android
347
Martijn Coenenc28f1152016-08-22 14:06:56 +0200348
Martijn Coenen72110162016-08-19 14:28:25 +0200349#endif // ANDROID_HIDL_SUPPORT_H
350