blob: 4e63613026bf48050ba22073646e7eec88292950 [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 Hong1e265bb2016-11-08 12:33:44 -080024#include <functional>
Yifan Honga3c31842016-10-21 10:33:14 -070025#include <hidl/Status.h>
Yifan Hong190e4292016-10-21 10:34:25 -070026#include <hwbinder/IBinder.h>
Martijn Coenen72110162016-08-19 14:28:25 +020027#include <hwbinder/Parcel.h>
Yifan Hong1e265bb2016-11-08 12:33:44 -080028#include <map>
Andreas Huber00a985c2016-09-28 14:24:53 -070029#include <tuple>
Iliyan Malchev692070a2016-09-12 16:30:44 -070030#include <utils/Errors.h>
31#include <utils/RefBase.h>
32#include <utils/StrongPointer.h>
Martijn Coenen72110162016-08-19 14:28:25 +020033
34namespace android {
35namespace hardware {
36
37struct hidl_string {
38 hidl_string();
39 ~hidl_string();
40
Yifan Hong602b85a2016-10-24 13:40:01 -070041 // copy constructor.
Martijn Coenen72110162016-08-19 14:28:25 +020042 hidl_string(const hidl_string &);
Yifan Hong602b85a2016-10-24 13:40:01 -070043 // copy from a C-style string.
Steven Morelande03c0872016-10-24 10:43:50 -070044 hidl_string(const char *);
Yifan Hong602b85a2016-10-24 13:40:01 -070045 // copy from an std::string.
46 hidl_string(const std::string &);
47
48 // move constructor.
49 hidl_string(hidl_string &&);
Martijn Coenen72110162016-08-19 14:28:25 +020050
51 const char *c_str() const;
52 size_t size() const;
53 bool empty() const;
54
Yifan Hong602b85a2016-10-24 13:40:01 -070055 // copy assignment operator.
Steven Morelande03c0872016-10-24 10:43:50 -070056 hidl_string &operator=(const hidl_string &);
Yifan Hong602b85a2016-10-24 13:40:01 -070057 // copy from a C-style string.
Martijn Coenen72110162016-08-19 14:28:25 +020058 hidl_string &operator=(const char *s);
Yifan Hong602b85a2016-10-24 13:40:01 -070059 // copy from an std::string.
60 hidl_string &operator=(const std::string &);
61 // move assignment operator.
62 hidl_string &operator=(hidl_string &&other);
63 // cast to std::string.
64 operator std::string() const;
65 // cast to C-style string. Caller is responsible
66 // to maintain this hidl_string alive.
67 operator const char *() const;
Steven Morelande03c0872016-10-24 10:43:50 -070068
Martijn Coenen72110162016-08-19 14:28:25 +020069 void clear();
70
71 // Reference an external char array. Ownership is _not_ transferred.
72 // Caller is responsible for ensuring that underlying memory is valid
73 // for the lifetime of this hidl_string.
74 void setToExternal(const char *data, size_t size);
75
Andreas Huberebfeb362016-08-25 13:39:05 -070076 // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
77 static const size_t kOffsetOfBuffer;
78
Martijn Coenen72110162016-08-19 14:28:25 +020079private:
Yifan Hong602b85a2016-10-24 13:40:01 -070080 const char *mBuffer;
Martijn Coenen72110162016-08-19 14:28:25 +020081 size_t mSize; // NOT including the terminating '\0'.
Yifan Hong602b85a2016-10-24 13:40:01 -070082 bool mOwnsBuffer; // if true then mBuffer is a mutable char *
Martijn Coenen72110162016-08-19 14:28:25 +020083
Yifan Hong602b85a2016-10-24 13:40:01 -070084 // copy from data with size. Assume that my memory is freed
85 // (through clear(), for example)
86 void copyFrom(const char *data, size_t size);
87 // move from another hidl_string
88 void moveFrom(hidl_string &&);
Martijn Coenen72110162016-08-19 14:28:25 +020089};
90
Yifan Hong089ae132016-11-11 11:32:52 -080091status_t readEmbeddedFromParcel(hidl_string *string,
92 const Parcel &parcel, size_t parentHandle, size_t parentOffset);
93
94status_t writeEmbeddedToParcel(const hidl_string &string,
95 Parcel *parcel, size_t parentHandle, size_t parentOffset);
96
Yifan Hong5708fb42016-10-26 17:50:29 -070097inline bool operator==(const hidl_string &hs, const char *s) {
98 return strcmp(hs.c_str(), s) == 0;
99}
100
101inline bool operator!=(const hidl_string &hs, const char *s) {
102 return !(hs == s);
103}
104
105inline bool operator==(const char *s, const hidl_string &hs) {
106 return strcmp(hs.c_str(), s) == 0;
107}
108
109inline bool operator!=(const char *s, const hidl_string &hs) {
110 return !(s == hs);
111}
112
Andreas Huber20dce082016-09-22 19:39:13 -0700113////////////////////////////////////////////////////////////////////////////////
114
Martijn Coenen72110162016-08-19 14:28:25 +0200115template<typename T>
116struct hidl_vec {
117 hidl_vec()
118 : mBuffer(NULL),
119 mSize(0),
120 mOwnsBuffer(true) {
121 }
122
Yifan Hong602b85a2016-10-24 13:40:01 -0700123 hidl_vec(const hidl_vec<T> &other) : hidl_vec() {
Martijn Coenen72110162016-08-19 14:28:25 +0200124 *this = other;
125 }
126
Janis Danisevskisd3ddf622016-10-24 11:40:50 +0100127 hidl_vec(hidl_vec<T> &&other)
Steven Moreland9fbfe472016-11-14 16:49:17 -0800128 : mOwnsBuffer(false) {
Janis Danisevskisd3ddf622016-10-24 11:40:50 +0100129 *this = std::move(other);
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700130 }
131
Steven Morelandb69926a2016-11-15 10:02:57 -0800132 hidl_vec(const std::initializer_list<T> list)
Steven Moreland9fbfe472016-11-14 16:49:17 -0800133 : mSize(list.size()),
134 mOwnsBuffer(true) {
135 mBuffer = new T[mSize];
136
Steven Morelandb69926a2016-11-15 10:02:57 -0800137 size_t idx = 0;
Steven Moreland9fbfe472016-11-14 16:49:17 -0800138 for (auto it = list.begin(); it != list.end(); ++it) {
139 mBuffer[idx++] = *it;
140 }
141 }
142
Yifan Hong602b85a2016-10-24 13:40:01 -0700143 hidl_vec(const std::vector<T> &other) : hidl_vec() {
144 *this = other;
145 }
146
Martijn Coenen72110162016-08-19 14:28:25 +0200147 ~hidl_vec() {
148 if (mOwnsBuffer) {
149 delete[] mBuffer;
150 }
151 mBuffer = NULL;
152 }
153
Alexey Polyudove2299012016-10-19 09:52:00 -0700154 // Reference an existing array, optionally taking ownership. It is the
Martijn Coenen72110162016-08-19 14:28:25 +0200155 // caller's responsibility to ensure that the underlying memory stays
156 // valid for the lifetime of this hidl_vec.
Alexey Polyudove2299012016-10-19 09:52:00 -0700157 void setToExternal(T *data, size_t size, bool shouldOwn = false) {
Martijn Coenen72110162016-08-19 14:28:25 +0200158 if (mOwnsBuffer) {
159 delete [] mBuffer;
160 }
161 mBuffer = data;
162 mSize = size;
Alexey Polyudove2299012016-10-19 09:52:00 -0700163 mOwnsBuffer = shouldOwn;
Martijn Coenen72110162016-08-19 14:28:25 +0200164 }
165
Alexey Polyudov6f0c9a12016-10-18 09:37:35 -0700166 T *data() {
167 return mBuffer;
168 }
169
170 const T *data() const {
171 return mBuffer;
172 }
173
Alexey Polyudovc98a99c2016-10-18 09:43:56 -0700174 T *releaseData() {
175 if (!mOwnsBuffer && mSize > 0) {
176 resize(mSize);
177 }
178 mOwnsBuffer = false;
179 return mBuffer;
180 }
181
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700182 hidl_vec &operator=(hidl_vec &&other) {
Janis Danisevskisd3ddf622016-10-24 11:40:50 +0100183 if (mOwnsBuffer) {
184 delete[] mBuffer;
185 }
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700186 mBuffer = other.mBuffer;
187 mSize = other.mSize;
188 mOwnsBuffer = other.mOwnsBuffer;
189 other.mOwnsBuffer = false;
190 return *this;
191 }
192
Martijn Coenen72110162016-08-19 14:28:25 +0200193 hidl_vec &operator=(const hidl_vec &other) {
194 if (this != &other) {
195 if (mOwnsBuffer) {
196 delete[] mBuffer;
197 }
Yifan Hong602b85a2016-10-24 13:40:01 -0700198 copyFrom(other, other.mSize);
Martijn Coenen72110162016-08-19 14:28:25 +0200199 }
200
201 return *this;
202 }
203
Yifan Hong602b85a2016-10-24 13:40:01 -0700204 // copy from an std::vector.
205 hidl_vec &operator=(const std::vector<T> &other) {
206 if (mOwnsBuffer) {
207 delete[] mBuffer;
208 }
209 copyFrom(other, other.size());
210 return *this;
211 }
212
213 // cast to an std::vector.
214 operator std::vector<T>() const {
215 std::vector<T> v(mSize);
216 for (size_t i = 0; i < mSize; ++i) {
217 v[i] = mBuffer[i];
218 }
219 return v;
220 }
221
Martijn Coenen72110162016-08-19 14:28:25 +0200222 size_t size() const {
223 return mSize;
224 }
225
226 T &operator[](size_t index) {
227 return mBuffer[index];
228 }
229
230 const T &operator[](size_t index) const {
231 return mBuffer[index];
232 }
233
234 void resize(size_t size) {
235 T *newBuffer = new T[size];
236
237 for (size_t i = 0; i < std::min(size, mSize); ++i) {
238 newBuffer[i] = mBuffer[i];
239 }
240
241 if (mOwnsBuffer) {
242 delete[] mBuffer;
243 }
244 mBuffer = newBuffer;
245
246 mSize = size;
247 mOwnsBuffer = true;
248 }
249
Yifan Hongb1d8d4c2016-08-23 17:39:06 -0700250 status_t findInParcel(const Parcel &parcel, size_t *handle) const {
251 return parcel.quickFindBuffer(mBuffer, handle);
252 }
253
Yifan Hong089ae132016-11-11 11:32:52 -0800254 // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
255 static const size_t kOffsetOfBuffer;
Martijn Coenen72110162016-08-19 14:28:25 +0200256private:
257 T *mBuffer;
258 size_t mSize;
259 bool mOwnsBuffer;
Yifan Hong602b85a2016-10-24 13:40:01 -0700260
261 // copy from an array-like object, assuming my resources are freed.
262 template <typename Array>
263 void copyFrom(const Array &data, size_t size) {
264 mSize = size;
265 mOwnsBuffer = true;
266 if (mSize > 0) {
267 mBuffer = new T[size];
268 for (size_t i = 0; i < size; ++i) {
269 mBuffer[i] = data[i];
270 }
271 } else {
272 mBuffer = NULL;
273 }
274 }
Martijn Coenen72110162016-08-19 14:28:25 +0200275};
276
Yifan Hong089ae132016-11-11 11:32:52 -0800277template <typename T>
278const size_t hidl_vec<T>::kOffsetOfBuffer = offsetof(hidl_vec<T>, mBuffer);
279
280template<typename T>
281status_t readEmbeddedFromParcel(
282 hidl_vec<T> * /*vec*/,
283 const Parcel &parcel,
284 size_t parentHandle,
285 size_t parentOffset,
286 size_t *handle) {
287 const void *ptr = parcel.readEmbeddedBuffer(
288 handle,
289 parentHandle,
290 parentOffset + hidl_vec<T>::kOffsetOfBuffer);
291
292 return ptr != NULL ? OK : UNKNOWN_ERROR;
293}
294
295template<typename T>
296status_t writeEmbeddedToParcel(
297 const hidl_vec<T> &vec,
298 Parcel *parcel,
299 size_t parentHandle,
300 size_t parentOffset,
301 size_t *handle) {
302 return parcel->writeEmbeddedBuffer(
303 vec.data(),
304 sizeof(T) * vec.size(),
305 handle,
306 parentHandle,
307 parentOffset + hidl_vec<T>::kOffsetOfBuffer);
308}
309
Andreas Huber20dce082016-09-22 19:39:13 -0700310////////////////////////////////////////////////////////////////////////////////
311
312namespace details {
313
314 template<size_t SIZE1, size_t... SIZES>
315 struct product {
316 static constexpr size_t value = SIZE1 * product<SIZES...>::value;
317 };
318
319 template<size_t SIZE1>
320 struct product<SIZE1> {
321 static constexpr size_t value = SIZE1;
322 };
323
324 template<typename T, size_t SIZE1, size_t... SIZES>
325 struct accessor {
326 explicit accessor(T *base)
327 : mBase(base) {
328 }
329
330 accessor<T, SIZES...> operator[](size_t index) {
331 return accessor<T, SIZES...>(
332 &mBase[index * product<SIZES...>::value]);
333 }
334
335 private:
336 T *mBase;
337 };
338
339 template<typename T, size_t SIZE1>
340 struct accessor<T, SIZE1> {
341 explicit accessor(T *base)
342 : mBase(base) {
343 }
344
345 T &operator[](size_t index) {
346 return mBase[index];
347 }
348
349 private:
350 T *mBase;
351 };
352
353 template<typename T, size_t SIZE1, size_t... SIZES>
354 struct const_accessor {
355 explicit const_accessor(const T *base)
356 : mBase(base) {
357 }
358
359 const_accessor<T, SIZES...> operator[](size_t index) {
360 return const_accessor<T, SIZES...>(
361 &mBase[index * product<SIZES...>::value]);
362 }
363
364 private:
365 const T *mBase;
366 };
367
368 template<typename T, size_t SIZE1>
369 struct const_accessor<T, SIZE1> {
370 explicit const_accessor(const T *base)
371 : mBase(base) {
372 }
373
374 const T &operator[](size_t index) const {
375 return mBase[index];
376 }
377
378 private:
379 const T *mBase;
380 };
381
382} // namespace details
383
384////////////////////////////////////////////////////////////////////////////////
385
386template<typename T, size_t SIZE1, size_t... SIZES>
387struct hidl_array {
388 hidl_array() = default;
389
390 T *data() { return mBuffer; }
391 const T *data() const { return mBuffer; }
392
393 details::accessor<T, SIZES...> operator[](size_t index) {
394 return details::accessor<T, SIZES...>(
395 &mBuffer[index * details::product<SIZES...>::value]);
396 }
397
398 details::const_accessor<T, SIZES...> operator[](size_t index) const {
399 return details::const_accessor<T, SIZES...>(
400 &mBuffer[index * details::product<SIZES...>::value]);
401 }
402
Andreas Huber00a985c2016-09-28 14:24:53 -0700403 using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;
404
405 static constexpr size_tuple_type size() {
406 return std::make_tuple(SIZE1, SIZES...);
407 }
408
Andreas Huber20dce082016-09-22 19:39:13 -0700409private:
410 T mBuffer[details::product<SIZE1, SIZES...>::value];
411};
412
413template<typename T, size_t SIZE1>
414struct hidl_array<T, SIZE1> {
415 hidl_array() = default;
416
417 T *data() { return mBuffer; }
418 const T *data() const { return mBuffer; }
419
420 T &operator[](size_t index) {
421 return mBuffer[index];
422 }
423
424 const T &operator[](size_t index) const {
425 return mBuffer[index];
426 }
427
Andreas Huber00a985c2016-09-28 14:24:53 -0700428 static constexpr size_t size() { return SIZE1; }
429
Andreas Huber20dce082016-09-22 19:39:13 -0700430private:
431 T mBuffer[SIZE1];
432};
433
Yifan Hongb1d8d4c2016-08-23 17:39:06 -0700434///////////////////////////// pointers for HIDL
435
436template <typename T>
437static status_t readEmbeddedReferenceFromParcel(
438 T const* * /* bufptr */,
439 const Parcel & parcel,
440 size_t parentHandle,
441 size_t parentOffset,
442 size_t *handle,
443 bool *shouldResolveRefInBuffer
444 ) {
445 // *bufptr is ignored because, if I am embedded in some
446 // other buffer, the kernel should have fixed me up already.
447 bool isPreviouslyWritten;
448 status_t result = parcel.readEmbeddedReference(
449 nullptr, // ignored, not written to bufptr.
450 handle,
451 parentHandle,
452 parentOffset,
453 &isPreviouslyWritten);
454 // tell caller to run T::readEmbeddedToParcel and
455 // T::readEmbeddedReferenceToParcel if necessary.
456 // It is not called here because we don't know if these two are valid methods.
457 *shouldResolveRefInBuffer = !isPreviouslyWritten;
458 return result;
459}
460
461template <typename T>
462static status_t writeEmbeddedReferenceToParcel(
463 T const* buf,
464 Parcel *parcel, size_t parentHandle, size_t parentOffset,
465 size_t *handle,
466 bool *shouldResolveRefInBuffer
467 ) {
468
469 if(buf == nullptr) {
470 *shouldResolveRefInBuffer = false;
471 return parcel->writeEmbeddedNullReference(handle, parentHandle, parentOffset);
472 }
473
474 // find whether the buffer exists
475 size_t childHandle, childOffset;
476 status_t result;
477 bool found;
478
479 result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);
480
481 // tell caller to run T::writeEmbeddedToParcel and
482 // T::writeEmbeddedReferenceToParcel if necessary.
483 // It is not called here because we don't know if these two are valid methods.
484 *shouldResolveRefInBuffer = !found;
485
486 if(result != OK) {
487 return result; // bad pointers and length given
488 }
489 if(!found) { // did not find it.
490 return parcel->writeEmbeddedBuffer(buf, sizeof(T), handle,
491 parentHandle, parentOffset);
492 }
493 // found the buffer. easy case.
494 return parcel->writeEmbeddedReference(
495 handle,
496 childHandle,
497 childOffset,
498 parentHandle,
499 parentOffset);
500}
501
502template <typename T>
503static status_t readReferenceFromParcel(
504 T const* *bufptr,
505 const Parcel & parcel,
506 size_t *handle,
507 bool *shouldResolveRefInBuffer
508 ) {
509 bool isPreviouslyWritten;
510 status_t result = parcel.readReference(reinterpret_cast<void const* *>(bufptr),
511 handle, &isPreviouslyWritten);
512 // tell caller to run T::readEmbeddedToParcel and
513 // T::readEmbeddedReferenceToParcel if necessary.
514 // It is not called here because we don't know if these two are valid methods.
515 *shouldResolveRefInBuffer = !isPreviouslyWritten;
516 return result;
517}
518
519template <typename T>
520static status_t writeReferenceToParcel(
521 T const *buf,
522 Parcel * parcel,
523 size_t *handle,
524 bool *shouldResolveRefInBuffer
525 ) {
526
527 if(buf == nullptr) {
528 *shouldResolveRefInBuffer = false;
529 return parcel->writeNullReference(handle);
530 }
531
532 // find whether the buffer exists
533 size_t childHandle, childOffset;
534 status_t result;
535 bool found;
536
537 result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);
538
539 // tell caller to run T::writeEmbeddedToParcel and
540 // T::writeEmbeddedReferenceToParcel if necessary.
541 // It is not called here because we don't know if these two are valid methods.
542 *shouldResolveRefInBuffer = !found;
543
544 if(result != OK) {
545 return result; // bad pointers and length given
546 }
547 if(!found) { // did not find it.
548 return parcel->writeBuffer(buf, sizeof(T), handle);
549 }
550 // found the buffer. easy case.
551 return parcel->writeReference(handle,
552 childHandle, childOffset);
553}
554
Martijn Coenen72110162016-08-19 14:28:25 +0200555// ----------------------------------------------------------------------
556// Version functions
557struct hidl_version {
558public:
Chia-I Wu666b76b2016-10-06 14:15:59 +0800559 constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {}
Martijn Coenen72110162016-08-19 14:28:25 +0200560
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700561 bool operator==(const hidl_version& other) const {
Martijn Coenen72110162016-08-19 14:28:25 +0200562 return (mMajor == other.get_major() && mMinor == other.get_minor());
563 }
Martijn Coenenc28f1152016-08-22 14:06:56 +0200564
Martijn Coenen097a7672016-09-08 16:56:41 +0200565 constexpr uint16_t get_major() const { return mMajor; }
566 constexpr uint16_t get_minor() const { return mMinor; }
Martijn Coenen72110162016-08-19 14:28:25 +0200567
568 android::status_t writeToParcel(android::hardware::Parcel& parcel) const {
Chia-I Wu666b76b2016-10-06 14:15:59 +0800569 return parcel.writeUint32(static_cast<uint32_t>(mMajor) << 16 | mMinor);
Martijn Coenen72110162016-08-19 14:28:25 +0200570 }
571
572 static hidl_version* readFromParcel(const android::hardware::Parcel& parcel) {
573 uint32_t version;
574 android::status_t status = parcel.readUint32(&version);
575 if (status != OK) {
576 return nullptr;
577 } else {
578 return new hidl_version(version >> 16, version & 0xFFFF);
579 }
580 }
581
582private:
583 uint16_t mMajor;
584 uint16_t mMinor;
585};
586
587inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
588 return hidl_version(major,minor);
589}
590
Yifan Hongc1a60ef2016-11-08 18:53:16 -0800591struct IBase : virtual public RefBase {
Yifan Honga3c31842016-10-21 10:33:14 -0700592 virtual bool isRemote() const = 0;
593 // HIDL reserved methods follow.
594 virtual ::android::hardware::Return<void> interfaceChain(
595 std::function<void(const hidl_vec<hidl_string>&)> _hidl_cb) = 0;
596 // descriptor for HIDL reserved methods.
Steven Moreland5a682322016-11-11 12:32:50 -0800597 static const char* descriptor;
Yifan Honga3c31842016-10-21 10:33:14 -0700598};
599
Yifan Hong1e265bb2016-11-08 12:33:44 -0800600extern std::map<std::string, std::function<sp<IBinder>(void*)>> gBnConstructorMap;
601
602// Construct a smallest possible binder from the given interface.
603// If it is remote, then its remote() will be retrieved.
604// Otherwise, the smallest possible BnChild is found where IChild is a subclass of IType
605// and iface is of class IChild. BnChild will be used to wrapped the given iface.
606// Return nullptr if iface is null or any failure.
607template <typename IType, typename IHwType>
608sp<IBinder> toBinder(sp<IType> iface) {
609 IType *ifacePtr = iface.get();
610 if (ifacePtr == nullptr) {
611 return nullptr;
612 }
613 if (ifacePtr->isRemote()) {
614 return ::android::hardware::IInterface::asBinder(static_cast<IHwType *>(ifacePtr));
615 } else {
616 std::string myDescriptor{};
617 ifacePtr->interfaceChain([&](const hidl_vec<hidl_string> &types) {
618 if (types.size() > 0) {
619 myDescriptor = types[0].c_str();
620 }
621 });
622 if (myDescriptor.empty()) {
623 // interfaceChain fails || types.size() == 0
624 return nullptr;
625 }
626 auto iter = gBnConstructorMap.find(myDescriptor);
627 if (iter == gBnConstructorMap.end()) {
628 return nullptr;
629 }
630 return sp<IBinder>((iter->second)(reinterpret_cast<void *>(ifacePtr)));
631 }
632}
633
634// cast the interface IParent to IChild.
635// Return nullptr if parent is null or any failure.
636template<typename IChild, typename IParent, typename BpChild, typename IHwParent>
Yifan Hong190e4292016-10-21 10:34:25 -0700637sp<IChild> castInterface(sp<IParent> parent, const char *childIndicator) {
638 if (parent.get() == nullptr) {
639 // casts always succeed with nullptrs.
640 return nullptr;
641 }
642 bool canCast = false;
643 parent->interfaceChain([&](const hidl_vec<hidl_string> &allowedCastTypes) {
644 for (size_t i = 0; i < allowedCastTypes.size(); i++) {
645 if (allowedCastTypes[i] == childIndicator) {
646 canCast = true;
647 break;
648 }
649 }
650 });
651
652 if (!canCast) {
653 return sp<IChild>(nullptr); // cast failed.
654 }
655 if (parent->isRemote()) {
656 // binderized mode. Got BpChild. grab the remote and wrap it.
Yifan Hong1e265bb2016-11-08 12:33:44 -0800657 return sp<IChild>(new BpChild(toBinder<IParent, IHwParent>(parent)));
Yifan Hong190e4292016-10-21 10:34:25 -0700658 }
659 // Passthrough mode. Got BnChild and BsChild.
660 return sp<IChild>(static_cast<IChild *>(parent.get()));
661}
662
Steven Morelandbdf26662016-09-02 11:03:15 -0700663#if defined(__LP64__)
664#define HAL_LIBRARY_PATH_SYSTEM "/system/lib64/hw/"
665#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib64/hw/"
666#define HAL_LIBRARY_PATH_ODM "/odm/lib64/hw/"
667#else
668#define HAL_LIBRARY_PATH_SYSTEM "/system/lib/hw/"
669#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib/hw/"
670#define HAL_LIBRARY_PATH_ODM "/odm/lib/hw/"
671#endif
672
Steven Moreland40ede2c2016-11-09 13:51:53 -0800673#define DECLARE_SERVICE_MANAGER_INTERACTIONS(INTERFACE) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200674 static ::android::sp<I##INTERFACE> getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700675 const std::string &serviceName, bool getStub=false); \
Steven Moreland40ede2c2016-11-09 13:51:53 -0800676 ::android::status_t registerAsService(const std::string &serviceName); \
677 static bool registerForNotifications( \
678 const std::string &serviceName, \
679 const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> \
680 &notification); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200681
Steven Moreland40ede2c2016-11-09 13:51:53 -0800682#define IMPLEMENT_SERVICE_MANAGER_INTERACTIONS(INTERFACE, PACKAGE) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200683 ::android::sp<I##INTERFACE> I##INTERFACE::getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700684 const std::string &serviceName, bool getStub) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200685 { \
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700686 using ::android::sp; \
687 using ::android::hardware::defaultServiceManager; \
688 using ::android::hardware::IBinder; \
689 using ::android::hidl::manager::V1_0::IServiceManager; \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200690 sp<I##INTERFACE> iface; \
Martijn Coenen270cb502016-10-25 00:19:56 +0200691 const sp<IServiceManager> sm = defaultServiceManager(); \
692 if (sm != nullptr && !getStub) { \
Steven Morelandb8573e12016-11-07 12:40:05 -0800693 sp<IBinder> binderIface; \
Steven Morelandf0cc0972016-11-02 17:51:46 -0700694 ::android::hardware::Return<void> ret = \
695 sm->get(PACKAGE "::I" #INTERFACE, serviceName.c_str(), \
696 [&binderIface](sp<IBinder> iface) { \
697 binderIface = iface; \
698 }); \
699 if (ret.getStatus().isOk()) { \
700 iface = IHw##INTERFACE::asInterface(binderIface); \
701 if (iface != nullptr) { \
702 return iface; \
703 } \
Steven Morelandb8573e12016-11-07 12:40:05 -0800704 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700705 } \
706 int dlMode = RTLD_LAZY; \
Steven Morelandf0cc0972016-11-02 17:51:46 -0700707 void *handle = dlopen(HAL_LIBRARY_PATH_ODM PACKAGE "-impl.so", dlMode); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700708 if (handle == nullptr) { \
Steven Morelandf0cc0972016-11-02 17:51:46 -0700709 handle = dlopen(HAL_LIBRARY_PATH_VENDOR PACKAGE "-impl.so", dlMode); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700710 } \
711 if (handle == nullptr) { \
Steven Morelandf0cc0972016-11-02 17:51:46 -0700712 handle = dlopen(HAL_LIBRARY_PATH_SYSTEM PACKAGE "-impl.so", dlMode); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700713 } \
714 if (handle == nullptr) { \
715 return iface; \
716 } \
717 I##INTERFACE* (*generator)(const char* name); \
718 *(void **)(&generator) = dlsym(handle, "HIDL_FETCH_I"#INTERFACE); \
719 if (generator) { \
Martijn Coenenf7a651d2016-09-08 13:38:12 +0200720 iface = (*generator)(serviceName.c_str()); \
Steven Moreland7391bc32016-09-14 10:31:48 -0700721 if (iface != nullptr) { \
722 iface = new Bs##INTERFACE(iface); \
723 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700724 } \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200725 return iface; \
726 } \
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700727 ::android::status_t I##INTERFACE::registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200728 const std::string &serviceName) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200729 { \
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700730 using ::android::sp; \
731 using ::android::hardware::defaultServiceManager; \
732 using ::android::hidl::manager::V1_0::IServiceManager; \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200733 sp<Bn##INTERFACE> binderIface = new Bn##INTERFACE(this); \
734 const sp<IServiceManager> sm = defaultServiceManager(); \
Steven Morelandf0cc0972016-11-02 17:51:46 -0700735 bool success = false; \
736 ::android::hardware::Return<void> ret = \
737 this->interfaceChain( \
738 [&success, &sm, &serviceName, &binderIface](const auto &chain) { \
739 success = sm->add(chain, serviceName.c_str(), binderIface); \
740 }); \
741 success = success && ret.getStatus().isOk(); \
742 return success ? ::android::OK : ::android::UNKNOWN_ERROR; \
Steven Moreland40ede2c2016-11-09 13:51:53 -0800743 } \
744 bool I##INTERFACE::registerForNotifications( \
745 const std::string &serviceName, \
746 const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> \
747 &notification) \
748 { \
749 using ::android::sp; \
750 using ::android::hardware::defaultServiceManager; \
751 using ::android::hidl::manager::V1_0::IServiceManager; \
752 const sp<IServiceManager> sm = defaultServiceManager(); \
753 if (sm == nullptr) { \
754 return false; \
755 } \
756 return sm->registerForNotifications(PACKAGE "::I" #INTERFACE, \
757 serviceName, \
758 notification); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200759 }
760
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700761// ----------------------------------------------------------------------
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700762// Class that provides Hidl instrumentation utilities.
763struct HidlInstrumentor {
764 // Event that triggers the instrumentation. e.g. enter of an API call on
765 // the server/client side, exit of an API call on the server/client side
766 // etc.
767 enum InstrumentationEvent {
768 SERVER_API_ENTRY = 0,
769 SERVER_API_EXIT,
770 CLIENT_API_ENTRY,
771 CLIENT_API_EXIT,
772 SYNC_CALLBACK_ENTRY,
773 SYNC_CALLBACK_EXIT,
774 ASYNC_CALLBACK_ENTRY,
775 ASYNC_CALLBACK_EXIT,
Steven Morelandcefbd6e2016-11-01 10:14:30 -0700776 PASSTHROUGH_ENTRY,
777 PASSTHROUGH_EXIT,
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700778 };
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700779
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700780 // Signature of the instrumentation callback function.
781 using InstrumentationCallback = std::function<void(
782 const InstrumentationEvent event,
783 const char *package,
784 const char *version,
785 const char *interface,
786 const char *method,
787 std::vector<void *> *args)>;
788
789 explicit HidlInstrumentor(const std::string &prefix);
790 virtual ~HidlInstrumentor();
791
792 protected:
793 // Function that lookup and dynamically loads the hidl instrumentation
794 // libraries and registers the instrumentation callback functions.
795 //
796 // The instrumentation libraries should be stored under any of the following
797 // directories: HAL_LIBRARY_PATH_SYSTEM, HAL_LIBRARY_PATH_VENDOR and
798 // HAL_LIBRARY_PATH_ODM. The name of instrumentation libraries should
799 // follow pattern: ^profilerPrefix(.*).profiler.so$
800 //
801 // Each instrumentation library is expected to implement the instrumentation
802 // function called HIDL_INSTRUMENTATION_FUNCTION.
803 //
804 // A no-op for user build.
805 void registerInstrumentationCallbacks(
806 const std::string &profilerPrefix,
807 std::vector<InstrumentationCallback> *instrumentationCallbacks);
808
809 // Utility function to determine whether a give file is a instrumentation
810 // library (i.e. the file name follow the expected pattern).
811 bool isInstrumentationLib(
812 const std::string &profilerPrefix,
813 const dirent *file);
814 // A list of registered instrumentation callbacks.
815 std::vector<InstrumentationCallback> mInstrumentationCallbacks;
816 // Flag whether to enable instrumentation.
817 bool mEnableInstrumentation;
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700818};
819
Martijn Coenen72110162016-08-19 14:28:25 +0200820} // namespace hardware
821} // namespace android
822
Martijn Coenenc28f1152016-08-22 14:06:56 +0200823
Martijn Coenen72110162016-08-19 14:28:25 +0200824#endif // ANDROID_HIDL_SUPPORT_H
825