blob: 07eebebd020ae11a2261077ae2a063fb8699ba74 [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
Janis Danisevskisd3ddf622016-10-24 11:40:50 +0100116 hidl_vec(hidl_vec<T> &&other)
117 : mOwnsBuffer(false) {
118 *this = std::move(other);
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700119 }
120
Yifan Hong602b85a2016-10-24 13:40:01 -0700121 hidl_vec(const std::vector<T> &other) : hidl_vec() {
122 *this = other;
123 }
124
Martijn Coenen72110162016-08-19 14:28:25 +0200125 ~hidl_vec() {
126 if (mOwnsBuffer) {
127 delete[] mBuffer;
128 }
129 mBuffer = NULL;
130 }
131
Alexey Polyudove2299012016-10-19 09:52:00 -0700132 // Reference an existing array, optionally taking ownership. It is the
Martijn Coenen72110162016-08-19 14:28:25 +0200133 // caller's responsibility to ensure that the underlying memory stays
134 // valid for the lifetime of this hidl_vec.
Alexey Polyudove2299012016-10-19 09:52:00 -0700135 void setToExternal(T *data, size_t size, bool shouldOwn = false) {
Martijn Coenen72110162016-08-19 14:28:25 +0200136 if (mOwnsBuffer) {
137 delete [] mBuffer;
138 }
139 mBuffer = data;
140 mSize = size;
Alexey Polyudove2299012016-10-19 09:52:00 -0700141 mOwnsBuffer = shouldOwn;
Martijn Coenen72110162016-08-19 14:28:25 +0200142 }
143
Alexey Polyudov6f0c9a12016-10-18 09:37:35 -0700144 T *data() {
145 return mBuffer;
146 }
147
148 const T *data() const {
149 return mBuffer;
150 }
151
Alexey Polyudovc98a99c2016-10-18 09:43:56 -0700152 T *releaseData() {
153 if (!mOwnsBuffer && mSize > 0) {
154 resize(mSize);
155 }
156 mOwnsBuffer = false;
157 return mBuffer;
158 }
159
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700160 hidl_vec &operator=(hidl_vec &&other) {
Janis Danisevskisd3ddf622016-10-24 11:40:50 +0100161 if (mOwnsBuffer) {
162 delete[] mBuffer;
163 }
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700164 mBuffer = other.mBuffer;
165 mSize = other.mSize;
166 mOwnsBuffer = other.mOwnsBuffer;
167 other.mOwnsBuffer = false;
168 return *this;
169 }
170
Martijn Coenen72110162016-08-19 14:28:25 +0200171 hidl_vec &operator=(const hidl_vec &other) {
172 if (this != &other) {
173 if (mOwnsBuffer) {
174 delete[] mBuffer;
175 }
Yifan Hong602b85a2016-10-24 13:40:01 -0700176 copyFrom(other, other.mSize);
Martijn Coenen72110162016-08-19 14:28:25 +0200177 }
178
179 return *this;
180 }
181
Yifan Hong602b85a2016-10-24 13:40:01 -0700182 // copy from an std::vector.
183 hidl_vec &operator=(const std::vector<T> &other) {
184 if (mOwnsBuffer) {
185 delete[] mBuffer;
186 }
187 copyFrom(other, other.size());
188 return *this;
189 }
190
191 // cast to an std::vector.
192 operator std::vector<T>() const {
193 std::vector<T> v(mSize);
194 for (size_t i = 0; i < mSize; ++i) {
195 v[i] = mBuffer[i];
196 }
197 return v;
198 }
199
Martijn Coenen72110162016-08-19 14:28:25 +0200200 size_t size() const {
201 return mSize;
202 }
203
204 T &operator[](size_t index) {
205 return mBuffer[index];
206 }
207
208 const T &operator[](size_t index) const {
209 return mBuffer[index];
210 }
211
212 void resize(size_t size) {
213 T *newBuffer = new T[size];
214
215 for (size_t i = 0; i < std::min(size, mSize); ++i) {
216 newBuffer[i] = mBuffer[i];
217 }
218
219 if (mOwnsBuffer) {
220 delete[] mBuffer;
221 }
222 mBuffer = newBuffer;
223
224 mSize = size;
225 mOwnsBuffer = true;
226 }
227
228 status_t readEmbeddedFromParcel(
229 const Parcel &parcel,
230 size_t parentHandle,
231 size_t parentOffset,
232 size_t *handle);
233
234 status_t writeEmbeddedToParcel(
235 Parcel *parcel,
236 size_t parentHandle,
237 size_t parentOffset,
238 size_t *handle) const;
239
Yifan Hongb1d8d4c2016-08-23 17:39:06 -0700240 status_t findInParcel(const Parcel &parcel, size_t *handle) const {
241 return parcel.quickFindBuffer(mBuffer, handle);
242 }
243
244
Martijn Coenen72110162016-08-19 14:28:25 +0200245private:
246 T *mBuffer;
247 size_t mSize;
248 bool mOwnsBuffer;
Yifan Hong602b85a2016-10-24 13:40:01 -0700249
250 // copy from an array-like object, assuming my resources are freed.
251 template <typename Array>
252 void copyFrom(const Array &data, size_t size) {
253 mSize = size;
254 mOwnsBuffer = true;
255 if (mSize > 0) {
256 mBuffer = new T[size];
257 for (size_t i = 0; i < size; ++i) {
258 mBuffer[i] = data[i];
259 }
260 } else {
261 mBuffer = NULL;
262 }
263 }
Martijn Coenen72110162016-08-19 14:28:25 +0200264};
265
Andreas Huber20dce082016-09-22 19:39:13 -0700266////////////////////////////////////////////////////////////////////////////////
267
268namespace details {
269
270 template<size_t SIZE1, size_t... SIZES>
271 struct product {
272 static constexpr size_t value = SIZE1 * product<SIZES...>::value;
273 };
274
275 template<size_t SIZE1>
276 struct product<SIZE1> {
277 static constexpr size_t value = SIZE1;
278 };
279
280 template<typename T, size_t SIZE1, size_t... SIZES>
281 struct accessor {
282 explicit accessor(T *base)
283 : mBase(base) {
284 }
285
286 accessor<T, SIZES...> operator[](size_t index) {
287 return accessor<T, SIZES...>(
288 &mBase[index * product<SIZES...>::value]);
289 }
290
291 private:
292 T *mBase;
293 };
294
295 template<typename T, size_t SIZE1>
296 struct accessor<T, SIZE1> {
297 explicit accessor(T *base)
298 : mBase(base) {
299 }
300
301 T &operator[](size_t index) {
302 return mBase[index];
303 }
304
305 private:
306 T *mBase;
307 };
308
309 template<typename T, size_t SIZE1, size_t... SIZES>
310 struct const_accessor {
311 explicit const_accessor(const T *base)
312 : mBase(base) {
313 }
314
315 const_accessor<T, SIZES...> operator[](size_t index) {
316 return const_accessor<T, SIZES...>(
317 &mBase[index * product<SIZES...>::value]);
318 }
319
320 private:
321 const T *mBase;
322 };
323
324 template<typename T, size_t SIZE1>
325 struct const_accessor<T, SIZE1> {
326 explicit const_accessor(const T *base)
327 : mBase(base) {
328 }
329
330 const T &operator[](size_t index) const {
331 return mBase[index];
332 }
333
334 private:
335 const T *mBase;
336 };
337
338} // namespace details
339
340////////////////////////////////////////////////////////////////////////////////
341
342template<typename T, size_t SIZE1, size_t... SIZES>
343struct hidl_array {
344 hidl_array() = default;
345
346 T *data() { return mBuffer; }
347 const T *data() const { return mBuffer; }
348
349 details::accessor<T, SIZES...> operator[](size_t index) {
350 return details::accessor<T, SIZES...>(
351 &mBuffer[index * details::product<SIZES...>::value]);
352 }
353
354 details::const_accessor<T, SIZES...> operator[](size_t index) const {
355 return details::const_accessor<T, SIZES...>(
356 &mBuffer[index * details::product<SIZES...>::value]);
357 }
358
Andreas Huber00a985c2016-09-28 14:24:53 -0700359 using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;
360
361 static constexpr size_tuple_type size() {
362 return std::make_tuple(SIZE1, SIZES...);
363 }
364
Andreas Huber20dce082016-09-22 19:39:13 -0700365private:
366 T mBuffer[details::product<SIZE1, SIZES...>::value];
367};
368
369template<typename T, size_t SIZE1>
370struct hidl_array<T, SIZE1> {
371 hidl_array() = default;
372
373 T *data() { return mBuffer; }
374 const T *data() const { return mBuffer; }
375
376 T &operator[](size_t index) {
377 return mBuffer[index];
378 }
379
380 const T &operator[](size_t index) const {
381 return mBuffer[index];
382 }
383
Andreas Huber00a985c2016-09-28 14:24:53 -0700384 static constexpr size_t size() { return SIZE1; }
385
Andreas Huber20dce082016-09-22 19:39:13 -0700386private:
387 T mBuffer[SIZE1];
388};
389
390////////////////////////////////////////////////////////////////////////////////
391
Martijn Coenen72110162016-08-19 14:28:25 +0200392template<typename T>
393status_t hidl_vec<T>::readEmbeddedFromParcel(
394 const Parcel &parcel,
395 size_t parentHandle,
396 size_t parentOffset,
397 size_t *handle) {
398 const void *ptr = parcel.readEmbeddedBuffer(
399 handle,
400 parentHandle,
401 parentOffset + offsetof(hidl_vec<T>, mBuffer));
402
403 return ptr != NULL ? OK : UNKNOWN_ERROR;
404}
405
406template<typename T>
407status_t hidl_vec<T>::writeEmbeddedToParcel(
408 Parcel *parcel,
409 size_t parentHandle,
410 size_t parentOffset,
411 size_t *handle) const {
412 return parcel->writeEmbeddedBuffer(
413 mBuffer,
414 sizeof(T) * mSize,
415 handle,
416 parentHandle,
417 parentOffset + offsetof(hidl_vec<T>, mBuffer));
418}
419
Yifan Hongb1d8d4c2016-08-23 17:39:06 -0700420///////////////////////////// pointers for HIDL
421
422template <typename T>
423static status_t readEmbeddedReferenceFromParcel(
424 T const* * /* bufptr */,
425 const Parcel & parcel,
426 size_t parentHandle,
427 size_t parentOffset,
428 size_t *handle,
429 bool *shouldResolveRefInBuffer
430 ) {
431 // *bufptr is ignored because, if I am embedded in some
432 // other buffer, the kernel should have fixed me up already.
433 bool isPreviouslyWritten;
434 status_t result = parcel.readEmbeddedReference(
435 nullptr, // ignored, not written to bufptr.
436 handle,
437 parentHandle,
438 parentOffset,
439 &isPreviouslyWritten);
440 // tell caller to run T::readEmbeddedToParcel and
441 // T::readEmbeddedReferenceToParcel if necessary.
442 // It is not called here because we don't know if these two are valid methods.
443 *shouldResolveRefInBuffer = !isPreviouslyWritten;
444 return result;
445}
446
447template <typename T>
448static status_t writeEmbeddedReferenceToParcel(
449 T const* buf,
450 Parcel *parcel, size_t parentHandle, size_t parentOffset,
451 size_t *handle,
452 bool *shouldResolveRefInBuffer
453 ) {
454
455 if(buf == nullptr) {
456 *shouldResolveRefInBuffer = false;
457 return parcel->writeEmbeddedNullReference(handle, parentHandle, parentOffset);
458 }
459
460 // find whether the buffer exists
461 size_t childHandle, childOffset;
462 status_t result;
463 bool found;
464
465 result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);
466
467 // tell caller to run T::writeEmbeddedToParcel and
468 // T::writeEmbeddedReferenceToParcel if necessary.
469 // It is not called here because we don't know if these two are valid methods.
470 *shouldResolveRefInBuffer = !found;
471
472 if(result != OK) {
473 return result; // bad pointers and length given
474 }
475 if(!found) { // did not find it.
476 return parcel->writeEmbeddedBuffer(buf, sizeof(T), handle,
477 parentHandle, parentOffset);
478 }
479 // found the buffer. easy case.
480 return parcel->writeEmbeddedReference(
481 handle,
482 childHandle,
483 childOffset,
484 parentHandle,
485 parentOffset);
486}
487
488template <typename T>
489static status_t readReferenceFromParcel(
490 T const* *bufptr,
491 const Parcel & parcel,
492 size_t *handle,
493 bool *shouldResolveRefInBuffer
494 ) {
495 bool isPreviouslyWritten;
496 status_t result = parcel.readReference(reinterpret_cast<void const* *>(bufptr),
497 handle, &isPreviouslyWritten);
498 // tell caller to run T::readEmbeddedToParcel and
499 // T::readEmbeddedReferenceToParcel if necessary.
500 // It is not called here because we don't know if these two are valid methods.
501 *shouldResolveRefInBuffer = !isPreviouslyWritten;
502 return result;
503}
504
505template <typename T>
506static status_t writeReferenceToParcel(
507 T const *buf,
508 Parcel * parcel,
509 size_t *handle,
510 bool *shouldResolveRefInBuffer
511 ) {
512
513 if(buf == nullptr) {
514 *shouldResolveRefInBuffer = false;
515 return parcel->writeNullReference(handle);
516 }
517
518 // find whether the buffer exists
519 size_t childHandle, childOffset;
520 status_t result;
521 bool found;
522
523 result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);
524
525 // tell caller to run T::writeEmbeddedToParcel and
526 // T::writeEmbeddedReferenceToParcel if necessary.
527 // It is not called here because we don't know if these two are valid methods.
528 *shouldResolveRefInBuffer = !found;
529
530 if(result != OK) {
531 return result; // bad pointers and length given
532 }
533 if(!found) { // did not find it.
534 return parcel->writeBuffer(buf, sizeof(T), handle);
535 }
536 // found the buffer. easy case.
537 return parcel->writeReference(handle,
538 childHandle, childOffset);
539}
540
Martijn Coenen72110162016-08-19 14:28:25 +0200541// ----------------------------------------------------------------------
542// Version functions
543struct hidl_version {
544public:
Chia-I Wu666b76b2016-10-06 14:15:59 +0800545 constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {}
Martijn Coenen72110162016-08-19 14:28:25 +0200546
547 bool operator==(const hidl_version& other) {
548 return (mMajor == other.get_major() && mMinor == other.get_minor());
549 }
Martijn Coenenc28f1152016-08-22 14:06:56 +0200550
Martijn Coenen097a7672016-09-08 16:56:41 +0200551 constexpr uint16_t get_major() const { return mMajor; }
552 constexpr uint16_t get_minor() const { return mMinor; }
Martijn Coenen72110162016-08-19 14:28:25 +0200553
554 android::status_t writeToParcel(android::hardware::Parcel& parcel) const {
Chia-I Wu666b76b2016-10-06 14:15:59 +0800555 return parcel.writeUint32(static_cast<uint32_t>(mMajor) << 16 | mMinor);
Martijn Coenen72110162016-08-19 14:28:25 +0200556 }
557
558 static hidl_version* readFromParcel(const android::hardware::Parcel& parcel) {
559 uint32_t version;
560 android::status_t status = parcel.readUint32(&version);
561 if (status != OK) {
562 return nullptr;
563 } else {
564 return new hidl_version(version >> 16, version & 0xFFFF);
565 }
566 }
567
568private:
569 uint16_t mMajor;
570 uint16_t mMinor;
571};
572
573inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
574 return hidl_version(major,minor);
575}
576
Yifan Honga3c31842016-10-21 10:33:14 -0700577struct IHidlInterfaceBase : virtual public RefBase {
578 virtual bool isRemote() const = 0;
579 // HIDL reserved methods follow.
580 virtual ::android::hardware::Return<void> interfaceChain(
581 std::function<void(const hidl_vec<hidl_string>&)> _hidl_cb) = 0;
582 // descriptor for HIDL reserved methods.
583 static const ::android::String16 descriptor;
584};
585
Steven Morelandbdf26662016-09-02 11:03:15 -0700586#if defined(__LP64__)
587#define HAL_LIBRARY_PATH_SYSTEM "/system/lib64/hw/"
588#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib64/hw/"
589#define HAL_LIBRARY_PATH_ODM "/odm/lib64/hw/"
590#else
591#define HAL_LIBRARY_PATH_SYSTEM "/system/lib/hw/"
592#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib/hw/"
593#define HAL_LIBRARY_PATH_ODM "/odm/lib/hw/"
594#endif
595
Martijn Coenenc28f1152016-08-22 14:06:56 +0200596#define DECLARE_REGISTER_AND_GET_SERVICE(INTERFACE) \
597 static ::android::sp<I##INTERFACE> getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700598 const std::string &serviceName, bool getStub=false); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700599 status_t registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200600 const std::string &serviceName); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200601
Steven Morelandbdf26662016-09-02 11:03:15 -0700602#define IMPLEMENT_REGISTER_AND_GET_SERVICE(INTERFACE, LIB) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200603 ::android::sp<I##INTERFACE> I##INTERFACE::getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700604 const std::string &serviceName, bool getStub) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200605 { \
606 sp<I##INTERFACE> iface; \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700607 const struct timespec DELAY {1,0}; \
608 unsigned retries = 3; \
Martijn Coenen270cb502016-10-25 00:19:56 +0200609 const sp<IServiceManager> sm = defaultServiceManager(); \
610 if (sm != nullptr && !getStub) { \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700611 do { \
Martijn Coenen270cb502016-10-25 00:19:56 +0200612 sp<IBinder> binderIface = \
613 sm->checkService(String16(serviceName.c_str()), \
614 I##INTERFACE::version); \
615 iface = IHw##INTERFACE::asInterface(binderIface); \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700616 if (iface != nullptr) { \
617 return iface; \
618 } \
619 TEMP_FAILURE_RETRY(nanosleep(&DELAY, nullptr)); \
620 } while (retries--); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700621 } \
622 int dlMode = RTLD_LAZY; \
623 void *handle = dlopen(HAL_LIBRARY_PATH_ODM LIB, dlMode); \
624 if (handle == nullptr) { \
625 handle = dlopen(HAL_LIBRARY_PATH_VENDOR LIB, dlMode); \
626 } \
627 if (handle == nullptr) { \
628 handle = dlopen(HAL_LIBRARY_PATH_SYSTEM LIB, dlMode); \
629 } \
630 if (handle == nullptr) { \
631 return iface; \
632 } \
633 I##INTERFACE* (*generator)(const char* name); \
634 *(void **)(&generator) = dlsym(handle, "HIDL_FETCH_I"#INTERFACE); \
635 if (generator) { \
Martijn Coenenf7a651d2016-09-08 13:38:12 +0200636 iface = (*generator)(serviceName.c_str()); \
Steven Moreland7391bc32016-09-14 10:31:48 -0700637 if (iface != nullptr) { \
638 iface = new Bs##INTERFACE(iface); \
639 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700640 } \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200641 return iface; \
642 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700643 status_t I##INTERFACE::registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200644 const std::string &serviceName) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200645 { \
646 sp<Bn##INTERFACE> binderIface = new Bn##INTERFACE(this); \
647 const sp<IServiceManager> sm = defaultServiceManager(); \
Martijn Coenen097a7672016-09-08 16:56:41 +0200648 return sm->addService(String16(serviceName.c_str()), binderIface, \
649 I##INTERFACE::version); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200650 }
651
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700652// ----------------------------------------------------------------------
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700653// Class that provides Hidl instrumentation utilities.
654struct HidlInstrumentor {
655 // Event that triggers the instrumentation. e.g. enter of an API call on
656 // the server/client side, exit of an API call on the server/client side
657 // etc.
658 enum InstrumentationEvent {
659 SERVER_API_ENTRY = 0,
660 SERVER_API_EXIT,
661 CLIENT_API_ENTRY,
662 CLIENT_API_EXIT,
663 SYNC_CALLBACK_ENTRY,
664 SYNC_CALLBACK_EXIT,
665 ASYNC_CALLBACK_ENTRY,
666 ASYNC_CALLBACK_EXIT,
667 };
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700668
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700669 // Signature of the instrumentation callback function.
670 using InstrumentationCallback = std::function<void(
671 const InstrumentationEvent event,
672 const char *package,
673 const char *version,
674 const char *interface,
675 const char *method,
676 std::vector<void *> *args)>;
677
678 explicit HidlInstrumentor(const std::string &prefix);
679 virtual ~HidlInstrumentor();
680
681 protected:
682 // Function that lookup and dynamically loads the hidl instrumentation
683 // libraries and registers the instrumentation callback functions.
684 //
685 // The instrumentation libraries should be stored under any of the following
686 // directories: HAL_LIBRARY_PATH_SYSTEM, HAL_LIBRARY_PATH_VENDOR and
687 // HAL_LIBRARY_PATH_ODM. The name of instrumentation libraries should
688 // follow pattern: ^profilerPrefix(.*).profiler.so$
689 //
690 // Each instrumentation library is expected to implement the instrumentation
691 // function called HIDL_INSTRUMENTATION_FUNCTION.
692 //
693 // A no-op for user build.
694 void registerInstrumentationCallbacks(
695 const std::string &profilerPrefix,
696 std::vector<InstrumentationCallback> *instrumentationCallbacks);
697
698 // Utility function to determine whether a give file is a instrumentation
699 // library (i.e. the file name follow the expected pattern).
700 bool isInstrumentationLib(
701 const std::string &profilerPrefix,
702 const dirent *file);
703 // A list of registered instrumentation callbacks.
704 std::vector<InstrumentationCallback> mInstrumentationCallbacks;
705 // Flag whether to enable instrumentation.
706 bool mEnableInstrumentation;
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700707};
708
Martijn Coenen72110162016-08-19 14:28:25 +0200709} // namespace hardware
710} // namespace android
711
Martijn Coenenc28f1152016-08-22 14:06:56 +0200712
Martijn Coenen72110162016-08-19 14:28:25 +0200713#endif // ANDROID_HIDL_SUPPORT_H
714