blob: b78d0a9cafd64364877c0072f28e9c74ae263a4e [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>
Yifan Hong190e4292016-10-21 10:34:25 -070025#include <hwbinder/IBinder.h>
Martijn Coenen72110162016-08-19 14:28:25 +020026#include <hwbinder/Parcel.h>
Andreas Huber00a985c2016-09-28 14:24:53 -070027#include <tuple>
Iliyan Malchev692070a2016-09-12 16:30:44 -070028#include <utils/Errors.h>
29#include <utils/RefBase.h>
30#include <utils/StrongPointer.h>
Martijn Coenen72110162016-08-19 14:28:25 +020031
32namespace android {
33namespace hardware {
34
35struct hidl_string {
36 hidl_string();
37 ~hidl_string();
38
Yifan Hong602b85a2016-10-24 13:40:01 -070039 // copy constructor.
Martijn Coenen72110162016-08-19 14:28:25 +020040 hidl_string(const hidl_string &);
Yifan Hong602b85a2016-10-24 13:40:01 -070041 // copy from a C-style string.
Steven Morelande03c0872016-10-24 10:43:50 -070042 hidl_string(const char *);
Yifan Hong602b85a2016-10-24 13:40:01 -070043 // copy from an std::string.
44 hidl_string(const std::string &);
45
46 // move constructor.
47 hidl_string(hidl_string &&);
Martijn Coenen72110162016-08-19 14:28:25 +020048
49 const char *c_str() const;
50 size_t size() const;
51 bool empty() const;
52
Yifan Hong602b85a2016-10-24 13:40:01 -070053 // copy assignment operator.
Steven Morelande03c0872016-10-24 10:43:50 -070054 hidl_string &operator=(const hidl_string &);
Yifan Hong602b85a2016-10-24 13:40:01 -070055 // copy from a C-style string.
Martijn Coenen72110162016-08-19 14:28:25 +020056 hidl_string &operator=(const char *s);
Yifan Hong602b85a2016-10-24 13:40:01 -070057 // copy from an std::string.
58 hidl_string &operator=(const std::string &);
59 // move assignment operator.
60 hidl_string &operator=(hidl_string &&other);
61 // cast to std::string.
62 operator std::string() const;
63 // cast to C-style string. Caller is responsible
64 // to maintain this hidl_string alive.
65 operator const char *() const;
Steven Morelande03c0872016-10-24 10:43:50 -070066
Martijn Coenen72110162016-08-19 14:28:25 +020067 void clear();
68
69 // Reference an external char array. Ownership is _not_ transferred.
70 // Caller is responsible for ensuring that underlying memory is valid
71 // for the lifetime of this hidl_string.
72 void setToExternal(const char *data, size_t size);
73
74 status_t readEmbeddedFromParcel(
75 const Parcel &parcel, size_t parentHandle, size_t parentOffset);
76
77 status_t writeEmbeddedToParcel(
78 Parcel *parcel, size_t parentHandle, size_t parentOffset) const;
79
Andreas Huberebfeb362016-08-25 13:39:05 -070080 // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
81 static const size_t kOffsetOfBuffer;
82
Martijn Coenen72110162016-08-19 14:28:25 +020083private:
Yifan Hong602b85a2016-10-24 13:40:01 -070084 const char *mBuffer;
Martijn Coenen72110162016-08-19 14:28:25 +020085 size_t mSize; // NOT including the terminating '\0'.
Yifan Hong602b85a2016-10-24 13:40:01 -070086 bool mOwnsBuffer; // if true then mBuffer is a mutable char *
Martijn Coenen72110162016-08-19 14:28:25 +020087
Yifan Hong602b85a2016-10-24 13:40:01 -070088 // copy from data with size. Assume that my memory is freed
89 // (through clear(), for example)
90 void copyFrom(const char *data, size_t size);
91 // move from another hidl_string
92 void moveFrom(hidl_string &&);
Martijn Coenen72110162016-08-19 14:28:25 +020093};
94
Yifan Hong5708fb42016-10-26 17:50:29 -070095inline bool operator==(const hidl_string &hs, const char *s) {
96 return strcmp(hs.c_str(), s) == 0;
97}
98
99inline bool operator!=(const hidl_string &hs, const char *s) {
100 return !(hs == s);
101}
102
103inline bool operator==(const char *s, const hidl_string &hs) {
104 return strcmp(hs.c_str(), s) == 0;
105}
106
107inline bool operator!=(const char *s, const hidl_string &hs) {
108 return !(s == hs);
109}
110
Andreas Huber20dce082016-09-22 19:39:13 -0700111////////////////////////////////////////////////////////////////////////////////
112
Martijn Coenen72110162016-08-19 14:28:25 +0200113template<typename T>
114struct hidl_vec {
115 hidl_vec()
116 : mBuffer(NULL),
117 mSize(0),
118 mOwnsBuffer(true) {
119 }
120
Yifan Hong602b85a2016-10-24 13:40:01 -0700121 hidl_vec(const hidl_vec<T> &other) : hidl_vec() {
Martijn Coenen72110162016-08-19 14:28:25 +0200122 *this = other;
123 }
124
Janis Danisevskisd3ddf622016-10-24 11:40:50 +0100125 hidl_vec(hidl_vec<T> &&other)
126 : mOwnsBuffer(false) {
127 *this = std::move(other);
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700128 }
129
Yifan Hong602b85a2016-10-24 13:40:01 -0700130 hidl_vec(const std::vector<T> &other) : hidl_vec() {
131 *this = other;
132 }
133
Martijn Coenen72110162016-08-19 14:28:25 +0200134 ~hidl_vec() {
135 if (mOwnsBuffer) {
136 delete[] mBuffer;
137 }
138 mBuffer = NULL;
139 }
140
Alexey Polyudove2299012016-10-19 09:52:00 -0700141 // Reference an existing array, optionally taking ownership. It is the
Martijn Coenen72110162016-08-19 14:28:25 +0200142 // caller's responsibility to ensure that the underlying memory stays
143 // valid for the lifetime of this hidl_vec.
Alexey Polyudove2299012016-10-19 09:52:00 -0700144 void setToExternal(T *data, size_t size, bool shouldOwn = false) {
Martijn Coenen72110162016-08-19 14:28:25 +0200145 if (mOwnsBuffer) {
146 delete [] mBuffer;
147 }
148 mBuffer = data;
149 mSize = size;
Alexey Polyudove2299012016-10-19 09:52:00 -0700150 mOwnsBuffer = shouldOwn;
Martijn Coenen72110162016-08-19 14:28:25 +0200151 }
152
Alexey Polyudov6f0c9a12016-10-18 09:37:35 -0700153 T *data() {
154 return mBuffer;
155 }
156
157 const T *data() const {
158 return mBuffer;
159 }
160
Alexey Polyudovc98a99c2016-10-18 09:43:56 -0700161 T *releaseData() {
162 if (!mOwnsBuffer && mSize > 0) {
163 resize(mSize);
164 }
165 mOwnsBuffer = false;
166 return mBuffer;
167 }
168
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700169 hidl_vec &operator=(hidl_vec &&other) {
Janis Danisevskisd3ddf622016-10-24 11:40:50 +0100170 if (mOwnsBuffer) {
171 delete[] mBuffer;
172 }
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700173 mBuffer = other.mBuffer;
174 mSize = other.mSize;
175 mOwnsBuffer = other.mOwnsBuffer;
176 other.mOwnsBuffer = false;
177 return *this;
178 }
179
Martijn Coenen72110162016-08-19 14:28:25 +0200180 hidl_vec &operator=(const hidl_vec &other) {
181 if (this != &other) {
182 if (mOwnsBuffer) {
183 delete[] mBuffer;
184 }
Yifan Hong602b85a2016-10-24 13:40:01 -0700185 copyFrom(other, other.mSize);
Martijn Coenen72110162016-08-19 14:28:25 +0200186 }
187
188 return *this;
189 }
190
Yifan Hong602b85a2016-10-24 13:40:01 -0700191 // copy from an std::vector.
192 hidl_vec &operator=(const std::vector<T> &other) {
193 if (mOwnsBuffer) {
194 delete[] mBuffer;
195 }
196 copyFrom(other, other.size());
197 return *this;
198 }
199
200 // cast to an std::vector.
201 operator std::vector<T>() const {
202 std::vector<T> v(mSize);
203 for (size_t i = 0; i < mSize; ++i) {
204 v[i] = mBuffer[i];
205 }
206 return v;
207 }
208
Martijn Coenen72110162016-08-19 14:28:25 +0200209 size_t size() const {
210 return mSize;
211 }
212
213 T &operator[](size_t index) {
214 return mBuffer[index];
215 }
216
217 const T &operator[](size_t index) const {
218 return mBuffer[index];
219 }
220
221 void resize(size_t size) {
222 T *newBuffer = new T[size];
223
224 for (size_t i = 0; i < std::min(size, mSize); ++i) {
225 newBuffer[i] = mBuffer[i];
226 }
227
228 if (mOwnsBuffer) {
229 delete[] mBuffer;
230 }
231 mBuffer = newBuffer;
232
233 mSize = size;
234 mOwnsBuffer = true;
235 }
236
237 status_t readEmbeddedFromParcel(
238 const Parcel &parcel,
239 size_t parentHandle,
240 size_t parentOffset,
241 size_t *handle);
242
243 status_t writeEmbeddedToParcel(
244 Parcel *parcel,
245 size_t parentHandle,
246 size_t parentOffset,
247 size_t *handle) const;
248
Yifan Hongb1d8d4c2016-08-23 17:39:06 -0700249 status_t findInParcel(const Parcel &parcel, size_t *handle) const {
250 return parcel.quickFindBuffer(mBuffer, handle);
251 }
252
253
Martijn Coenen72110162016-08-19 14:28:25 +0200254private:
255 T *mBuffer;
256 size_t mSize;
257 bool mOwnsBuffer;
Yifan Hong602b85a2016-10-24 13:40:01 -0700258
259 // copy from an array-like object, assuming my resources are freed.
260 template <typename Array>
261 void copyFrom(const Array &data, size_t size) {
262 mSize = size;
263 mOwnsBuffer = true;
264 if (mSize > 0) {
265 mBuffer = new T[size];
266 for (size_t i = 0; i < size; ++i) {
267 mBuffer[i] = data[i];
268 }
269 } else {
270 mBuffer = NULL;
271 }
272 }
Martijn Coenen72110162016-08-19 14:28:25 +0200273};
274
Andreas Huber20dce082016-09-22 19:39:13 -0700275////////////////////////////////////////////////////////////////////////////////
276
277namespace details {
278
279 template<size_t SIZE1, size_t... SIZES>
280 struct product {
281 static constexpr size_t value = SIZE1 * product<SIZES...>::value;
282 };
283
284 template<size_t SIZE1>
285 struct product<SIZE1> {
286 static constexpr size_t value = SIZE1;
287 };
288
289 template<typename T, size_t SIZE1, size_t... SIZES>
290 struct accessor {
291 explicit accessor(T *base)
292 : mBase(base) {
293 }
294
295 accessor<T, SIZES...> operator[](size_t index) {
296 return accessor<T, SIZES...>(
297 &mBase[index * product<SIZES...>::value]);
298 }
299
300 private:
301 T *mBase;
302 };
303
304 template<typename T, size_t SIZE1>
305 struct accessor<T, SIZE1> {
306 explicit accessor(T *base)
307 : mBase(base) {
308 }
309
310 T &operator[](size_t index) {
311 return mBase[index];
312 }
313
314 private:
315 T *mBase;
316 };
317
318 template<typename T, size_t SIZE1, size_t... SIZES>
319 struct const_accessor {
320 explicit const_accessor(const T *base)
321 : mBase(base) {
322 }
323
324 const_accessor<T, SIZES...> operator[](size_t index) {
325 return const_accessor<T, SIZES...>(
326 &mBase[index * product<SIZES...>::value]);
327 }
328
329 private:
330 const T *mBase;
331 };
332
333 template<typename T, size_t SIZE1>
334 struct const_accessor<T, SIZE1> {
335 explicit const_accessor(const T *base)
336 : mBase(base) {
337 }
338
339 const T &operator[](size_t index) const {
340 return mBase[index];
341 }
342
343 private:
344 const T *mBase;
345 };
346
347} // namespace details
348
349////////////////////////////////////////////////////////////////////////////////
350
351template<typename T, size_t SIZE1, size_t... SIZES>
352struct hidl_array {
353 hidl_array() = default;
354
355 T *data() { return mBuffer; }
356 const T *data() const { return mBuffer; }
357
358 details::accessor<T, SIZES...> operator[](size_t index) {
359 return details::accessor<T, SIZES...>(
360 &mBuffer[index * details::product<SIZES...>::value]);
361 }
362
363 details::const_accessor<T, SIZES...> operator[](size_t index) const {
364 return details::const_accessor<T, SIZES...>(
365 &mBuffer[index * details::product<SIZES...>::value]);
366 }
367
Andreas Huber00a985c2016-09-28 14:24:53 -0700368 using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;
369
370 static constexpr size_tuple_type size() {
371 return std::make_tuple(SIZE1, SIZES...);
372 }
373
Andreas Huber20dce082016-09-22 19:39:13 -0700374private:
375 T mBuffer[details::product<SIZE1, SIZES...>::value];
376};
377
378template<typename T, size_t SIZE1>
379struct hidl_array<T, SIZE1> {
380 hidl_array() = default;
381
382 T *data() { return mBuffer; }
383 const T *data() const { return mBuffer; }
384
385 T &operator[](size_t index) {
386 return mBuffer[index];
387 }
388
389 const T &operator[](size_t index) const {
390 return mBuffer[index];
391 }
392
Andreas Huber00a985c2016-09-28 14:24:53 -0700393 static constexpr size_t size() { return SIZE1; }
394
Andreas Huber20dce082016-09-22 19:39:13 -0700395private:
396 T mBuffer[SIZE1];
397};
398
399////////////////////////////////////////////////////////////////////////////////
400
Martijn Coenen72110162016-08-19 14:28:25 +0200401template<typename T>
402status_t hidl_vec<T>::readEmbeddedFromParcel(
403 const Parcel &parcel,
404 size_t parentHandle,
405 size_t parentOffset,
406 size_t *handle) {
407 const void *ptr = parcel.readEmbeddedBuffer(
408 handle,
409 parentHandle,
410 parentOffset + offsetof(hidl_vec<T>, mBuffer));
411
412 return ptr != NULL ? OK : UNKNOWN_ERROR;
413}
414
415template<typename T>
416status_t hidl_vec<T>::writeEmbeddedToParcel(
417 Parcel *parcel,
418 size_t parentHandle,
419 size_t parentOffset,
420 size_t *handle) const {
421 return parcel->writeEmbeddedBuffer(
422 mBuffer,
423 sizeof(T) * mSize,
424 handle,
425 parentHandle,
426 parentOffset + offsetof(hidl_vec<T>, mBuffer));
427}
428
Yifan Hongb1d8d4c2016-08-23 17:39:06 -0700429///////////////////////////// pointers for HIDL
430
431template <typename T>
432static status_t readEmbeddedReferenceFromParcel(
433 T const* * /* bufptr */,
434 const Parcel & parcel,
435 size_t parentHandle,
436 size_t parentOffset,
437 size_t *handle,
438 bool *shouldResolveRefInBuffer
439 ) {
440 // *bufptr is ignored because, if I am embedded in some
441 // other buffer, the kernel should have fixed me up already.
442 bool isPreviouslyWritten;
443 status_t result = parcel.readEmbeddedReference(
444 nullptr, // ignored, not written to bufptr.
445 handle,
446 parentHandle,
447 parentOffset,
448 &isPreviouslyWritten);
449 // tell caller to run T::readEmbeddedToParcel and
450 // T::readEmbeddedReferenceToParcel if necessary.
451 // It is not called here because we don't know if these two are valid methods.
452 *shouldResolveRefInBuffer = !isPreviouslyWritten;
453 return result;
454}
455
456template <typename T>
457static status_t writeEmbeddedReferenceToParcel(
458 T const* buf,
459 Parcel *parcel, size_t parentHandle, size_t parentOffset,
460 size_t *handle,
461 bool *shouldResolveRefInBuffer
462 ) {
463
464 if(buf == nullptr) {
465 *shouldResolveRefInBuffer = false;
466 return parcel->writeEmbeddedNullReference(handle, parentHandle, parentOffset);
467 }
468
469 // find whether the buffer exists
470 size_t childHandle, childOffset;
471 status_t result;
472 bool found;
473
474 result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);
475
476 // tell caller to run T::writeEmbeddedToParcel and
477 // T::writeEmbeddedReferenceToParcel if necessary.
478 // It is not called here because we don't know if these two are valid methods.
479 *shouldResolveRefInBuffer = !found;
480
481 if(result != OK) {
482 return result; // bad pointers and length given
483 }
484 if(!found) { // did not find it.
485 return parcel->writeEmbeddedBuffer(buf, sizeof(T), handle,
486 parentHandle, parentOffset);
487 }
488 // found the buffer. easy case.
489 return parcel->writeEmbeddedReference(
490 handle,
491 childHandle,
492 childOffset,
493 parentHandle,
494 parentOffset);
495}
496
497template <typename T>
498static status_t readReferenceFromParcel(
499 T const* *bufptr,
500 const Parcel & parcel,
501 size_t *handle,
502 bool *shouldResolveRefInBuffer
503 ) {
504 bool isPreviouslyWritten;
505 status_t result = parcel.readReference(reinterpret_cast<void const* *>(bufptr),
506 handle, &isPreviouslyWritten);
507 // tell caller to run T::readEmbeddedToParcel and
508 // T::readEmbeddedReferenceToParcel if necessary.
509 // It is not called here because we don't know if these two are valid methods.
510 *shouldResolveRefInBuffer = !isPreviouslyWritten;
511 return result;
512}
513
514template <typename T>
515static status_t writeReferenceToParcel(
516 T const *buf,
517 Parcel * parcel,
518 size_t *handle,
519 bool *shouldResolveRefInBuffer
520 ) {
521
522 if(buf == nullptr) {
523 *shouldResolveRefInBuffer = false;
524 return parcel->writeNullReference(handle);
525 }
526
527 // find whether the buffer exists
528 size_t childHandle, childOffset;
529 status_t result;
530 bool found;
531
532 result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);
533
534 // tell caller to run T::writeEmbeddedToParcel and
535 // T::writeEmbeddedReferenceToParcel if necessary.
536 // It is not called here because we don't know if these two are valid methods.
537 *shouldResolveRefInBuffer = !found;
538
539 if(result != OK) {
540 return result; // bad pointers and length given
541 }
542 if(!found) { // did not find it.
543 return parcel->writeBuffer(buf, sizeof(T), handle);
544 }
545 // found the buffer. easy case.
546 return parcel->writeReference(handle,
547 childHandle, childOffset);
548}
549
Martijn Coenen72110162016-08-19 14:28:25 +0200550// ----------------------------------------------------------------------
551// Version functions
552struct hidl_version {
553public:
Chia-I Wu666b76b2016-10-06 14:15:59 +0800554 constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {}
Martijn Coenen72110162016-08-19 14:28:25 +0200555
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700556 bool operator==(const hidl_version& other) const {
Martijn Coenen72110162016-08-19 14:28:25 +0200557 return (mMajor == other.get_major() && mMinor == other.get_minor());
558 }
Martijn Coenenc28f1152016-08-22 14:06:56 +0200559
Martijn Coenen097a7672016-09-08 16:56:41 +0200560 constexpr uint16_t get_major() const { return mMajor; }
561 constexpr uint16_t get_minor() const { return mMinor; }
Martijn Coenen72110162016-08-19 14:28:25 +0200562
563 android::status_t writeToParcel(android::hardware::Parcel& parcel) const {
Chia-I Wu666b76b2016-10-06 14:15:59 +0800564 return parcel.writeUint32(static_cast<uint32_t>(mMajor) << 16 | mMinor);
Martijn Coenen72110162016-08-19 14:28:25 +0200565 }
566
567 static hidl_version* readFromParcel(const android::hardware::Parcel& parcel) {
568 uint32_t version;
569 android::status_t status = parcel.readUint32(&version);
570 if (status != OK) {
571 return nullptr;
572 } else {
573 return new hidl_version(version >> 16, version & 0xFFFF);
574 }
575 }
576
577private:
578 uint16_t mMajor;
579 uint16_t mMinor;
580};
581
582inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
583 return hidl_version(major,minor);
584}
585
Yifan Honga3c31842016-10-21 10:33:14 -0700586struct IHidlInterfaceBase : virtual public RefBase {
587 virtual bool isRemote() const = 0;
Yifan Hong190e4292016-10-21 10:34:25 -0700588 virtual sp<::android::hardware::IBinder> toBinder() = 0;
Yifan Honga3c31842016-10-21 10:33:14 -0700589 // HIDL reserved methods follow.
590 virtual ::android::hardware::Return<void> interfaceChain(
591 std::function<void(const hidl_vec<hidl_string>&)> _hidl_cb) = 0;
592 // descriptor for HIDL reserved methods.
593 static const ::android::String16 descriptor;
594};
595
Yifan Hong190e4292016-10-21 10:34:25 -0700596template<typename IChild, typename IParent, typename BpChild>
597sp<IChild> castInterface(sp<IParent> parent, const char *childIndicator) {
598 if (parent.get() == nullptr) {
599 // casts always succeed with nullptrs.
600 return nullptr;
601 }
602 bool canCast = false;
603 parent->interfaceChain([&](const hidl_vec<hidl_string> &allowedCastTypes) {
604 for (size_t i = 0; i < allowedCastTypes.size(); i++) {
605 if (allowedCastTypes[i] == childIndicator) {
606 canCast = true;
607 break;
608 }
609 }
610 });
611
612 if (!canCast) {
613 return sp<IChild>(nullptr); // cast failed.
614 }
615 if (parent->isRemote()) {
616 // binderized mode. Got BpChild. grab the remote and wrap it.
617 return sp<IChild>(new BpChild(parent->toBinder()));
618 }
619 // Passthrough mode. Got BnChild and BsChild.
620 return sp<IChild>(static_cast<IChild *>(parent.get()));
621}
622
Steven Morelandbdf26662016-09-02 11:03:15 -0700623#if defined(__LP64__)
624#define HAL_LIBRARY_PATH_SYSTEM "/system/lib64/hw/"
625#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib64/hw/"
626#define HAL_LIBRARY_PATH_ODM "/odm/lib64/hw/"
627#else
628#define HAL_LIBRARY_PATH_SYSTEM "/system/lib/hw/"
629#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib/hw/"
630#define HAL_LIBRARY_PATH_ODM "/odm/lib/hw/"
631#endif
632
Martijn Coenenc28f1152016-08-22 14:06:56 +0200633#define DECLARE_REGISTER_AND_GET_SERVICE(INTERFACE) \
634 static ::android::sp<I##INTERFACE> getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700635 const std::string &serviceName, bool getStub=false); \
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700636 ::android::status_t registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200637 const std::string &serviceName); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200638
Steven Morelandbdf26662016-09-02 11:03:15 -0700639#define IMPLEMENT_REGISTER_AND_GET_SERVICE(INTERFACE, LIB) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200640 ::android::sp<I##INTERFACE> I##INTERFACE::getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700641 const std::string &serviceName, bool getStub) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200642 { \
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700643 using ::android::sp; \
644 using ::android::hardware::defaultServiceManager; \
645 using ::android::hardware::IBinder; \
646 using ::android::hidl::manager::V1_0::IServiceManager; \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200647 sp<I##INTERFACE> iface; \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700648 const struct timespec DELAY {1,0}; \
649 unsigned retries = 3; \
Martijn Coenen270cb502016-10-25 00:19:56 +0200650 const sp<IServiceManager> sm = defaultServiceManager(); \
651 if (sm != nullptr && !getStub) { \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700652 do { \
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700653 sp<IBinder> binderIface; \
654 IServiceManager::Version version { \
655 .major = I##INTERFACE::version.get_major(), \
656 .minor = I##INTERFACE::version.get_minor(), \
657 }; \
658 sm->get(serviceName.c_str(), version, \
659 [&binderIface](sp<IBinder> iface) { \
660 binderIface = iface; \
661 }); \
Martijn Coenen270cb502016-10-25 00:19:56 +0200662 iface = IHw##INTERFACE::asInterface(binderIface); \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700663 if (iface != nullptr) { \
664 return iface; \
665 } \
666 TEMP_FAILURE_RETRY(nanosleep(&DELAY, nullptr)); \
667 } while (retries--); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700668 } \
669 int dlMode = RTLD_LAZY; \
670 void *handle = dlopen(HAL_LIBRARY_PATH_ODM LIB, dlMode); \
671 if (handle == nullptr) { \
672 handle = dlopen(HAL_LIBRARY_PATH_VENDOR LIB, dlMode); \
673 } \
674 if (handle == nullptr) { \
675 handle = dlopen(HAL_LIBRARY_PATH_SYSTEM LIB, dlMode); \
676 } \
677 if (handle == nullptr) { \
678 return iface; \
679 } \
680 I##INTERFACE* (*generator)(const char* name); \
681 *(void **)(&generator) = dlsym(handle, "HIDL_FETCH_I"#INTERFACE); \
682 if (generator) { \
Martijn Coenenf7a651d2016-09-08 13:38:12 +0200683 iface = (*generator)(serviceName.c_str()); \
Steven Moreland7391bc32016-09-14 10:31:48 -0700684 if (iface != nullptr) { \
685 iface = new Bs##INTERFACE(iface); \
686 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700687 } \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200688 return iface; \
689 } \
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700690 ::android::status_t I##INTERFACE::registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200691 const std::string &serviceName) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200692 { \
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700693 using ::android::sp; \
694 using ::android::hardware::defaultServiceManager; \
695 using ::android::hidl::manager::V1_0::IServiceManager; \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200696 sp<Bn##INTERFACE> binderIface = new Bn##INTERFACE(this); \
697 const sp<IServiceManager> sm = defaultServiceManager(); \
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700698 IServiceManager::Version version { \
699 .major = I##INTERFACE::version.get_major(), \
700 .minor = I##INTERFACE::version.get_minor(), \
701 }; \
702 sm->add(serviceName.c_str(), binderIface, version); \
703 /* TODO return value */ \
704 return ::android::OK; \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200705 }
706
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700707// ----------------------------------------------------------------------
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700708// Class that provides Hidl instrumentation utilities.
709struct HidlInstrumentor {
710 // Event that triggers the instrumentation. e.g. enter of an API call on
711 // the server/client side, exit of an API call on the server/client side
712 // etc.
713 enum InstrumentationEvent {
714 SERVER_API_ENTRY = 0,
715 SERVER_API_EXIT,
716 CLIENT_API_ENTRY,
717 CLIENT_API_EXIT,
718 SYNC_CALLBACK_ENTRY,
719 SYNC_CALLBACK_EXIT,
720 ASYNC_CALLBACK_ENTRY,
721 ASYNC_CALLBACK_EXIT,
Steven Morelandcefbd6e2016-11-01 10:14:30 -0700722 PASSTHROUGH_ENTRY,
723 PASSTHROUGH_EXIT,
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700724 };
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700725
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700726 // Signature of the instrumentation callback function.
727 using InstrumentationCallback = std::function<void(
728 const InstrumentationEvent event,
729 const char *package,
730 const char *version,
731 const char *interface,
732 const char *method,
733 std::vector<void *> *args)>;
734
735 explicit HidlInstrumentor(const std::string &prefix);
736 virtual ~HidlInstrumentor();
737
738 protected:
739 // Function that lookup and dynamically loads the hidl instrumentation
740 // libraries and registers the instrumentation callback functions.
741 //
742 // The instrumentation libraries should be stored under any of the following
743 // directories: HAL_LIBRARY_PATH_SYSTEM, HAL_LIBRARY_PATH_VENDOR and
744 // HAL_LIBRARY_PATH_ODM. The name of instrumentation libraries should
745 // follow pattern: ^profilerPrefix(.*).profiler.so$
746 //
747 // Each instrumentation library is expected to implement the instrumentation
748 // function called HIDL_INSTRUMENTATION_FUNCTION.
749 //
750 // A no-op for user build.
751 void registerInstrumentationCallbacks(
752 const std::string &profilerPrefix,
753 std::vector<InstrumentationCallback> *instrumentationCallbacks);
754
755 // Utility function to determine whether a give file is a instrumentation
756 // library (i.e. the file name follow the expected pattern).
757 bool isInstrumentationLib(
758 const std::string &profilerPrefix,
759 const dirent *file);
760 // A list of registered instrumentation callbacks.
761 std::vector<InstrumentationCallback> mInstrumentationCallbacks;
762 // Flag whether to enable instrumentation.
763 bool mEnableInstrumentation;
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700764};
765
Martijn Coenen72110162016-08-19 14:28:25 +0200766} // namespace hardware
767} // namespace android
768
Martijn Coenenc28f1152016-08-22 14:06:56 +0200769
Martijn Coenen72110162016-08-19 14:28:25 +0200770#endif // ANDROID_HIDL_SUPPORT_H
771