blob: 1324af5b9a04d8e3af3ad86c7e859b1679a52770 [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>
Yifan Honga3c31842016-10-21 10:33:14 -070024#include <hidl/Status.h>
Martijn Coenen72110162016-08-19 14:28:25 +020025#include <hwbinder/Parcel.h>
Andreas Huber00a985c2016-09-28 14:24:53 -070026#include <tuple>
Iliyan Malchev692070a2016-09-12 16:30:44 -070027#include <utils/Errors.h>
28#include <utils/RefBase.h>
29#include <utils/StrongPointer.h>
Martijn Coenen72110162016-08-19 14:28:25 +020030
31namespace android {
32namespace hardware {
33
34struct hidl_string {
35 hidl_string();
36 ~hidl_string();
37
Yifan Hong602b85a2016-10-24 13:40:01 -070038 // copy constructor.
Martijn Coenen72110162016-08-19 14:28:25 +020039 hidl_string(const hidl_string &);
Yifan Hong602b85a2016-10-24 13:40:01 -070040 // copy from a C-style string.
Steven Morelande03c0872016-10-24 10:43:50 -070041 hidl_string(const char *);
Yifan Hong602b85a2016-10-24 13:40:01 -070042 // copy from an std::string.
43 hidl_string(const std::string &);
44
45 // move constructor.
46 hidl_string(hidl_string &&);
Martijn Coenen72110162016-08-19 14:28:25 +020047
48 const char *c_str() const;
49 size_t size() const;
50 bool empty() const;
51
Yifan Hong602b85a2016-10-24 13:40:01 -070052 // copy assignment operator.
Steven Morelande03c0872016-10-24 10:43:50 -070053 hidl_string &operator=(const hidl_string &);
Yifan Hong602b85a2016-10-24 13:40:01 -070054 // copy from a C-style string.
Martijn Coenen72110162016-08-19 14:28:25 +020055 hidl_string &operator=(const char *s);
Yifan Hong602b85a2016-10-24 13:40:01 -070056 // copy from an std::string.
57 hidl_string &operator=(const std::string &);
58 // move assignment operator.
59 hidl_string &operator=(hidl_string &&other);
60 // cast to std::string.
61 operator std::string() const;
62 // cast to C-style string. Caller is responsible
63 // to maintain this hidl_string alive.
64 operator const char *() const;
Steven Morelande03c0872016-10-24 10:43:50 -070065
Martijn Coenen72110162016-08-19 14:28:25 +020066 void clear();
67
68 // Reference an external char array. Ownership is _not_ transferred.
69 // Caller is responsible for ensuring that underlying memory is valid
70 // for the lifetime of this hidl_string.
71 void setToExternal(const char *data, size_t size);
72
73 status_t readEmbeddedFromParcel(
74 const Parcel &parcel, size_t parentHandle, size_t parentOffset);
75
76 status_t writeEmbeddedToParcel(
77 Parcel *parcel, size_t parentHandle, size_t parentOffset) const;
78
Yifan Honga3c31842016-10-21 10:33:14 -070079 inline bool operator==(const char *s) const {
80 return strcmp(mBuffer, s) == 0;
81 }
82
83 inline bool operator!=(const char *s) const {
84 return !(operator==(s));
85 }
86
Andreas Huberebfeb362016-08-25 13:39:05 -070087 // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
88 static const size_t kOffsetOfBuffer;
89
Martijn Coenen72110162016-08-19 14:28:25 +020090private:
Yifan Hong602b85a2016-10-24 13:40:01 -070091 const char *mBuffer;
Martijn Coenen72110162016-08-19 14:28:25 +020092 size_t mSize; // NOT including the terminating '\0'.
Yifan Hong602b85a2016-10-24 13:40:01 -070093 bool mOwnsBuffer; // if true then mBuffer is a mutable char *
Martijn Coenen72110162016-08-19 14:28:25 +020094
Yifan Hong602b85a2016-10-24 13:40:01 -070095 // copy from data with size. Assume that my memory is freed
96 // (through clear(), for example)
97 void copyFrom(const char *data, size_t size);
98 // move from another hidl_string
99 void moveFrom(hidl_string &&);
Martijn Coenen72110162016-08-19 14:28:25 +0200100};
101
Andreas Huber20dce082016-09-22 19:39:13 -0700102////////////////////////////////////////////////////////////////////////////////
103
Martijn Coenen72110162016-08-19 14:28:25 +0200104template<typename T>
105struct hidl_vec {
106 hidl_vec()
107 : mBuffer(NULL),
108 mSize(0),
109 mOwnsBuffer(true) {
110 }
111
Yifan Hong602b85a2016-10-24 13:40:01 -0700112 hidl_vec(const hidl_vec<T> &other) : hidl_vec() {
Martijn Coenen72110162016-08-19 14:28:25 +0200113 *this = other;
114 }
115
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700116 hidl_vec(hidl_vec<T> &&other) {
117 *this = static_cast<hidl_vec &&>(other);
118 }
119
Yifan Hong602b85a2016-10-24 13:40:01 -0700120 hidl_vec(const std::vector<T> &other) : hidl_vec() {
121 *this = other;
122 }
123
Martijn Coenen72110162016-08-19 14:28:25 +0200124 ~hidl_vec() {
125 if (mOwnsBuffer) {
126 delete[] mBuffer;
127 }
128 mBuffer = NULL;
129 }
130
Alexey Polyudove2299012016-10-19 09:52:00 -0700131 // Reference an existing array, optionally taking ownership. It is the
Martijn Coenen72110162016-08-19 14:28:25 +0200132 // caller's responsibility to ensure that the underlying memory stays
133 // valid for the lifetime of this hidl_vec.
Alexey Polyudove2299012016-10-19 09:52:00 -0700134 void setToExternal(T *data, size_t size, bool shouldOwn = false) {
Martijn Coenen72110162016-08-19 14:28:25 +0200135 if (mOwnsBuffer) {
136 delete [] mBuffer;
137 }
138 mBuffer = data;
139 mSize = size;
Alexey Polyudove2299012016-10-19 09:52:00 -0700140 mOwnsBuffer = shouldOwn;
Martijn Coenen72110162016-08-19 14:28:25 +0200141 }
142
Alexey Polyudov6f0c9a12016-10-18 09:37:35 -0700143 T *data() {
144 return mBuffer;
145 }
146
147 const T *data() const {
148 return mBuffer;
149 }
150
Alexey Polyudovc98a99c2016-10-18 09:43:56 -0700151 T *releaseData() {
152 if (!mOwnsBuffer && mSize > 0) {
153 resize(mSize);
154 }
155 mOwnsBuffer = false;
156 return mBuffer;
157 }
158
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700159 hidl_vec &operator=(hidl_vec &&other) {
160 mBuffer = other.mBuffer;
161 mSize = other.mSize;
162 mOwnsBuffer = other.mOwnsBuffer;
163 other.mOwnsBuffer = false;
164 return *this;
165 }
166
Martijn Coenen72110162016-08-19 14:28:25 +0200167 hidl_vec &operator=(const hidl_vec &other) {
168 if (this != &other) {
169 if (mOwnsBuffer) {
170 delete[] mBuffer;
171 }
Yifan Hong602b85a2016-10-24 13:40:01 -0700172 copyFrom(other, other.mSize);
Martijn Coenen72110162016-08-19 14:28:25 +0200173 }
174
175 return *this;
176 }
177
Yifan Hong602b85a2016-10-24 13:40:01 -0700178 // copy from an std::vector.
179 hidl_vec &operator=(const std::vector<T> &other) {
180 if (mOwnsBuffer) {
181 delete[] mBuffer;
182 }
183 copyFrom(other, other.size());
184 return *this;
185 }
186
187 // cast to an std::vector.
188 operator std::vector<T>() const {
189 std::vector<T> v(mSize);
190 for (size_t i = 0; i < mSize; ++i) {
191 v[i] = mBuffer[i];
192 }
193 return v;
194 }
195
Martijn Coenen72110162016-08-19 14:28:25 +0200196 size_t size() const {
197 return mSize;
198 }
199
200 T &operator[](size_t index) {
201 return mBuffer[index];
202 }
203
204 const T &operator[](size_t index) const {
205 return mBuffer[index];
206 }
207
208 void resize(size_t size) {
209 T *newBuffer = new T[size];
210
211 for (size_t i = 0; i < std::min(size, mSize); ++i) {
212 newBuffer[i] = mBuffer[i];
213 }
214
215 if (mOwnsBuffer) {
216 delete[] mBuffer;
217 }
218 mBuffer = newBuffer;
219
220 mSize = size;
221 mOwnsBuffer = true;
222 }
223
224 status_t readEmbeddedFromParcel(
225 const Parcel &parcel,
226 size_t parentHandle,
227 size_t parentOffset,
228 size_t *handle);
229
230 status_t writeEmbeddedToParcel(
231 Parcel *parcel,
232 size_t parentHandle,
233 size_t parentOffset,
234 size_t *handle) const;
235
Yifan Hongb1d8d4c2016-08-23 17:39:06 -0700236 status_t findInParcel(const Parcel &parcel, size_t *handle) const {
237 return parcel.quickFindBuffer(mBuffer, handle);
238 }
239
240
Martijn Coenen72110162016-08-19 14:28:25 +0200241private:
242 T *mBuffer;
243 size_t mSize;
244 bool mOwnsBuffer;
Yifan Hong602b85a2016-10-24 13:40:01 -0700245
246 // copy from an array-like object, assuming my resources are freed.
247 template <typename Array>
248 void copyFrom(const Array &data, size_t size) {
249 mSize = size;
250 mOwnsBuffer = true;
251 if (mSize > 0) {
252 mBuffer = new T[size];
253 for (size_t i = 0; i < size; ++i) {
254 mBuffer[i] = data[i];
255 }
256 } else {
257 mBuffer = NULL;
258 }
259 }
Martijn Coenen72110162016-08-19 14:28:25 +0200260};
261
Andreas Huber20dce082016-09-22 19:39:13 -0700262////////////////////////////////////////////////////////////////////////////////
263
264namespace details {
265
266 template<size_t SIZE1, size_t... SIZES>
267 struct product {
268 static constexpr size_t value = SIZE1 * product<SIZES...>::value;
269 };
270
271 template<size_t SIZE1>
272 struct product<SIZE1> {
273 static constexpr size_t value = SIZE1;
274 };
275
276 template<typename T, size_t SIZE1, size_t... SIZES>
277 struct accessor {
278 explicit accessor(T *base)
279 : mBase(base) {
280 }
281
282 accessor<T, SIZES...> operator[](size_t index) {
283 return accessor<T, SIZES...>(
284 &mBase[index * product<SIZES...>::value]);
285 }
286
287 private:
288 T *mBase;
289 };
290
291 template<typename T, size_t SIZE1>
292 struct accessor<T, SIZE1> {
293 explicit accessor(T *base)
294 : mBase(base) {
295 }
296
297 T &operator[](size_t index) {
298 return mBase[index];
299 }
300
301 private:
302 T *mBase;
303 };
304
305 template<typename T, size_t SIZE1, size_t... SIZES>
306 struct const_accessor {
307 explicit const_accessor(const T *base)
308 : mBase(base) {
309 }
310
311 const_accessor<T, SIZES...> operator[](size_t index) {
312 return const_accessor<T, SIZES...>(
313 &mBase[index * product<SIZES...>::value]);
314 }
315
316 private:
317 const T *mBase;
318 };
319
320 template<typename T, size_t SIZE1>
321 struct const_accessor<T, SIZE1> {
322 explicit const_accessor(const T *base)
323 : mBase(base) {
324 }
325
326 const T &operator[](size_t index) const {
327 return mBase[index];
328 }
329
330 private:
331 const T *mBase;
332 };
333
334} // namespace details
335
336////////////////////////////////////////////////////////////////////////////////
337
338template<typename T, size_t SIZE1, size_t... SIZES>
339struct hidl_array {
340 hidl_array() = default;
341
342 T *data() { return mBuffer; }
343 const T *data() const { return mBuffer; }
344
345 details::accessor<T, SIZES...> operator[](size_t index) {
346 return details::accessor<T, SIZES...>(
347 &mBuffer[index * details::product<SIZES...>::value]);
348 }
349
350 details::const_accessor<T, SIZES...> operator[](size_t index) const {
351 return details::const_accessor<T, SIZES...>(
352 &mBuffer[index * details::product<SIZES...>::value]);
353 }
354
Andreas Huber00a985c2016-09-28 14:24:53 -0700355 using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;
356
357 static constexpr size_tuple_type size() {
358 return std::make_tuple(SIZE1, SIZES...);
359 }
360
Andreas Huber20dce082016-09-22 19:39:13 -0700361private:
362 T mBuffer[details::product<SIZE1, SIZES...>::value];
363};
364
365template<typename T, size_t SIZE1>
366struct hidl_array<T, SIZE1> {
367 hidl_array() = default;
368
369 T *data() { return mBuffer; }
370 const T *data() const { return mBuffer; }
371
372 T &operator[](size_t index) {
373 return mBuffer[index];
374 }
375
376 const T &operator[](size_t index) const {
377 return mBuffer[index];
378 }
379
Andreas Huber00a985c2016-09-28 14:24:53 -0700380 static constexpr size_t size() { return SIZE1; }
381
Andreas Huber20dce082016-09-22 19:39:13 -0700382private:
383 T mBuffer[SIZE1];
384};
385
386////////////////////////////////////////////////////////////////////////////////
387
Martijn Coenen72110162016-08-19 14:28:25 +0200388template<typename T>
389status_t hidl_vec<T>::readEmbeddedFromParcel(
390 const Parcel &parcel,
391 size_t parentHandle,
392 size_t parentOffset,
393 size_t *handle) {
394 const void *ptr = parcel.readEmbeddedBuffer(
395 handle,
396 parentHandle,
397 parentOffset + offsetof(hidl_vec<T>, mBuffer));
398
399 return ptr != NULL ? OK : UNKNOWN_ERROR;
400}
401
402template<typename T>
403status_t hidl_vec<T>::writeEmbeddedToParcel(
404 Parcel *parcel,
405 size_t parentHandle,
406 size_t parentOffset,
407 size_t *handle) const {
408 return parcel->writeEmbeddedBuffer(
409 mBuffer,
410 sizeof(T) * mSize,
411 handle,
412 parentHandle,
413 parentOffset + offsetof(hidl_vec<T>, mBuffer));
414}
415
Yifan Hongb1d8d4c2016-08-23 17:39:06 -0700416///////////////////////////// pointers for HIDL
417
418template <typename T>
419static status_t readEmbeddedReferenceFromParcel(
420 T const* * /* bufptr */,
421 const Parcel & parcel,
422 size_t parentHandle,
423 size_t parentOffset,
424 size_t *handle,
425 bool *shouldResolveRefInBuffer
426 ) {
427 // *bufptr is ignored because, if I am embedded in some
428 // other buffer, the kernel should have fixed me up already.
429 bool isPreviouslyWritten;
430 status_t result = parcel.readEmbeddedReference(
431 nullptr, // ignored, not written to bufptr.
432 handle,
433 parentHandle,
434 parentOffset,
435 &isPreviouslyWritten);
436 // tell caller to run T::readEmbeddedToParcel and
437 // T::readEmbeddedReferenceToParcel if necessary.
438 // It is not called here because we don't know if these two are valid methods.
439 *shouldResolveRefInBuffer = !isPreviouslyWritten;
440 return result;
441}
442
443template <typename T>
444static status_t writeEmbeddedReferenceToParcel(
445 T const* buf,
446 Parcel *parcel, size_t parentHandle, size_t parentOffset,
447 size_t *handle,
448 bool *shouldResolveRefInBuffer
449 ) {
450
451 if(buf == nullptr) {
452 *shouldResolveRefInBuffer = false;
453 return parcel->writeEmbeddedNullReference(handle, parentHandle, parentOffset);
454 }
455
456 // find whether the buffer exists
457 size_t childHandle, childOffset;
458 status_t result;
459 bool found;
460
461 result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);
462
463 // tell caller to run T::writeEmbeddedToParcel and
464 // T::writeEmbeddedReferenceToParcel if necessary.
465 // It is not called here because we don't know if these two are valid methods.
466 *shouldResolveRefInBuffer = !found;
467
468 if(result != OK) {
469 return result; // bad pointers and length given
470 }
471 if(!found) { // did not find it.
472 return parcel->writeEmbeddedBuffer(buf, sizeof(T), handle,
473 parentHandle, parentOffset);
474 }
475 // found the buffer. easy case.
476 return parcel->writeEmbeddedReference(
477 handle,
478 childHandle,
479 childOffset,
480 parentHandle,
481 parentOffset);
482}
483
484template <typename T>
485static status_t readReferenceFromParcel(
486 T const* *bufptr,
487 const Parcel & parcel,
488 size_t *handle,
489 bool *shouldResolveRefInBuffer
490 ) {
491 bool isPreviouslyWritten;
492 status_t result = parcel.readReference(reinterpret_cast<void const* *>(bufptr),
493 handle, &isPreviouslyWritten);
494 // tell caller to run T::readEmbeddedToParcel and
495 // T::readEmbeddedReferenceToParcel if necessary.
496 // It is not called here because we don't know if these two are valid methods.
497 *shouldResolveRefInBuffer = !isPreviouslyWritten;
498 return result;
499}
500
501template <typename T>
502static status_t writeReferenceToParcel(
503 T const *buf,
504 Parcel * parcel,
505 size_t *handle,
506 bool *shouldResolveRefInBuffer
507 ) {
508
509 if(buf == nullptr) {
510 *shouldResolveRefInBuffer = false;
511 return parcel->writeNullReference(handle);
512 }
513
514 // find whether the buffer exists
515 size_t childHandle, childOffset;
516 status_t result;
517 bool found;
518
519 result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);
520
521 // tell caller to run T::writeEmbeddedToParcel and
522 // T::writeEmbeddedReferenceToParcel if necessary.
523 // It is not called here because we don't know if these two are valid methods.
524 *shouldResolveRefInBuffer = !found;
525
526 if(result != OK) {
527 return result; // bad pointers and length given
528 }
529 if(!found) { // did not find it.
530 return parcel->writeBuffer(buf, sizeof(T), handle);
531 }
532 // found the buffer. easy case.
533 return parcel->writeReference(handle,
534 childHandle, childOffset);
535}
536
Martijn Coenen72110162016-08-19 14:28:25 +0200537// ----------------------------------------------------------------------
538// Version functions
539struct hidl_version {
540public:
Chia-I Wu666b76b2016-10-06 14:15:59 +0800541 constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {}
Martijn Coenen72110162016-08-19 14:28:25 +0200542
543 bool operator==(const hidl_version& other) {
544 return (mMajor == other.get_major() && mMinor == other.get_minor());
545 }
Martijn Coenenc28f1152016-08-22 14:06:56 +0200546
Martijn Coenen097a7672016-09-08 16:56:41 +0200547 constexpr uint16_t get_major() const { return mMajor; }
548 constexpr uint16_t get_minor() const { return mMinor; }
Martijn Coenen72110162016-08-19 14:28:25 +0200549
550 android::status_t writeToParcel(android::hardware::Parcel& parcel) const {
Chia-I Wu666b76b2016-10-06 14:15:59 +0800551 return parcel.writeUint32(static_cast<uint32_t>(mMajor) << 16 | mMinor);
Martijn Coenen72110162016-08-19 14:28:25 +0200552 }
553
554 static hidl_version* readFromParcel(const android::hardware::Parcel& parcel) {
555 uint32_t version;
556 android::status_t status = parcel.readUint32(&version);
557 if (status != OK) {
558 return nullptr;
559 } else {
560 return new hidl_version(version >> 16, version & 0xFFFF);
561 }
562 }
563
564private:
565 uint16_t mMajor;
566 uint16_t mMinor;
567};
568
569inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
570 return hidl_version(major,minor);
571}
572
Yifan Honga3c31842016-10-21 10:33:14 -0700573struct IHidlInterfaceBase : virtual public RefBase {
574 virtual bool isRemote() const = 0;
575 // HIDL reserved methods follow.
576 virtual ::android::hardware::Return<void> interfaceChain(
577 std::function<void(const hidl_vec<hidl_string>&)> _hidl_cb) = 0;
578 // descriptor for HIDL reserved methods.
579 static const ::android::String16 descriptor;
580};
581
Steven Morelandbdf26662016-09-02 11:03:15 -0700582#if defined(__LP64__)
583#define HAL_LIBRARY_PATH_SYSTEM "/system/lib64/hw/"
584#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib64/hw/"
585#define HAL_LIBRARY_PATH_ODM "/odm/lib64/hw/"
586#else
587#define HAL_LIBRARY_PATH_SYSTEM "/system/lib/hw/"
588#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib/hw/"
589#define HAL_LIBRARY_PATH_ODM "/odm/lib/hw/"
590#endif
591
Martijn Coenenc28f1152016-08-22 14:06:56 +0200592#define DECLARE_REGISTER_AND_GET_SERVICE(INTERFACE) \
593 static ::android::sp<I##INTERFACE> getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700594 const std::string &serviceName, bool getStub=false); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700595 status_t registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200596 const std::string &serviceName); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200597
Steven Morelandbdf26662016-09-02 11:03:15 -0700598#define IMPLEMENT_REGISTER_AND_GET_SERVICE(INTERFACE, LIB) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200599 ::android::sp<I##INTERFACE> I##INTERFACE::getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700600 const std::string &serviceName, bool getStub) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200601 { \
602 sp<I##INTERFACE> iface; \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700603 const struct timespec DELAY {1,0}; \
604 unsigned retries = 3; \
Martijn Coenen270cb502016-10-25 00:19:56 +0200605 const sp<IServiceManager> sm = defaultServiceManager(); \
606 if (sm != nullptr && !getStub) { \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700607 do { \
Martijn Coenen270cb502016-10-25 00:19:56 +0200608 sp<IBinder> binderIface = \
609 sm->checkService(String16(serviceName.c_str()), \
610 I##INTERFACE::version); \
611 iface = IHw##INTERFACE::asInterface(binderIface); \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700612 if (iface != nullptr) { \
613 return iface; \
614 } \
615 TEMP_FAILURE_RETRY(nanosleep(&DELAY, nullptr)); \
616 } while (retries--); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700617 } \
618 int dlMode = RTLD_LAZY; \
619 void *handle = dlopen(HAL_LIBRARY_PATH_ODM LIB, dlMode); \
620 if (handle == nullptr) { \
621 handle = dlopen(HAL_LIBRARY_PATH_VENDOR LIB, dlMode); \
622 } \
623 if (handle == nullptr) { \
624 handle = dlopen(HAL_LIBRARY_PATH_SYSTEM LIB, dlMode); \
625 } \
626 if (handle == nullptr) { \
627 return iface; \
628 } \
629 I##INTERFACE* (*generator)(const char* name); \
630 *(void **)(&generator) = dlsym(handle, "HIDL_FETCH_I"#INTERFACE); \
631 if (generator) { \
Martijn Coenenf7a651d2016-09-08 13:38:12 +0200632 iface = (*generator)(serviceName.c_str()); \
Steven Moreland7391bc32016-09-14 10:31:48 -0700633 if (iface != nullptr) { \
634 iface = new Bs##INTERFACE(iface); \
635 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700636 } \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200637 return iface; \
638 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700639 status_t I##INTERFACE::registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200640 const std::string &serviceName) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200641 { \
642 sp<Bn##INTERFACE> binderIface = new Bn##INTERFACE(this); \
643 const sp<IServiceManager> sm = defaultServiceManager(); \
Martijn Coenen097a7672016-09-08 16:56:41 +0200644 return sm->addService(String16(serviceName.c_str()), binderIface, \
645 I##INTERFACE::version); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200646 }
647
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700648// ----------------------------------------------------------------------
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700649// Class that provides Hidl instrumentation utilities.
650struct HidlInstrumentor {
651 // Event that triggers the instrumentation. e.g. enter of an API call on
652 // the server/client side, exit of an API call on the server/client side
653 // etc.
654 enum InstrumentationEvent {
655 SERVER_API_ENTRY = 0,
656 SERVER_API_EXIT,
657 CLIENT_API_ENTRY,
658 CLIENT_API_EXIT,
659 SYNC_CALLBACK_ENTRY,
660 SYNC_CALLBACK_EXIT,
661 ASYNC_CALLBACK_ENTRY,
662 ASYNC_CALLBACK_EXIT,
663 };
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700664
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700665 // Signature of the instrumentation callback function.
666 using InstrumentationCallback = std::function<void(
667 const InstrumentationEvent event,
668 const char *package,
669 const char *version,
670 const char *interface,
671 const char *method,
672 std::vector<void *> *args)>;
673
674 explicit HidlInstrumentor(const std::string &prefix);
675 virtual ~HidlInstrumentor();
676
677 protected:
678 // Function that lookup and dynamically loads the hidl instrumentation
679 // libraries and registers the instrumentation callback functions.
680 //
681 // The instrumentation libraries should be stored under any of the following
682 // directories: HAL_LIBRARY_PATH_SYSTEM, HAL_LIBRARY_PATH_VENDOR and
683 // HAL_LIBRARY_PATH_ODM. The name of instrumentation libraries should
684 // follow pattern: ^profilerPrefix(.*).profiler.so$
685 //
686 // Each instrumentation library is expected to implement the instrumentation
687 // function called HIDL_INSTRUMENTATION_FUNCTION.
688 //
689 // A no-op for user build.
690 void registerInstrumentationCallbacks(
691 const std::string &profilerPrefix,
692 std::vector<InstrumentationCallback> *instrumentationCallbacks);
693
694 // Utility function to determine whether a give file is a instrumentation
695 // library (i.e. the file name follow the expected pattern).
696 bool isInstrumentationLib(
697 const std::string &profilerPrefix,
698 const dirent *file);
699 // A list of registered instrumentation callbacks.
700 std::vector<InstrumentationCallback> mInstrumentationCallbacks;
701 // Flag whether to enable instrumentation.
702 bool mEnableInstrumentation;
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700703};
704
Martijn Coenen72110162016-08-19 14:28:25 +0200705} // namespace hardware
706} // namespace android
707
Martijn Coenenc28f1152016-08-22 14:06:56 +0200708
Martijn Coenen72110162016-08-19 14:28:25 +0200709#endif // ANDROID_HIDL_SUPPORT_H
710