blob: e2495e32d58cf244dfe4de9500358f132f67519c [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
Andreas Huber20dce082016-09-22 19:39:13 -070067////////////////////////////////////////////////////////////////////////////////
68
Martijn Coenen72110162016-08-19 14:28:25 +020069template<typename T>
70struct hidl_vec {
71 hidl_vec()
72 : mBuffer(NULL),
73 mSize(0),
74 mOwnsBuffer(true) {
75 }
76
77 hidl_vec(const hidl_vec<T> &other)
78 : mBuffer(NULL),
79 mSize(0),
80 mOwnsBuffer(true) {
81 *this = other;
82 }
83
84 ~hidl_vec() {
85 if (mOwnsBuffer) {
86 delete[] mBuffer;
87 }
88 mBuffer = NULL;
89 }
90
91 // Reference an existing array _WITHOUT_ taking ownership. It is the
92 // caller's responsibility to ensure that the underlying memory stays
93 // valid for the lifetime of this hidl_vec.
94 void setToExternal(T *data, size_t size) {
95 if (mOwnsBuffer) {
96 delete [] mBuffer;
97 }
98 mBuffer = data;
99 mSize = size;
100 mOwnsBuffer = false;
101 }
102
103 hidl_vec &operator=(const hidl_vec &other) {
104 if (this != &other) {
105 if (mOwnsBuffer) {
106 delete[] mBuffer;
107 }
108 mBuffer = NULL;
109 mSize = other.mSize;
110 mOwnsBuffer = true;
111 if (mSize > 0) {
112 mBuffer = new T[mSize];
113 for (size_t i = 0; i < mSize; ++i) {
114 mBuffer[i] = other.mBuffer[i];
115 }
116 }
117 }
118
119 return *this;
120 }
121
122 size_t size() const {
123 return mSize;
124 }
125
126 T &operator[](size_t index) {
127 return mBuffer[index];
128 }
129
130 const T &operator[](size_t index) const {
131 return mBuffer[index];
132 }
133
134 void resize(size_t size) {
135 T *newBuffer = new T[size];
136
137 for (size_t i = 0; i < std::min(size, mSize); ++i) {
138 newBuffer[i] = mBuffer[i];
139 }
140
141 if (mOwnsBuffer) {
142 delete[] mBuffer;
143 }
144 mBuffer = newBuffer;
145
146 mSize = size;
147 mOwnsBuffer = true;
148 }
149
150 status_t readEmbeddedFromParcel(
151 const Parcel &parcel,
152 size_t parentHandle,
153 size_t parentOffset,
154 size_t *handle);
155
156 status_t writeEmbeddedToParcel(
157 Parcel *parcel,
158 size_t parentHandle,
159 size_t parentOffset,
160 size_t *handle) const;
161
162private:
163 T *mBuffer;
164 size_t mSize;
165 bool mOwnsBuffer;
166};
167
Andreas Huber20dce082016-09-22 19:39:13 -0700168////////////////////////////////////////////////////////////////////////////////
169
170namespace details {
171
172 template<size_t SIZE1, size_t... SIZES>
173 struct product {
174 static constexpr size_t value = SIZE1 * product<SIZES...>::value;
175 };
176
177 template<size_t SIZE1>
178 struct product<SIZE1> {
179 static constexpr size_t value = SIZE1;
180 };
181
182 template<typename T, size_t SIZE1, size_t... SIZES>
183 struct accessor {
184 explicit accessor(T *base)
185 : mBase(base) {
186 }
187
188 accessor<T, SIZES...> operator[](size_t index) {
189 return accessor<T, SIZES...>(
190 &mBase[index * product<SIZES...>::value]);
191 }
192
193 private:
194 T *mBase;
195 };
196
197 template<typename T, size_t SIZE1>
198 struct accessor<T, SIZE1> {
199 explicit accessor(T *base)
200 : mBase(base) {
201 }
202
203 T &operator[](size_t index) {
204 return mBase[index];
205 }
206
207 private:
208 T *mBase;
209 };
210
211 template<typename T, size_t SIZE1, size_t... SIZES>
212 struct const_accessor {
213 explicit const_accessor(const T *base)
214 : mBase(base) {
215 }
216
217 const_accessor<T, SIZES...> operator[](size_t index) {
218 return const_accessor<T, SIZES...>(
219 &mBase[index * product<SIZES...>::value]);
220 }
221
222 private:
223 const T *mBase;
224 };
225
226 template<typename T, size_t SIZE1>
227 struct const_accessor<T, SIZE1> {
228 explicit const_accessor(const T *base)
229 : mBase(base) {
230 }
231
232 const T &operator[](size_t index) const {
233 return mBase[index];
234 }
235
236 private:
237 const T *mBase;
238 };
239
240} // namespace details
241
242////////////////////////////////////////////////////////////////////////////////
243
244template<typename T, size_t SIZE1, size_t... SIZES>
245struct hidl_array {
246 hidl_array() = default;
247
248 T *data() { return mBuffer; }
249 const T *data() const { return mBuffer; }
250
251 details::accessor<T, SIZES...> operator[](size_t index) {
252 return details::accessor<T, SIZES...>(
253 &mBuffer[index * details::product<SIZES...>::value]);
254 }
255
256 details::const_accessor<T, SIZES...> operator[](size_t index) const {
257 return details::const_accessor<T, SIZES...>(
258 &mBuffer[index * details::product<SIZES...>::value]);
259 }
260
261private:
262 T mBuffer[details::product<SIZE1, SIZES...>::value];
263};
264
265template<typename T, size_t SIZE1>
266struct hidl_array<T, SIZE1> {
267 hidl_array() = default;
268
269 T *data() { return mBuffer; }
270 const T *data() const { return mBuffer; }
271
272 T &operator[](size_t index) {
273 return mBuffer[index];
274 }
275
276 const T &operator[](size_t index) const {
277 return mBuffer[index];
278 }
279
280private:
281 T mBuffer[SIZE1];
282};
283
284////////////////////////////////////////////////////////////////////////////////
285
Martijn Coenen72110162016-08-19 14:28:25 +0200286template<typename T>
287status_t hidl_vec<T>::readEmbeddedFromParcel(
288 const Parcel &parcel,
289 size_t parentHandle,
290 size_t parentOffset,
291 size_t *handle) {
292 const void *ptr = parcel.readEmbeddedBuffer(
293 handle,
294 parentHandle,
295 parentOffset + offsetof(hidl_vec<T>, mBuffer));
296
297 return ptr != NULL ? OK : UNKNOWN_ERROR;
298}
299
300template<typename T>
301status_t hidl_vec<T>::writeEmbeddedToParcel(
302 Parcel *parcel,
303 size_t parentHandle,
304 size_t parentOffset,
305 size_t *handle) const {
306 return parcel->writeEmbeddedBuffer(
307 mBuffer,
308 sizeof(T) * mSize,
309 handle,
310 parentHandle,
311 parentOffset + offsetof(hidl_vec<T>, mBuffer));
312}
313
314// ----------------------------------------------------------------------
315// Version functions
316struct hidl_version {
317public:
Martijn Coenen097a7672016-09-08 16:56:41 +0200318 constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {};
Martijn Coenen72110162016-08-19 14:28:25 +0200319
320 bool operator==(const hidl_version& other) {
321 return (mMajor == other.get_major() && mMinor == other.get_minor());
322 }
Martijn Coenenc28f1152016-08-22 14:06:56 +0200323
Martijn Coenen097a7672016-09-08 16:56:41 +0200324 constexpr uint16_t get_major() const { return mMajor; }
325 constexpr uint16_t get_minor() const { return mMinor; }
Martijn Coenen72110162016-08-19 14:28:25 +0200326
327 android::status_t writeToParcel(android::hardware::Parcel& parcel) const {
328 return parcel.writeUint32((uint32_t) mMajor << 16 | mMinor);
329 }
330
331 static hidl_version* readFromParcel(const android::hardware::Parcel& parcel) {
332 uint32_t version;
333 android::status_t status = parcel.readUint32(&version);
334 if (status != OK) {
335 return nullptr;
336 } else {
337 return new hidl_version(version >> 16, version & 0xFFFF);
338 }
339 }
340
341private:
342 uint16_t mMajor;
343 uint16_t mMinor;
344};
345
346inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
347 return hidl_version(major,minor);
348}
349
Steven Morelandbdf26662016-09-02 11:03:15 -0700350#if defined(__LP64__)
351#define HAL_LIBRARY_PATH_SYSTEM "/system/lib64/hw/"
352#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib64/hw/"
353#define HAL_LIBRARY_PATH_ODM "/odm/lib64/hw/"
354#else
355#define HAL_LIBRARY_PATH_SYSTEM "/system/lib/hw/"
356#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib/hw/"
357#define HAL_LIBRARY_PATH_ODM "/odm/lib/hw/"
358#endif
359
Martijn Coenenc28f1152016-08-22 14:06:56 +0200360#define DECLARE_REGISTER_AND_GET_SERVICE(INTERFACE) \
361 static ::android::sp<I##INTERFACE> getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700362 const std::string &serviceName, bool getStub=false); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700363 status_t registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200364 const std::string &serviceName); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200365
Steven Morelandbdf26662016-09-02 11:03:15 -0700366#define IMPLEMENT_REGISTER_AND_GET_SERVICE(INTERFACE, LIB) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200367 ::android::sp<I##INTERFACE> I##INTERFACE::getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700368 const std::string &serviceName, bool getStub) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200369 { \
370 sp<I##INTERFACE> iface; \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700371 const struct timespec DELAY {1,0}; \
372 unsigned retries = 3; \
373 if (!getStub) { \
374 do { \
375 const sp<IServiceManager> sm = defaultServiceManager(); \
376 if (sm != nullptr) { \
377 sp<IBinder> binderIface = \
378 sm->checkService(String16(serviceName.c_str()), \
379 I##INTERFACE::version); \
380 iface = IHw##INTERFACE::asInterface(binderIface); \
381 } \
382 if (iface != nullptr) { \
383 return iface; \
384 } \
385 TEMP_FAILURE_RETRY(nanosleep(&DELAY, nullptr)); \
386 } while (retries--); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700387 } \
388 int dlMode = RTLD_LAZY; \
389 void *handle = dlopen(HAL_LIBRARY_PATH_ODM LIB, dlMode); \
390 if (handle == nullptr) { \
391 handle = dlopen(HAL_LIBRARY_PATH_VENDOR LIB, dlMode); \
392 } \
393 if (handle == nullptr) { \
394 handle = dlopen(HAL_LIBRARY_PATH_SYSTEM LIB, dlMode); \
395 } \
396 if (handle == nullptr) { \
397 return iface; \
398 } \
399 I##INTERFACE* (*generator)(const char* name); \
400 *(void **)(&generator) = dlsym(handle, "HIDL_FETCH_I"#INTERFACE); \
401 if (generator) { \
Martijn Coenenf7a651d2016-09-08 13:38:12 +0200402 iface = (*generator)(serviceName.c_str()); \
Steven Moreland7391bc32016-09-14 10:31:48 -0700403 if (iface != nullptr) { \
404 iface = new Bs##INTERFACE(iface); \
405 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700406 } \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200407 return iface; \
408 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700409 status_t I##INTERFACE::registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200410 const std::string &serviceName) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200411 { \
412 sp<Bn##INTERFACE> binderIface = new Bn##INTERFACE(this); \
413 const sp<IServiceManager> sm = defaultServiceManager(); \
Martijn Coenen097a7672016-09-08 16:56:41 +0200414 return sm->addService(String16(serviceName.c_str()), binderIface, \
415 I##INTERFACE::version); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200416 }
417
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700418// ----------------------------------------------------------------------
419// Hidl instrumentation utilities.
420
421// Event that triggers the instrumentation. e.g. enter of an API call on
422// the server/client side, exit of an API call on the server/client side etc.
423enum InstrumentationEvent {
424 SERVER_API_ENTRY = 0,
425 SERVER_API_EXIT,
426 CLIENT_API_ENTRY,
427 CLIENT_API_EXIT,
428 SYNC_CALLBACK_ENTRY,
429 SYNC_CALLBACK_EXIT,
430 ASYNC_CALLBACK_ENTRY,
431 ASYNC_CALLBACK_EXIT,
432};
433
434// Signature of the instrumentation callback function.
435using InstrumentationCallback = std::function<void(
436 const InstrumentationEvent event,
437 const char *package,
438 const char *version,
439 const char *interface,
440 const char *method,
441 std::vector<void *> *args)>;
442
443// Function that lookup and dynamically loads the hidl instrumentation libraries
444// and registers the instrumentation callback functions.
445//
446// The instrumentation libraries should be stored under any of the following
447// directories: HAL_LIBRARY_PATH_SYSTEM, HAL_LIBRARY_PATH_VENDOR and
448// HAL_LIBRARY_PATH_ODM. The name of instrumentation libraries should follow
449// pattern: ^profilerPrefix(.*).profiler.so$
450//
451// Each instrumentation library is expected to implement the instrumentation
452// function called HIDL_INSTRUMENTATION_FUNCTION.
453//
454// A no-op for user build.
455void registerInstrumentationCallbacks(
456 const std::string &profilerPrefix,
457 std::vector<InstrumentationCallback> *instrumentationCallbacks);
458
459// Utility function to determine whether a give file is a instrumentation
460// library (i.e. the file name follow the expected pattern).
461bool isInstrumentationLib(
462 const std::string &profilerPrefix,
463 const dirent *file);
464
Martijn Coenen72110162016-08-19 14:28:25 +0200465} // namespace hardware
466} // namespace android
467
Martijn Coenenc28f1152016-08-22 14:06:56 +0200468
Martijn Coenen72110162016-08-19 14:28:25 +0200469#endif // ANDROID_HIDL_SUPPORT_H
470