blob: 37c4431ad6de96e49cc9b2cdc9abd2041970ae83 [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
Andreas Huberebfeb362016-08-25 13:39:05 -070079 // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
80 static const size_t kOffsetOfBuffer;
81
Martijn Coenen72110162016-08-19 14:28:25 +020082private:
Yifan Hong602b85a2016-10-24 13:40:01 -070083 const char *mBuffer;
Martijn Coenen72110162016-08-19 14:28:25 +020084 size_t mSize; // NOT including the terminating '\0'.
Yifan Hong602b85a2016-10-24 13:40:01 -070085 bool mOwnsBuffer; // if true then mBuffer is a mutable char *
Martijn Coenen72110162016-08-19 14:28:25 +020086
Yifan Hong602b85a2016-10-24 13:40:01 -070087 // copy from data with size. Assume that my memory is freed
88 // (through clear(), for example)
89 void copyFrom(const char *data, size_t size);
90 // move from another hidl_string
91 void moveFrom(hidl_string &&);
Martijn Coenen72110162016-08-19 14:28:25 +020092};
93
Yifan Hong5708fb42016-10-26 17:50:29 -070094inline bool operator==(const hidl_string &hs, const char *s) {
95 return strcmp(hs.c_str(), s) == 0;
96}
97
98inline bool operator!=(const hidl_string &hs, const char *s) {
99 return !(hs == s);
100}
101
102inline bool operator==(const char *s, const hidl_string &hs) {
103 return strcmp(hs.c_str(), s) == 0;
104}
105
106inline bool operator!=(const char *s, const hidl_string &hs) {
107 return !(s == hs);
108}
109
Andreas Huber20dce082016-09-22 19:39:13 -0700110////////////////////////////////////////////////////////////////////////////////
111
Martijn Coenen72110162016-08-19 14:28:25 +0200112template<typename T>
113struct hidl_vec {
114 hidl_vec()
115 : mBuffer(NULL),
116 mSize(0),
117 mOwnsBuffer(true) {
118 }
119
Yifan Hong602b85a2016-10-24 13:40:01 -0700120 hidl_vec(const hidl_vec<T> &other) : hidl_vec() {
Martijn Coenen72110162016-08-19 14:28:25 +0200121 *this = other;
122 }
123
Janis Danisevskisd3ddf622016-10-24 11:40:50 +0100124 hidl_vec(hidl_vec<T> &&other)
125 : mOwnsBuffer(false) {
126 *this = std::move(other);
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700127 }
128
Yifan Hong602b85a2016-10-24 13:40:01 -0700129 hidl_vec(const std::vector<T> &other) : hidl_vec() {
130 *this = other;
131 }
132
Martijn Coenen72110162016-08-19 14:28:25 +0200133 ~hidl_vec() {
134 if (mOwnsBuffer) {
135 delete[] mBuffer;
136 }
137 mBuffer = NULL;
138 }
139
Alexey Polyudove2299012016-10-19 09:52:00 -0700140 // Reference an existing array, optionally taking ownership. It is the
Martijn Coenen72110162016-08-19 14:28:25 +0200141 // caller's responsibility to ensure that the underlying memory stays
142 // valid for the lifetime of this hidl_vec.
Alexey Polyudove2299012016-10-19 09:52:00 -0700143 void setToExternal(T *data, size_t size, bool shouldOwn = false) {
Martijn Coenen72110162016-08-19 14:28:25 +0200144 if (mOwnsBuffer) {
145 delete [] mBuffer;
146 }
147 mBuffer = data;
148 mSize = size;
Alexey Polyudove2299012016-10-19 09:52:00 -0700149 mOwnsBuffer = shouldOwn;
Martijn Coenen72110162016-08-19 14:28:25 +0200150 }
151
Alexey Polyudov6f0c9a12016-10-18 09:37:35 -0700152 T *data() {
153 return mBuffer;
154 }
155
156 const T *data() const {
157 return mBuffer;
158 }
159
Alexey Polyudovc98a99c2016-10-18 09:43:56 -0700160 T *releaseData() {
161 if (!mOwnsBuffer && mSize > 0) {
162 resize(mSize);
163 }
164 mOwnsBuffer = false;
165 return mBuffer;
166 }
167
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700168 hidl_vec &operator=(hidl_vec &&other) {
Janis Danisevskisd3ddf622016-10-24 11:40:50 +0100169 if (mOwnsBuffer) {
170 delete[] mBuffer;
171 }
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700172 mBuffer = other.mBuffer;
173 mSize = other.mSize;
174 mOwnsBuffer = other.mOwnsBuffer;
175 other.mOwnsBuffer = false;
176 return *this;
177 }
178
Martijn Coenen72110162016-08-19 14:28:25 +0200179 hidl_vec &operator=(const hidl_vec &other) {
180 if (this != &other) {
181 if (mOwnsBuffer) {
182 delete[] mBuffer;
183 }
Yifan Hong602b85a2016-10-24 13:40:01 -0700184 copyFrom(other, other.mSize);
Martijn Coenen72110162016-08-19 14:28:25 +0200185 }
186
187 return *this;
188 }
189
Yifan Hong602b85a2016-10-24 13:40:01 -0700190 // copy from an std::vector.
191 hidl_vec &operator=(const std::vector<T> &other) {
192 if (mOwnsBuffer) {
193 delete[] mBuffer;
194 }
195 copyFrom(other, other.size());
196 return *this;
197 }
198
199 // cast to an std::vector.
200 operator std::vector<T>() const {
201 std::vector<T> v(mSize);
202 for (size_t i = 0; i < mSize; ++i) {
203 v[i] = mBuffer[i];
204 }
205 return v;
206 }
207
Martijn Coenen72110162016-08-19 14:28:25 +0200208 size_t size() const {
209 return mSize;
210 }
211
212 T &operator[](size_t index) {
213 return mBuffer[index];
214 }
215
216 const T &operator[](size_t index) const {
217 return mBuffer[index];
218 }
219
220 void resize(size_t size) {
221 T *newBuffer = new T[size];
222
223 for (size_t i = 0; i < std::min(size, mSize); ++i) {
224 newBuffer[i] = mBuffer[i];
225 }
226
227 if (mOwnsBuffer) {
228 delete[] mBuffer;
229 }
230 mBuffer = newBuffer;
231
232 mSize = size;
233 mOwnsBuffer = true;
234 }
235
236 status_t readEmbeddedFromParcel(
237 const Parcel &parcel,
238 size_t parentHandle,
239 size_t parentOffset,
240 size_t *handle);
241
242 status_t writeEmbeddedToParcel(
243 Parcel *parcel,
244 size_t parentHandle,
245 size_t parentOffset,
246 size_t *handle) const;
247
Yifan Hongb1d8d4c2016-08-23 17:39:06 -0700248 status_t findInParcel(const Parcel &parcel, size_t *handle) const {
249 return parcel.quickFindBuffer(mBuffer, handle);
250 }
251
252
Martijn Coenen72110162016-08-19 14:28:25 +0200253private:
254 T *mBuffer;
255 size_t mSize;
256 bool mOwnsBuffer;
Yifan Hong602b85a2016-10-24 13:40:01 -0700257
258 // copy from an array-like object, assuming my resources are freed.
259 template <typename Array>
260 void copyFrom(const Array &data, size_t size) {
261 mSize = size;
262 mOwnsBuffer = true;
263 if (mSize > 0) {
264 mBuffer = new T[size];
265 for (size_t i = 0; i < size; ++i) {
266 mBuffer[i] = data[i];
267 }
268 } else {
269 mBuffer = NULL;
270 }
271 }
Martijn Coenen72110162016-08-19 14:28:25 +0200272};
273
Andreas Huber20dce082016-09-22 19:39:13 -0700274////////////////////////////////////////////////////////////////////////////////
275
276namespace details {
277
278 template<size_t SIZE1, size_t... SIZES>
279 struct product {
280 static constexpr size_t value = SIZE1 * product<SIZES...>::value;
281 };
282
283 template<size_t SIZE1>
284 struct product<SIZE1> {
285 static constexpr size_t value = SIZE1;
286 };
287
288 template<typename T, size_t SIZE1, size_t... SIZES>
289 struct accessor {
290 explicit accessor(T *base)
291 : mBase(base) {
292 }
293
294 accessor<T, SIZES...> operator[](size_t index) {
295 return accessor<T, SIZES...>(
296 &mBase[index * product<SIZES...>::value]);
297 }
298
299 private:
300 T *mBase;
301 };
302
303 template<typename T, size_t SIZE1>
304 struct accessor<T, SIZE1> {
305 explicit accessor(T *base)
306 : mBase(base) {
307 }
308
309 T &operator[](size_t index) {
310 return mBase[index];
311 }
312
313 private:
314 T *mBase;
315 };
316
317 template<typename T, size_t SIZE1, size_t... SIZES>
318 struct const_accessor {
319 explicit const_accessor(const T *base)
320 : mBase(base) {
321 }
322
323 const_accessor<T, SIZES...> operator[](size_t index) {
324 return const_accessor<T, SIZES...>(
325 &mBase[index * product<SIZES...>::value]);
326 }
327
328 private:
329 const T *mBase;
330 };
331
332 template<typename T, size_t SIZE1>
333 struct const_accessor<T, SIZE1> {
334 explicit const_accessor(const T *base)
335 : mBase(base) {
336 }
337
338 const T &operator[](size_t index) const {
339 return mBase[index];
340 }
341
342 private:
343 const T *mBase;
344 };
345
346} // namespace details
347
348////////////////////////////////////////////////////////////////////////////////
349
350template<typename T, size_t SIZE1, size_t... SIZES>
351struct hidl_array {
352 hidl_array() = default;
353
354 T *data() { return mBuffer; }
355 const T *data() const { return mBuffer; }
356
357 details::accessor<T, SIZES...> operator[](size_t index) {
358 return details::accessor<T, SIZES...>(
359 &mBuffer[index * details::product<SIZES...>::value]);
360 }
361
362 details::const_accessor<T, SIZES...> operator[](size_t index) const {
363 return details::const_accessor<T, SIZES...>(
364 &mBuffer[index * details::product<SIZES...>::value]);
365 }
366
Andreas Huber00a985c2016-09-28 14:24:53 -0700367 using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;
368
369 static constexpr size_tuple_type size() {
370 return std::make_tuple(SIZE1, SIZES...);
371 }
372
Andreas Huber20dce082016-09-22 19:39:13 -0700373private:
374 T mBuffer[details::product<SIZE1, SIZES...>::value];
375};
376
377template<typename T, size_t SIZE1>
378struct hidl_array<T, SIZE1> {
379 hidl_array() = default;
380
381 T *data() { return mBuffer; }
382 const T *data() const { return mBuffer; }
383
384 T &operator[](size_t index) {
385 return mBuffer[index];
386 }
387
388 const T &operator[](size_t index) const {
389 return mBuffer[index];
390 }
391
Andreas Huber00a985c2016-09-28 14:24:53 -0700392 static constexpr size_t size() { return SIZE1; }
393
Andreas Huber20dce082016-09-22 19:39:13 -0700394private:
395 T mBuffer[SIZE1];
396};
397
398////////////////////////////////////////////////////////////////////////////////
399
Martijn Coenen72110162016-08-19 14:28:25 +0200400template<typename T>
401status_t hidl_vec<T>::readEmbeddedFromParcel(
402 const Parcel &parcel,
403 size_t parentHandle,
404 size_t parentOffset,
405 size_t *handle) {
406 const void *ptr = parcel.readEmbeddedBuffer(
407 handle,
408 parentHandle,
409 parentOffset + offsetof(hidl_vec<T>, mBuffer));
410
411 return ptr != NULL ? OK : UNKNOWN_ERROR;
412}
413
414template<typename T>
415status_t hidl_vec<T>::writeEmbeddedToParcel(
416 Parcel *parcel,
417 size_t parentHandle,
418 size_t parentOffset,
419 size_t *handle) const {
420 return parcel->writeEmbeddedBuffer(
421 mBuffer,
422 sizeof(T) * mSize,
423 handle,
424 parentHandle,
425 parentOffset + offsetof(hidl_vec<T>, mBuffer));
426}
427
Yifan Hongb1d8d4c2016-08-23 17:39:06 -0700428///////////////////////////// pointers for HIDL
429
430template <typename T>
431static status_t readEmbeddedReferenceFromParcel(
432 T const* * /* bufptr */,
433 const Parcel & parcel,
434 size_t parentHandle,
435 size_t parentOffset,
436 size_t *handle,
437 bool *shouldResolveRefInBuffer
438 ) {
439 // *bufptr is ignored because, if I am embedded in some
440 // other buffer, the kernel should have fixed me up already.
441 bool isPreviouslyWritten;
442 status_t result = parcel.readEmbeddedReference(
443 nullptr, // ignored, not written to bufptr.
444 handle,
445 parentHandle,
446 parentOffset,
447 &isPreviouslyWritten);
448 // tell caller to run T::readEmbeddedToParcel and
449 // T::readEmbeddedReferenceToParcel if necessary.
450 // It is not called here because we don't know if these two are valid methods.
451 *shouldResolveRefInBuffer = !isPreviouslyWritten;
452 return result;
453}
454
455template <typename T>
456static status_t writeEmbeddedReferenceToParcel(
457 T const* buf,
458 Parcel *parcel, size_t parentHandle, size_t parentOffset,
459 size_t *handle,
460 bool *shouldResolveRefInBuffer
461 ) {
462
463 if(buf == nullptr) {
464 *shouldResolveRefInBuffer = false;
465 return parcel->writeEmbeddedNullReference(handle, parentHandle, parentOffset);
466 }
467
468 // find whether the buffer exists
469 size_t childHandle, childOffset;
470 status_t result;
471 bool found;
472
473 result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);
474
475 // tell caller to run T::writeEmbeddedToParcel and
476 // T::writeEmbeddedReferenceToParcel if necessary.
477 // It is not called here because we don't know if these two are valid methods.
478 *shouldResolveRefInBuffer = !found;
479
480 if(result != OK) {
481 return result; // bad pointers and length given
482 }
483 if(!found) { // did not find it.
484 return parcel->writeEmbeddedBuffer(buf, sizeof(T), handle,
485 parentHandle, parentOffset);
486 }
487 // found the buffer. easy case.
488 return parcel->writeEmbeddedReference(
489 handle,
490 childHandle,
491 childOffset,
492 parentHandle,
493 parentOffset);
494}
495
496template <typename T>
497static status_t readReferenceFromParcel(
498 T const* *bufptr,
499 const Parcel & parcel,
500 size_t *handle,
501 bool *shouldResolveRefInBuffer
502 ) {
503 bool isPreviouslyWritten;
504 status_t result = parcel.readReference(reinterpret_cast<void const* *>(bufptr),
505 handle, &isPreviouslyWritten);
506 // tell caller to run T::readEmbeddedToParcel and
507 // T::readEmbeddedReferenceToParcel if necessary.
508 // It is not called here because we don't know if these two are valid methods.
509 *shouldResolveRefInBuffer = !isPreviouslyWritten;
510 return result;
511}
512
513template <typename T>
514static status_t writeReferenceToParcel(
515 T const *buf,
516 Parcel * parcel,
517 size_t *handle,
518 bool *shouldResolveRefInBuffer
519 ) {
520
521 if(buf == nullptr) {
522 *shouldResolveRefInBuffer = false;
523 return parcel->writeNullReference(handle);
524 }
525
526 // find whether the buffer exists
527 size_t childHandle, childOffset;
528 status_t result;
529 bool found;
530
531 result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);
532
533 // tell caller to run T::writeEmbeddedToParcel and
534 // T::writeEmbeddedReferenceToParcel if necessary.
535 // It is not called here because we don't know if these two are valid methods.
536 *shouldResolveRefInBuffer = !found;
537
538 if(result != OK) {
539 return result; // bad pointers and length given
540 }
541 if(!found) { // did not find it.
542 return parcel->writeBuffer(buf, sizeof(T), handle);
543 }
544 // found the buffer. easy case.
545 return parcel->writeReference(handle,
546 childHandle, childOffset);
547}
548
Martijn Coenen72110162016-08-19 14:28:25 +0200549// ----------------------------------------------------------------------
550// Version functions
551struct hidl_version {
552public:
Chia-I Wu666b76b2016-10-06 14:15:59 +0800553 constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {}
Martijn Coenen72110162016-08-19 14:28:25 +0200554
555 bool operator==(const hidl_version& other) {
556 return (mMajor == other.get_major() && mMinor == other.get_minor());
557 }
Martijn Coenenc28f1152016-08-22 14:06:56 +0200558
Martijn Coenen097a7672016-09-08 16:56:41 +0200559 constexpr uint16_t get_major() const { return mMajor; }
560 constexpr uint16_t get_minor() const { return mMinor; }
Martijn Coenen72110162016-08-19 14:28:25 +0200561
562 android::status_t writeToParcel(android::hardware::Parcel& parcel) const {
Chia-I Wu666b76b2016-10-06 14:15:59 +0800563 return parcel.writeUint32(static_cast<uint32_t>(mMajor) << 16 | mMinor);
Martijn Coenen72110162016-08-19 14:28:25 +0200564 }
565
566 static hidl_version* readFromParcel(const android::hardware::Parcel& parcel) {
567 uint32_t version;
568 android::status_t status = parcel.readUint32(&version);
569 if (status != OK) {
570 return nullptr;
571 } else {
572 return new hidl_version(version >> 16, version & 0xFFFF);
573 }
574 }
575
576private:
577 uint16_t mMajor;
578 uint16_t mMinor;
579};
580
581inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
582 return hidl_version(major,minor);
583}
584
Yifan Honga3c31842016-10-21 10:33:14 -0700585struct IHidlInterfaceBase : virtual public RefBase {
586 virtual bool isRemote() const = 0;
587 // HIDL reserved methods follow.
588 virtual ::android::hardware::Return<void> interfaceChain(
589 std::function<void(const hidl_vec<hidl_string>&)> _hidl_cb) = 0;
590 // descriptor for HIDL reserved methods.
591 static const ::android::String16 descriptor;
592};
593
Steven Morelandbdf26662016-09-02 11:03:15 -0700594#if defined(__LP64__)
595#define HAL_LIBRARY_PATH_SYSTEM "/system/lib64/hw/"
596#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib64/hw/"
597#define HAL_LIBRARY_PATH_ODM "/odm/lib64/hw/"
598#else
599#define HAL_LIBRARY_PATH_SYSTEM "/system/lib/hw/"
600#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib/hw/"
601#define HAL_LIBRARY_PATH_ODM "/odm/lib/hw/"
602#endif
603
Martijn Coenenc28f1152016-08-22 14:06:56 +0200604#define DECLARE_REGISTER_AND_GET_SERVICE(INTERFACE) \
605 static ::android::sp<I##INTERFACE> getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700606 const std::string &serviceName, bool getStub=false); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700607 status_t registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200608 const std::string &serviceName); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200609
Steven Morelandbdf26662016-09-02 11:03:15 -0700610#define IMPLEMENT_REGISTER_AND_GET_SERVICE(INTERFACE, LIB) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200611 ::android::sp<I##INTERFACE> I##INTERFACE::getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700612 const std::string &serviceName, bool getStub) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200613 { \
614 sp<I##INTERFACE> iface; \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700615 const struct timespec DELAY {1,0}; \
616 unsigned retries = 3; \
Martijn Coenen270cb502016-10-25 00:19:56 +0200617 const sp<IServiceManager> sm = defaultServiceManager(); \
618 if (sm != nullptr && !getStub) { \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700619 do { \
Martijn Coenen270cb502016-10-25 00:19:56 +0200620 sp<IBinder> binderIface = \
621 sm->checkService(String16(serviceName.c_str()), \
622 I##INTERFACE::version); \
623 iface = IHw##INTERFACE::asInterface(binderIface); \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700624 if (iface != nullptr) { \
625 return iface; \
626 } \
627 TEMP_FAILURE_RETRY(nanosleep(&DELAY, nullptr)); \
628 } while (retries--); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700629 } \
630 int dlMode = RTLD_LAZY; \
631 void *handle = dlopen(HAL_LIBRARY_PATH_ODM LIB, dlMode); \
632 if (handle == nullptr) { \
633 handle = dlopen(HAL_LIBRARY_PATH_VENDOR LIB, dlMode); \
634 } \
635 if (handle == nullptr) { \
636 handle = dlopen(HAL_LIBRARY_PATH_SYSTEM LIB, dlMode); \
637 } \
638 if (handle == nullptr) { \
639 return iface; \
640 } \
641 I##INTERFACE* (*generator)(const char* name); \
642 *(void **)(&generator) = dlsym(handle, "HIDL_FETCH_I"#INTERFACE); \
643 if (generator) { \
Martijn Coenenf7a651d2016-09-08 13:38:12 +0200644 iface = (*generator)(serviceName.c_str()); \
Steven Moreland7391bc32016-09-14 10:31:48 -0700645 if (iface != nullptr) { \
646 iface = new Bs##INTERFACE(iface); \
647 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700648 } \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200649 return iface; \
650 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700651 status_t I##INTERFACE::registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200652 const std::string &serviceName) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200653 { \
654 sp<Bn##INTERFACE> binderIface = new Bn##INTERFACE(this); \
655 const sp<IServiceManager> sm = defaultServiceManager(); \
Martijn Coenen097a7672016-09-08 16:56:41 +0200656 return sm->addService(String16(serviceName.c_str()), binderIface, \
657 I##INTERFACE::version); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200658 }
659
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700660// ----------------------------------------------------------------------
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700661// Class that provides Hidl instrumentation utilities.
662struct HidlInstrumentor {
663 // Event that triggers the instrumentation. e.g. enter of an API call on
664 // the server/client side, exit of an API call on the server/client side
665 // etc.
666 enum InstrumentationEvent {
667 SERVER_API_ENTRY = 0,
668 SERVER_API_EXIT,
669 CLIENT_API_ENTRY,
670 CLIENT_API_EXIT,
671 SYNC_CALLBACK_ENTRY,
672 SYNC_CALLBACK_EXIT,
673 ASYNC_CALLBACK_ENTRY,
674 ASYNC_CALLBACK_EXIT,
675 };
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700676
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700677 // Signature of the instrumentation callback function.
678 using InstrumentationCallback = std::function<void(
679 const InstrumentationEvent event,
680 const char *package,
681 const char *version,
682 const char *interface,
683 const char *method,
684 std::vector<void *> *args)>;
685
686 explicit HidlInstrumentor(const std::string &prefix);
687 virtual ~HidlInstrumentor();
688
689 protected:
690 // Function that lookup and dynamically loads the hidl instrumentation
691 // libraries and registers the instrumentation callback functions.
692 //
693 // The instrumentation libraries should be stored under any of the following
694 // directories: HAL_LIBRARY_PATH_SYSTEM, HAL_LIBRARY_PATH_VENDOR and
695 // HAL_LIBRARY_PATH_ODM. The name of instrumentation libraries should
696 // follow pattern: ^profilerPrefix(.*).profiler.so$
697 //
698 // Each instrumentation library is expected to implement the instrumentation
699 // function called HIDL_INSTRUMENTATION_FUNCTION.
700 //
701 // A no-op for user build.
702 void registerInstrumentationCallbacks(
703 const std::string &profilerPrefix,
704 std::vector<InstrumentationCallback> *instrumentationCallbacks);
705
706 // Utility function to determine whether a give file is a instrumentation
707 // library (i.e. the file name follow the expected pattern).
708 bool isInstrumentationLib(
709 const std::string &profilerPrefix,
710 const dirent *file);
711 // A list of registered instrumentation callbacks.
712 std::vector<InstrumentationCallback> mInstrumentationCallbacks;
713 // Flag whether to enable instrumentation.
714 bool mEnableInstrumentation;
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700715};
716
Martijn Coenen72110162016-08-19 14:28:25 +0200717} // namespace hardware
718} // namespace android
719
Martijn Coenenc28f1152016-08-22 14:06:56 +0200720
Martijn Coenen72110162016-08-19 14:28:25 +0200721#endif // ANDROID_HIDL_SUPPORT_H
722