blob: b284f57abb75749f9fcc544539d88a96b5064766 [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>
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -070023#include <cutils/properties.h>
Martijn Coenen72110162016-08-19 14:28:25 +020024#include <hwbinder/Parcel.h>
Andreas Huber00a985c2016-09-28 14:24:53 -070025#include <tuple>
Iliyan Malchev692070a2016-09-12 16:30:44 -070026#include <utils/Errors.h>
27#include <utils/RefBase.h>
28#include <utils/StrongPointer.h>
Martijn Coenen72110162016-08-19 14:28:25 +020029
30namespace android {
31namespace hardware {
32
33struct hidl_string {
34 hidl_string();
35 ~hidl_string();
36
Yifan Hong602b85a2016-10-24 13:40:01 -070037 // copy constructor.
Martijn Coenen72110162016-08-19 14:28:25 +020038 hidl_string(const hidl_string &);
Yifan Hong602b85a2016-10-24 13:40:01 -070039 // copy from a C-style string.
Steven Morelande03c0872016-10-24 10:43:50 -070040 hidl_string(const char *);
Yifan Hong602b85a2016-10-24 13:40:01 -070041 // copy from an std::string.
42 hidl_string(const std::string &);
43
44 // move constructor.
45 hidl_string(hidl_string &&);
Martijn Coenen72110162016-08-19 14:28:25 +020046
47 const char *c_str() const;
48 size_t size() const;
49 bool empty() const;
50
Yifan Hong602b85a2016-10-24 13:40:01 -070051 // copy assignment operator.
Steven Morelande03c0872016-10-24 10:43:50 -070052 hidl_string &operator=(const hidl_string &);
Yifan Hong602b85a2016-10-24 13:40:01 -070053 // copy from a C-style string.
Martijn Coenen72110162016-08-19 14:28:25 +020054 hidl_string &operator=(const char *s);
Yifan Hong602b85a2016-10-24 13:40:01 -070055 // copy from an std::string.
56 hidl_string &operator=(const std::string &);
57 // move assignment operator.
58 hidl_string &operator=(hidl_string &&other);
59 // cast to std::string.
60 operator std::string() const;
61 // cast to C-style string. Caller is responsible
62 // to maintain this hidl_string alive.
63 operator const char *() const;
Steven Morelande03c0872016-10-24 10:43:50 -070064
Martijn Coenen72110162016-08-19 14:28:25 +020065 void clear();
66
67 // Reference an external char array. Ownership is _not_ transferred.
68 // Caller is responsible for ensuring that underlying memory is valid
69 // for the lifetime of this hidl_string.
70 void setToExternal(const char *data, size_t size);
71
72 status_t readEmbeddedFromParcel(
73 const Parcel &parcel, size_t parentHandle, size_t parentOffset);
74
75 status_t writeEmbeddedToParcel(
76 Parcel *parcel, size_t parentHandle, size_t parentOffset) const;
77
Andreas Huberebfeb362016-08-25 13:39:05 -070078 // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
79 static const size_t kOffsetOfBuffer;
80
Martijn Coenen72110162016-08-19 14:28:25 +020081private:
Yifan Hong602b85a2016-10-24 13:40:01 -070082 const char *mBuffer;
Martijn Coenen72110162016-08-19 14:28:25 +020083 size_t mSize; // NOT including the terminating '\0'.
Yifan Hong602b85a2016-10-24 13:40:01 -070084 bool mOwnsBuffer; // if true then mBuffer is a mutable char *
Martijn Coenen72110162016-08-19 14:28:25 +020085
Yifan Hong602b85a2016-10-24 13:40:01 -070086 // copy from data with size. Assume that my memory is freed
87 // (through clear(), for example)
88 void copyFrom(const char *data, size_t size);
89 // move from another hidl_string
90 void moveFrom(hidl_string &&);
Martijn Coenen72110162016-08-19 14:28:25 +020091};
92
Andreas Huber20dce082016-09-22 19:39:13 -070093////////////////////////////////////////////////////////////////////////////////
94
Martijn Coenen72110162016-08-19 14:28:25 +020095template<typename T>
96struct hidl_vec {
97 hidl_vec()
98 : mBuffer(NULL),
99 mSize(0),
100 mOwnsBuffer(true) {
101 }
102
Yifan Hong602b85a2016-10-24 13:40:01 -0700103 hidl_vec(const hidl_vec<T> &other) : hidl_vec() {
Martijn Coenen72110162016-08-19 14:28:25 +0200104 *this = other;
105 }
106
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700107 hidl_vec(hidl_vec<T> &&other) {
108 *this = static_cast<hidl_vec &&>(other);
109 }
110
Yifan Hong602b85a2016-10-24 13:40:01 -0700111 hidl_vec(const std::vector<T> &other) : hidl_vec() {
112 *this = other;
113 }
114
Martijn Coenen72110162016-08-19 14:28:25 +0200115 ~hidl_vec() {
116 if (mOwnsBuffer) {
117 delete[] mBuffer;
118 }
119 mBuffer = NULL;
120 }
121
Alexey Polyudove2299012016-10-19 09:52:00 -0700122 // Reference an existing array, optionally taking ownership. It is the
Martijn Coenen72110162016-08-19 14:28:25 +0200123 // caller's responsibility to ensure that the underlying memory stays
124 // valid for the lifetime of this hidl_vec.
Alexey Polyudove2299012016-10-19 09:52:00 -0700125 void setToExternal(T *data, size_t size, bool shouldOwn = false) {
Martijn Coenen72110162016-08-19 14:28:25 +0200126 if (mOwnsBuffer) {
127 delete [] mBuffer;
128 }
129 mBuffer = data;
130 mSize = size;
Alexey Polyudove2299012016-10-19 09:52:00 -0700131 mOwnsBuffer = shouldOwn;
Martijn Coenen72110162016-08-19 14:28:25 +0200132 }
133
Alexey Polyudov6f0c9a12016-10-18 09:37:35 -0700134 T *data() {
135 return mBuffer;
136 }
137
138 const T *data() const {
139 return mBuffer;
140 }
141
Alexey Polyudovc98a99c2016-10-18 09:43:56 -0700142 T *releaseData() {
143 if (!mOwnsBuffer && mSize > 0) {
144 resize(mSize);
145 }
146 mOwnsBuffer = false;
147 return mBuffer;
148 }
149
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700150 hidl_vec &operator=(hidl_vec &&other) {
151 mBuffer = other.mBuffer;
152 mSize = other.mSize;
153 mOwnsBuffer = other.mOwnsBuffer;
154 other.mOwnsBuffer = false;
155 return *this;
156 }
157
Martijn Coenen72110162016-08-19 14:28:25 +0200158 hidl_vec &operator=(const hidl_vec &other) {
159 if (this != &other) {
160 if (mOwnsBuffer) {
161 delete[] mBuffer;
162 }
Yifan Hong602b85a2016-10-24 13:40:01 -0700163 copyFrom(other, other.mSize);
Martijn Coenen72110162016-08-19 14:28:25 +0200164 }
165
166 return *this;
167 }
168
Yifan Hong602b85a2016-10-24 13:40:01 -0700169 // copy from an std::vector.
170 hidl_vec &operator=(const std::vector<T> &other) {
171 if (mOwnsBuffer) {
172 delete[] mBuffer;
173 }
174 copyFrom(other, other.size());
175 return *this;
176 }
177
178 // cast to an std::vector.
179 operator std::vector<T>() const {
180 std::vector<T> v(mSize);
181 for (size_t i = 0; i < mSize; ++i) {
182 v[i] = mBuffer[i];
183 }
184 return v;
185 }
186
Martijn Coenen72110162016-08-19 14:28:25 +0200187 size_t size() const {
188 return mSize;
189 }
190
191 T &operator[](size_t index) {
192 return mBuffer[index];
193 }
194
195 const T &operator[](size_t index) const {
196 return mBuffer[index];
197 }
198
199 void resize(size_t size) {
200 T *newBuffer = new T[size];
201
202 for (size_t i = 0; i < std::min(size, mSize); ++i) {
203 newBuffer[i] = mBuffer[i];
204 }
205
206 if (mOwnsBuffer) {
207 delete[] mBuffer;
208 }
209 mBuffer = newBuffer;
210
211 mSize = size;
212 mOwnsBuffer = true;
213 }
214
215 status_t readEmbeddedFromParcel(
216 const Parcel &parcel,
217 size_t parentHandle,
218 size_t parentOffset,
219 size_t *handle);
220
221 status_t writeEmbeddedToParcel(
222 Parcel *parcel,
223 size_t parentHandle,
224 size_t parentOffset,
225 size_t *handle) const;
226
Yifan Hongb1d8d4c2016-08-23 17:39:06 -0700227 status_t findInParcel(const Parcel &parcel, size_t *handle) const {
228 return parcel.quickFindBuffer(mBuffer, handle);
229 }
230
231
Martijn Coenen72110162016-08-19 14:28:25 +0200232private:
233 T *mBuffer;
234 size_t mSize;
235 bool mOwnsBuffer;
Yifan Hong602b85a2016-10-24 13:40:01 -0700236
237 // copy from an array-like object, assuming my resources are freed.
238 template <typename Array>
239 void copyFrom(const Array &data, size_t size) {
240 mSize = size;
241 mOwnsBuffer = true;
242 if (mSize > 0) {
243 mBuffer = new T[size];
244 for (size_t i = 0; i < size; ++i) {
245 mBuffer[i] = data[i];
246 }
247 } else {
248 mBuffer = NULL;
249 }
250 }
Martijn Coenen72110162016-08-19 14:28:25 +0200251};
252
Andreas Huber20dce082016-09-22 19:39:13 -0700253////////////////////////////////////////////////////////////////////////////////
254
255namespace details {
256
257 template<size_t SIZE1, size_t... SIZES>
258 struct product {
259 static constexpr size_t value = SIZE1 * product<SIZES...>::value;
260 };
261
262 template<size_t SIZE1>
263 struct product<SIZE1> {
264 static constexpr size_t value = SIZE1;
265 };
266
267 template<typename T, size_t SIZE1, size_t... SIZES>
268 struct accessor {
269 explicit accessor(T *base)
270 : mBase(base) {
271 }
272
273 accessor<T, SIZES...> operator[](size_t index) {
274 return accessor<T, SIZES...>(
275 &mBase[index * product<SIZES...>::value]);
276 }
277
278 private:
279 T *mBase;
280 };
281
282 template<typename T, size_t SIZE1>
283 struct accessor<T, SIZE1> {
284 explicit accessor(T *base)
285 : mBase(base) {
286 }
287
288 T &operator[](size_t index) {
289 return mBase[index];
290 }
291
292 private:
293 T *mBase;
294 };
295
296 template<typename T, size_t SIZE1, size_t... SIZES>
297 struct const_accessor {
298 explicit const_accessor(const T *base)
299 : mBase(base) {
300 }
301
302 const_accessor<T, SIZES...> operator[](size_t index) {
303 return const_accessor<T, SIZES...>(
304 &mBase[index * product<SIZES...>::value]);
305 }
306
307 private:
308 const T *mBase;
309 };
310
311 template<typename T, size_t SIZE1>
312 struct const_accessor<T, SIZE1> {
313 explicit const_accessor(const T *base)
314 : mBase(base) {
315 }
316
317 const T &operator[](size_t index) const {
318 return mBase[index];
319 }
320
321 private:
322 const T *mBase;
323 };
324
325} // namespace details
326
327////////////////////////////////////////////////////////////////////////////////
328
329template<typename T, size_t SIZE1, size_t... SIZES>
330struct hidl_array {
331 hidl_array() = default;
332
333 T *data() { return mBuffer; }
334 const T *data() const { return mBuffer; }
335
336 details::accessor<T, SIZES...> operator[](size_t index) {
337 return details::accessor<T, SIZES...>(
338 &mBuffer[index * details::product<SIZES...>::value]);
339 }
340
341 details::const_accessor<T, SIZES...> operator[](size_t index) const {
342 return details::const_accessor<T, SIZES...>(
343 &mBuffer[index * details::product<SIZES...>::value]);
344 }
345
Andreas Huber00a985c2016-09-28 14:24:53 -0700346 using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;
347
348 static constexpr size_tuple_type size() {
349 return std::make_tuple(SIZE1, SIZES...);
350 }
351
Andreas Huber20dce082016-09-22 19:39:13 -0700352private:
353 T mBuffer[details::product<SIZE1, SIZES...>::value];
354};
355
356template<typename T, size_t SIZE1>
357struct hidl_array<T, SIZE1> {
358 hidl_array() = default;
359
360 T *data() { return mBuffer; }
361 const T *data() const { return mBuffer; }
362
363 T &operator[](size_t index) {
364 return mBuffer[index];
365 }
366
367 const T &operator[](size_t index) const {
368 return mBuffer[index];
369 }
370
Andreas Huber00a985c2016-09-28 14:24:53 -0700371 static constexpr size_t size() { return SIZE1; }
372
Andreas Huber20dce082016-09-22 19:39:13 -0700373private:
374 T mBuffer[SIZE1];
375};
376
377////////////////////////////////////////////////////////////////////////////////
378
Martijn Coenen72110162016-08-19 14:28:25 +0200379template<typename T>
380status_t hidl_vec<T>::readEmbeddedFromParcel(
381 const Parcel &parcel,
382 size_t parentHandle,
383 size_t parentOffset,
384 size_t *handle) {
385 const void *ptr = parcel.readEmbeddedBuffer(
386 handle,
387 parentHandle,
388 parentOffset + offsetof(hidl_vec<T>, mBuffer));
389
390 return ptr != NULL ? OK : UNKNOWN_ERROR;
391}
392
393template<typename T>
394status_t hidl_vec<T>::writeEmbeddedToParcel(
395 Parcel *parcel,
396 size_t parentHandle,
397 size_t parentOffset,
398 size_t *handle) const {
399 return parcel->writeEmbeddedBuffer(
400 mBuffer,
401 sizeof(T) * mSize,
402 handle,
403 parentHandle,
404 parentOffset + offsetof(hidl_vec<T>, mBuffer));
405}
406
Yifan Hongb1d8d4c2016-08-23 17:39:06 -0700407///////////////////////////// pointers for HIDL
408
409template <typename T>
410static status_t readEmbeddedReferenceFromParcel(
411 T const* * /* bufptr */,
412 const Parcel & parcel,
413 size_t parentHandle,
414 size_t parentOffset,
415 size_t *handle,
416 bool *shouldResolveRefInBuffer
417 ) {
418 // *bufptr is ignored because, if I am embedded in some
419 // other buffer, the kernel should have fixed me up already.
420 bool isPreviouslyWritten;
421 status_t result = parcel.readEmbeddedReference(
422 nullptr, // ignored, not written to bufptr.
423 handle,
424 parentHandle,
425 parentOffset,
426 &isPreviouslyWritten);
427 // tell caller to run T::readEmbeddedToParcel and
428 // T::readEmbeddedReferenceToParcel if necessary.
429 // It is not called here because we don't know if these two are valid methods.
430 *shouldResolveRefInBuffer = !isPreviouslyWritten;
431 return result;
432}
433
434template <typename T>
435static status_t writeEmbeddedReferenceToParcel(
436 T const* buf,
437 Parcel *parcel, size_t parentHandle, size_t parentOffset,
438 size_t *handle,
439 bool *shouldResolveRefInBuffer
440 ) {
441
442 if(buf == nullptr) {
443 *shouldResolveRefInBuffer = false;
444 return parcel->writeEmbeddedNullReference(handle, parentHandle, parentOffset);
445 }
446
447 // find whether the buffer exists
448 size_t childHandle, childOffset;
449 status_t result;
450 bool found;
451
452 result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);
453
454 // tell caller to run T::writeEmbeddedToParcel and
455 // T::writeEmbeddedReferenceToParcel if necessary.
456 // It is not called here because we don't know if these two are valid methods.
457 *shouldResolveRefInBuffer = !found;
458
459 if(result != OK) {
460 return result; // bad pointers and length given
461 }
462 if(!found) { // did not find it.
463 return parcel->writeEmbeddedBuffer(buf, sizeof(T), handle,
464 parentHandle, parentOffset);
465 }
466 // found the buffer. easy case.
467 return parcel->writeEmbeddedReference(
468 handle,
469 childHandle,
470 childOffset,
471 parentHandle,
472 parentOffset);
473}
474
475template <typename T>
476static status_t readReferenceFromParcel(
477 T const* *bufptr,
478 const Parcel & parcel,
479 size_t *handle,
480 bool *shouldResolveRefInBuffer
481 ) {
482 bool isPreviouslyWritten;
483 status_t result = parcel.readReference(reinterpret_cast<void const* *>(bufptr),
484 handle, &isPreviouslyWritten);
485 // tell caller to run T::readEmbeddedToParcel and
486 // T::readEmbeddedReferenceToParcel if necessary.
487 // It is not called here because we don't know if these two are valid methods.
488 *shouldResolveRefInBuffer = !isPreviouslyWritten;
489 return result;
490}
491
492template <typename T>
493static status_t writeReferenceToParcel(
494 T const *buf,
495 Parcel * parcel,
496 size_t *handle,
497 bool *shouldResolveRefInBuffer
498 ) {
499
500 if(buf == nullptr) {
501 *shouldResolveRefInBuffer = false;
502 return parcel->writeNullReference(handle);
503 }
504
505 // find whether the buffer exists
506 size_t childHandle, childOffset;
507 status_t result;
508 bool found;
509
510 result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);
511
512 // tell caller to run T::writeEmbeddedToParcel and
513 // T::writeEmbeddedReferenceToParcel if necessary.
514 // It is not called here because we don't know if these two are valid methods.
515 *shouldResolveRefInBuffer = !found;
516
517 if(result != OK) {
518 return result; // bad pointers and length given
519 }
520 if(!found) { // did not find it.
521 return parcel->writeBuffer(buf, sizeof(T), handle);
522 }
523 // found the buffer. easy case.
524 return parcel->writeReference(handle,
525 childHandle, childOffset);
526}
527
Martijn Coenen72110162016-08-19 14:28:25 +0200528// ----------------------------------------------------------------------
529// Version functions
530struct hidl_version {
531public:
Chia-I Wu666b76b2016-10-06 14:15:59 +0800532 constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {}
Martijn Coenen72110162016-08-19 14:28:25 +0200533
534 bool operator==(const hidl_version& other) {
535 return (mMajor == other.get_major() && mMinor == other.get_minor());
536 }
Martijn Coenenc28f1152016-08-22 14:06:56 +0200537
Martijn Coenen097a7672016-09-08 16:56:41 +0200538 constexpr uint16_t get_major() const { return mMajor; }
539 constexpr uint16_t get_minor() const { return mMinor; }
Martijn Coenen72110162016-08-19 14:28:25 +0200540
541 android::status_t writeToParcel(android::hardware::Parcel& parcel) const {
Chia-I Wu666b76b2016-10-06 14:15:59 +0800542 return parcel.writeUint32(static_cast<uint32_t>(mMajor) << 16 | mMinor);
Martijn Coenen72110162016-08-19 14:28:25 +0200543 }
544
545 static hidl_version* readFromParcel(const android::hardware::Parcel& parcel) {
546 uint32_t version;
547 android::status_t status = parcel.readUint32(&version);
548 if (status != OK) {
549 return nullptr;
550 } else {
551 return new hidl_version(version >> 16, version & 0xFFFF);
552 }
553 }
554
555private:
556 uint16_t mMajor;
557 uint16_t mMinor;
558};
559
560inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
561 return hidl_version(major,minor);
562}
563
Steven Morelandbdf26662016-09-02 11:03:15 -0700564#if defined(__LP64__)
565#define HAL_LIBRARY_PATH_SYSTEM "/system/lib64/hw/"
566#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib64/hw/"
567#define HAL_LIBRARY_PATH_ODM "/odm/lib64/hw/"
568#else
569#define HAL_LIBRARY_PATH_SYSTEM "/system/lib/hw/"
570#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib/hw/"
571#define HAL_LIBRARY_PATH_ODM "/odm/lib/hw/"
572#endif
573
Martijn Coenenc28f1152016-08-22 14:06:56 +0200574#define DECLARE_REGISTER_AND_GET_SERVICE(INTERFACE) \
575 static ::android::sp<I##INTERFACE> getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700576 const std::string &serviceName, bool getStub=false); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700577 status_t registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200578 const std::string &serviceName); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200579
Steven Morelandbdf26662016-09-02 11:03:15 -0700580#define IMPLEMENT_REGISTER_AND_GET_SERVICE(INTERFACE, LIB) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200581 ::android::sp<I##INTERFACE> I##INTERFACE::getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700582 const std::string &serviceName, bool getStub) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200583 { \
584 sp<I##INTERFACE> iface; \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700585 const struct timespec DELAY {1,0}; \
586 unsigned retries = 3; \
Martijn Coenen270cb502016-10-25 00:19:56 +0200587 const sp<IServiceManager> sm = defaultServiceManager(); \
588 if (sm != nullptr && !getStub) { \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700589 do { \
Martijn Coenen270cb502016-10-25 00:19:56 +0200590 sp<IBinder> binderIface = \
591 sm->checkService(String16(serviceName.c_str()), \
592 I##INTERFACE::version); \
593 iface = IHw##INTERFACE::asInterface(binderIface); \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700594 if (iface != nullptr) { \
595 return iface; \
596 } \
597 TEMP_FAILURE_RETRY(nanosleep(&DELAY, nullptr)); \
598 } while (retries--); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700599 } \
600 int dlMode = RTLD_LAZY; \
601 void *handle = dlopen(HAL_LIBRARY_PATH_ODM LIB, dlMode); \
602 if (handle == nullptr) { \
603 handle = dlopen(HAL_LIBRARY_PATH_VENDOR LIB, dlMode); \
604 } \
605 if (handle == nullptr) { \
606 handle = dlopen(HAL_LIBRARY_PATH_SYSTEM LIB, dlMode); \
607 } \
608 if (handle == nullptr) { \
609 return iface; \
610 } \
611 I##INTERFACE* (*generator)(const char* name); \
612 *(void **)(&generator) = dlsym(handle, "HIDL_FETCH_I"#INTERFACE); \
613 if (generator) { \
Martijn Coenenf7a651d2016-09-08 13:38:12 +0200614 iface = (*generator)(serviceName.c_str()); \
Steven Moreland7391bc32016-09-14 10:31:48 -0700615 if (iface != nullptr) { \
616 iface = new Bs##INTERFACE(iface); \
617 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700618 } \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200619 return iface; \
620 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700621 status_t I##INTERFACE::registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200622 const std::string &serviceName) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200623 { \
624 sp<Bn##INTERFACE> binderIface = new Bn##INTERFACE(this); \
625 const sp<IServiceManager> sm = defaultServiceManager(); \
Martijn Coenen097a7672016-09-08 16:56:41 +0200626 return sm->addService(String16(serviceName.c_str()), binderIface, \
627 I##INTERFACE::version); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200628 }
629
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700630// ----------------------------------------------------------------------
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700631// Class that provides Hidl instrumentation utilities.
632struct HidlInstrumentor {
633 // Event that triggers the instrumentation. e.g. enter of an API call on
634 // the server/client side, exit of an API call on the server/client side
635 // etc.
636 enum InstrumentationEvent {
637 SERVER_API_ENTRY = 0,
638 SERVER_API_EXIT,
639 CLIENT_API_ENTRY,
640 CLIENT_API_EXIT,
641 SYNC_CALLBACK_ENTRY,
642 SYNC_CALLBACK_EXIT,
643 ASYNC_CALLBACK_ENTRY,
644 ASYNC_CALLBACK_EXIT,
645 };
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700646
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700647 // Signature of the instrumentation callback function.
648 using InstrumentationCallback = std::function<void(
649 const InstrumentationEvent event,
650 const char *package,
651 const char *version,
652 const char *interface,
653 const char *method,
654 std::vector<void *> *args)>;
655
656 explicit HidlInstrumentor(const std::string &prefix);
657 virtual ~HidlInstrumentor();
658
659 protected:
660 // Function that lookup and dynamically loads the hidl instrumentation
661 // libraries and registers the instrumentation callback functions.
662 //
663 // The instrumentation libraries should be stored under any of the following
664 // directories: HAL_LIBRARY_PATH_SYSTEM, HAL_LIBRARY_PATH_VENDOR and
665 // HAL_LIBRARY_PATH_ODM. The name of instrumentation libraries should
666 // follow pattern: ^profilerPrefix(.*).profiler.so$
667 //
668 // Each instrumentation library is expected to implement the instrumentation
669 // function called HIDL_INSTRUMENTATION_FUNCTION.
670 //
671 // A no-op for user build.
672 void registerInstrumentationCallbacks(
673 const std::string &profilerPrefix,
674 std::vector<InstrumentationCallback> *instrumentationCallbacks);
675
676 // Utility function to determine whether a give file is a instrumentation
677 // library (i.e. the file name follow the expected pattern).
678 bool isInstrumentationLib(
679 const std::string &profilerPrefix,
680 const dirent *file);
681 // A list of registered instrumentation callbacks.
682 std::vector<InstrumentationCallback> mInstrumentationCallbacks;
683 // Flag whether to enable instrumentation.
684 bool mEnableInstrumentation;
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700685};
686
Martijn Coenen72110162016-08-19 14:28:25 +0200687} // namespace hardware
688} // namespace android
689
Martijn Coenenc28f1152016-08-22 14:06:56 +0200690
Martijn Coenen72110162016-08-19 14:28:25 +0200691#endif // ANDROID_HIDL_SUPPORT_H
692