blob: 5329dec6dbd8875cd5d4002d2dcb0e7f43daad40 [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
76 status_t readEmbeddedFromParcel(
77 const Parcel &parcel, size_t parentHandle, size_t parentOffset);
78
79 status_t writeEmbeddedToParcel(
80 Parcel *parcel, size_t parentHandle, size_t parentOffset) const;
81
Andreas Huberebfeb362016-08-25 13:39:05 -070082 // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
83 static const size_t kOffsetOfBuffer;
84
Martijn Coenen72110162016-08-19 14:28:25 +020085private:
Yifan Hong602b85a2016-10-24 13:40:01 -070086 const char *mBuffer;
Martijn Coenen72110162016-08-19 14:28:25 +020087 size_t mSize; // NOT including the terminating '\0'.
Yifan Hong602b85a2016-10-24 13:40:01 -070088 bool mOwnsBuffer; // if true then mBuffer is a mutable char *
Martijn Coenen72110162016-08-19 14:28:25 +020089
Yifan Hong602b85a2016-10-24 13:40:01 -070090 // copy from data with size. Assume that my memory is freed
91 // (through clear(), for example)
92 void copyFrom(const char *data, size_t size);
93 // move from another hidl_string
94 void moveFrom(hidl_string &&);
Martijn Coenen72110162016-08-19 14:28:25 +020095};
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)
128 : mOwnsBuffer(false) {
129 *this = std::move(other);
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700130 }
131
Yifan Hong602b85a2016-10-24 13:40:01 -0700132 hidl_vec(const std::vector<T> &other) : hidl_vec() {
133 *this = other;
134 }
135
Martijn Coenen72110162016-08-19 14:28:25 +0200136 ~hidl_vec() {
137 if (mOwnsBuffer) {
138 delete[] mBuffer;
139 }
140 mBuffer = NULL;
141 }
142
Alexey Polyudove2299012016-10-19 09:52:00 -0700143 // Reference an existing array, optionally taking ownership. It is the
Martijn Coenen72110162016-08-19 14:28:25 +0200144 // caller's responsibility to ensure that the underlying memory stays
145 // valid for the lifetime of this hidl_vec.
Alexey Polyudove2299012016-10-19 09:52:00 -0700146 void setToExternal(T *data, size_t size, bool shouldOwn = false) {
Martijn Coenen72110162016-08-19 14:28:25 +0200147 if (mOwnsBuffer) {
148 delete [] mBuffer;
149 }
150 mBuffer = data;
151 mSize = size;
Alexey Polyudove2299012016-10-19 09:52:00 -0700152 mOwnsBuffer = shouldOwn;
Martijn Coenen72110162016-08-19 14:28:25 +0200153 }
154
Alexey Polyudov6f0c9a12016-10-18 09:37:35 -0700155 T *data() {
156 return mBuffer;
157 }
158
159 const T *data() const {
160 return mBuffer;
161 }
162
Alexey Polyudovc98a99c2016-10-18 09:43:56 -0700163 T *releaseData() {
164 if (!mOwnsBuffer && mSize > 0) {
165 resize(mSize);
166 }
167 mOwnsBuffer = false;
168 return mBuffer;
169 }
170
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700171 hidl_vec &operator=(hidl_vec &&other) {
Janis Danisevskisd3ddf622016-10-24 11:40:50 +0100172 if (mOwnsBuffer) {
173 delete[] mBuffer;
174 }
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700175 mBuffer = other.mBuffer;
176 mSize = other.mSize;
177 mOwnsBuffer = other.mOwnsBuffer;
178 other.mOwnsBuffer = false;
179 return *this;
180 }
181
Martijn Coenen72110162016-08-19 14:28:25 +0200182 hidl_vec &operator=(const hidl_vec &other) {
183 if (this != &other) {
184 if (mOwnsBuffer) {
185 delete[] mBuffer;
186 }
Yifan Hong602b85a2016-10-24 13:40:01 -0700187 copyFrom(other, other.mSize);
Martijn Coenen72110162016-08-19 14:28:25 +0200188 }
189
190 return *this;
191 }
192
Yifan Hong602b85a2016-10-24 13:40:01 -0700193 // copy from an std::vector.
194 hidl_vec &operator=(const std::vector<T> &other) {
195 if (mOwnsBuffer) {
196 delete[] mBuffer;
197 }
198 copyFrom(other, other.size());
199 return *this;
200 }
201
202 // cast to an std::vector.
203 operator std::vector<T>() const {
204 std::vector<T> v(mSize);
205 for (size_t i = 0; i < mSize; ++i) {
206 v[i] = mBuffer[i];
207 }
208 return v;
209 }
210
Martijn Coenen72110162016-08-19 14:28:25 +0200211 size_t size() const {
212 return mSize;
213 }
214
215 T &operator[](size_t index) {
216 return mBuffer[index];
217 }
218
219 const T &operator[](size_t index) const {
220 return mBuffer[index];
221 }
222
223 void resize(size_t size) {
224 T *newBuffer = new T[size];
225
226 for (size_t i = 0; i < std::min(size, mSize); ++i) {
227 newBuffer[i] = mBuffer[i];
228 }
229
230 if (mOwnsBuffer) {
231 delete[] mBuffer;
232 }
233 mBuffer = newBuffer;
234
235 mSize = size;
236 mOwnsBuffer = true;
237 }
238
239 status_t readEmbeddedFromParcel(
240 const Parcel &parcel,
241 size_t parentHandle,
242 size_t parentOffset,
243 size_t *handle);
244
245 status_t writeEmbeddedToParcel(
246 Parcel *parcel,
247 size_t parentHandle,
248 size_t parentOffset,
249 size_t *handle) const;
250
Yifan Hongb1d8d4c2016-08-23 17:39:06 -0700251 status_t findInParcel(const Parcel &parcel, size_t *handle) const {
252 return parcel.quickFindBuffer(mBuffer, handle);
253 }
254
255
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
Andreas Huber20dce082016-09-22 19:39:13 -0700277////////////////////////////////////////////////////////////////////////////////
278
279namespace details {
280
281 template<size_t SIZE1, size_t... SIZES>
282 struct product {
283 static constexpr size_t value = SIZE1 * product<SIZES...>::value;
284 };
285
286 template<size_t SIZE1>
287 struct product<SIZE1> {
288 static constexpr size_t value = SIZE1;
289 };
290
291 template<typename T, size_t SIZE1, size_t... SIZES>
292 struct accessor {
293 explicit accessor(T *base)
294 : mBase(base) {
295 }
296
297 accessor<T, SIZES...> operator[](size_t index) {
298 return accessor<T, SIZES...>(
299 &mBase[index * product<SIZES...>::value]);
300 }
301
302 private:
303 T *mBase;
304 };
305
306 template<typename T, size_t SIZE1>
307 struct accessor<T, SIZE1> {
308 explicit accessor(T *base)
309 : mBase(base) {
310 }
311
312 T &operator[](size_t index) {
313 return mBase[index];
314 }
315
316 private:
317 T *mBase;
318 };
319
320 template<typename T, size_t SIZE1, size_t... SIZES>
321 struct const_accessor {
322 explicit const_accessor(const T *base)
323 : mBase(base) {
324 }
325
326 const_accessor<T, SIZES...> operator[](size_t index) {
327 return const_accessor<T, SIZES...>(
328 &mBase[index * product<SIZES...>::value]);
329 }
330
331 private:
332 const T *mBase;
333 };
334
335 template<typename T, size_t SIZE1>
336 struct const_accessor<T, SIZE1> {
337 explicit const_accessor(const T *base)
338 : mBase(base) {
339 }
340
341 const T &operator[](size_t index) const {
342 return mBase[index];
343 }
344
345 private:
346 const T *mBase;
347 };
348
349} // namespace details
350
351////////////////////////////////////////////////////////////////////////////////
352
353template<typename T, size_t SIZE1, size_t... SIZES>
354struct hidl_array {
355 hidl_array() = default;
356
357 T *data() { return mBuffer; }
358 const T *data() const { return mBuffer; }
359
360 details::accessor<T, SIZES...> operator[](size_t index) {
361 return details::accessor<T, SIZES...>(
362 &mBuffer[index * details::product<SIZES...>::value]);
363 }
364
365 details::const_accessor<T, SIZES...> operator[](size_t index) const {
366 return details::const_accessor<T, SIZES...>(
367 &mBuffer[index * details::product<SIZES...>::value]);
368 }
369
Andreas Huber00a985c2016-09-28 14:24:53 -0700370 using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;
371
372 static constexpr size_tuple_type size() {
373 return std::make_tuple(SIZE1, SIZES...);
374 }
375
Andreas Huber20dce082016-09-22 19:39:13 -0700376private:
377 T mBuffer[details::product<SIZE1, SIZES...>::value];
378};
379
380template<typename T, size_t SIZE1>
381struct hidl_array<T, SIZE1> {
382 hidl_array() = default;
383
384 T *data() { return mBuffer; }
385 const T *data() const { return mBuffer; }
386
387 T &operator[](size_t index) {
388 return mBuffer[index];
389 }
390
391 const T &operator[](size_t index) const {
392 return mBuffer[index];
393 }
394
Andreas Huber00a985c2016-09-28 14:24:53 -0700395 static constexpr size_t size() { return SIZE1; }
396
Andreas Huber20dce082016-09-22 19:39:13 -0700397private:
398 T mBuffer[SIZE1];
399};
400
401////////////////////////////////////////////////////////////////////////////////
402
Martijn Coenen72110162016-08-19 14:28:25 +0200403template<typename T>
404status_t hidl_vec<T>::readEmbeddedFromParcel(
405 const Parcel &parcel,
406 size_t parentHandle,
407 size_t parentOffset,
408 size_t *handle) {
409 const void *ptr = parcel.readEmbeddedBuffer(
410 handle,
411 parentHandle,
412 parentOffset + offsetof(hidl_vec<T>, mBuffer));
413
414 return ptr != NULL ? OK : UNKNOWN_ERROR;
415}
416
417template<typename T>
418status_t hidl_vec<T>::writeEmbeddedToParcel(
419 Parcel *parcel,
420 size_t parentHandle,
421 size_t parentOffset,
422 size_t *handle) const {
423 return parcel->writeEmbeddedBuffer(
424 mBuffer,
425 sizeof(T) * mSize,
426 handle,
427 parentHandle,
428 parentOffset + offsetof(hidl_vec<T>, mBuffer));
429}
430
Yifan Hongb1d8d4c2016-08-23 17:39:06 -0700431///////////////////////////// pointers for HIDL
432
433template <typename T>
434static status_t readEmbeddedReferenceFromParcel(
435 T const* * /* bufptr */,
436 const Parcel & parcel,
437 size_t parentHandle,
438 size_t parentOffset,
439 size_t *handle,
440 bool *shouldResolveRefInBuffer
441 ) {
442 // *bufptr is ignored because, if I am embedded in some
443 // other buffer, the kernel should have fixed me up already.
444 bool isPreviouslyWritten;
445 status_t result = parcel.readEmbeddedReference(
446 nullptr, // ignored, not written to bufptr.
447 handle,
448 parentHandle,
449 parentOffset,
450 &isPreviouslyWritten);
451 // tell caller to run T::readEmbeddedToParcel and
452 // T::readEmbeddedReferenceToParcel if necessary.
453 // It is not called here because we don't know if these two are valid methods.
454 *shouldResolveRefInBuffer = !isPreviouslyWritten;
455 return result;
456}
457
458template <typename T>
459static status_t writeEmbeddedReferenceToParcel(
460 T const* buf,
461 Parcel *parcel, size_t parentHandle, size_t parentOffset,
462 size_t *handle,
463 bool *shouldResolveRefInBuffer
464 ) {
465
466 if(buf == nullptr) {
467 *shouldResolveRefInBuffer = false;
468 return parcel->writeEmbeddedNullReference(handle, parentHandle, parentOffset);
469 }
470
471 // find whether the buffer exists
472 size_t childHandle, childOffset;
473 status_t result;
474 bool found;
475
476 result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);
477
478 // tell caller to run T::writeEmbeddedToParcel and
479 // T::writeEmbeddedReferenceToParcel if necessary.
480 // It is not called here because we don't know if these two are valid methods.
481 *shouldResolveRefInBuffer = !found;
482
483 if(result != OK) {
484 return result; // bad pointers and length given
485 }
486 if(!found) { // did not find it.
487 return parcel->writeEmbeddedBuffer(buf, sizeof(T), handle,
488 parentHandle, parentOffset);
489 }
490 // found the buffer. easy case.
491 return parcel->writeEmbeddedReference(
492 handle,
493 childHandle,
494 childOffset,
495 parentHandle,
496 parentOffset);
497}
498
499template <typename T>
500static status_t readReferenceFromParcel(
501 T const* *bufptr,
502 const Parcel & parcel,
503 size_t *handle,
504 bool *shouldResolveRefInBuffer
505 ) {
506 bool isPreviouslyWritten;
507 status_t result = parcel.readReference(reinterpret_cast<void const* *>(bufptr),
508 handle, &isPreviouslyWritten);
509 // tell caller to run T::readEmbeddedToParcel and
510 // T::readEmbeddedReferenceToParcel if necessary.
511 // It is not called here because we don't know if these two are valid methods.
512 *shouldResolveRefInBuffer = !isPreviouslyWritten;
513 return result;
514}
515
516template <typename T>
517static status_t writeReferenceToParcel(
518 T const *buf,
519 Parcel * parcel,
520 size_t *handle,
521 bool *shouldResolveRefInBuffer
522 ) {
523
524 if(buf == nullptr) {
525 *shouldResolveRefInBuffer = false;
526 return parcel->writeNullReference(handle);
527 }
528
529 // find whether the buffer exists
530 size_t childHandle, childOffset;
531 status_t result;
532 bool found;
533
534 result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);
535
536 // tell caller to run T::writeEmbeddedToParcel and
537 // T::writeEmbeddedReferenceToParcel if necessary.
538 // It is not called here because we don't know if these two are valid methods.
539 *shouldResolveRefInBuffer = !found;
540
541 if(result != OK) {
542 return result; // bad pointers and length given
543 }
544 if(!found) { // did not find it.
545 return parcel->writeBuffer(buf, sizeof(T), handle);
546 }
547 // found the buffer. easy case.
548 return parcel->writeReference(handle,
549 childHandle, childOffset);
550}
551
Martijn Coenen72110162016-08-19 14:28:25 +0200552// ----------------------------------------------------------------------
553// Version functions
554struct hidl_version {
555public:
Chia-I Wu666b76b2016-10-06 14:15:59 +0800556 constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {}
Martijn Coenen72110162016-08-19 14:28:25 +0200557
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700558 bool operator==(const hidl_version& other) const {
Martijn Coenen72110162016-08-19 14:28:25 +0200559 return (mMajor == other.get_major() && mMinor == other.get_minor());
560 }
Martijn Coenenc28f1152016-08-22 14:06:56 +0200561
Martijn Coenen097a7672016-09-08 16:56:41 +0200562 constexpr uint16_t get_major() const { return mMajor; }
563 constexpr uint16_t get_minor() const { return mMinor; }
Martijn Coenen72110162016-08-19 14:28:25 +0200564
565 android::status_t writeToParcel(android::hardware::Parcel& parcel) const {
Chia-I Wu666b76b2016-10-06 14:15:59 +0800566 return parcel.writeUint32(static_cast<uint32_t>(mMajor) << 16 | mMinor);
Martijn Coenen72110162016-08-19 14:28:25 +0200567 }
568
569 static hidl_version* readFromParcel(const android::hardware::Parcel& parcel) {
570 uint32_t version;
571 android::status_t status = parcel.readUint32(&version);
572 if (status != OK) {
573 return nullptr;
574 } else {
575 return new hidl_version(version >> 16, version & 0xFFFF);
576 }
577 }
578
579private:
580 uint16_t mMajor;
581 uint16_t mMinor;
582};
583
584inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
585 return hidl_version(major,minor);
586}
587
Yifan Honga3c31842016-10-21 10:33:14 -0700588struct IHidlInterfaceBase : virtual public RefBase {
589 virtual bool isRemote() const = 0;
590 // HIDL reserved methods follow.
591 virtual ::android::hardware::Return<void> interfaceChain(
592 std::function<void(const hidl_vec<hidl_string>&)> _hidl_cb) = 0;
593 // descriptor for HIDL reserved methods.
594 static const ::android::String16 descriptor;
595};
596
Yifan Hong1e265bb2016-11-08 12:33:44 -0800597extern std::map<std::string, std::function<sp<IBinder>(void*)>> gBnConstructorMap;
598
599// Construct a smallest possible binder from the given interface.
600// If it is remote, then its remote() will be retrieved.
601// Otherwise, the smallest possible BnChild is found where IChild is a subclass of IType
602// and iface is of class IChild. BnChild will be used to wrapped the given iface.
603// Return nullptr if iface is null or any failure.
604template <typename IType, typename IHwType>
605sp<IBinder> toBinder(sp<IType> iface) {
606 IType *ifacePtr = iface.get();
607 if (ifacePtr == nullptr) {
608 return nullptr;
609 }
610 if (ifacePtr->isRemote()) {
611 return ::android::hardware::IInterface::asBinder(static_cast<IHwType *>(ifacePtr));
612 } else {
613 std::string myDescriptor{};
614 ifacePtr->interfaceChain([&](const hidl_vec<hidl_string> &types) {
615 if (types.size() > 0) {
616 myDescriptor = types[0].c_str();
617 }
618 });
619 if (myDescriptor.empty()) {
620 // interfaceChain fails || types.size() == 0
621 return nullptr;
622 }
623 auto iter = gBnConstructorMap.find(myDescriptor);
624 if (iter == gBnConstructorMap.end()) {
625 return nullptr;
626 }
627 return sp<IBinder>((iter->second)(reinterpret_cast<void *>(ifacePtr)));
628 }
629}
630
631// cast the interface IParent to IChild.
632// Return nullptr if parent is null or any failure.
633template<typename IChild, typename IParent, typename BpChild, typename IHwParent>
Yifan Hong190e4292016-10-21 10:34:25 -0700634sp<IChild> castInterface(sp<IParent> parent, const char *childIndicator) {
635 if (parent.get() == nullptr) {
636 // casts always succeed with nullptrs.
637 return nullptr;
638 }
639 bool canCast = false;
640 parent->interfaceChain([&](const hidl_vec<hidl_string> &allowedCastTypes) {
641 for (size_t i = 0; i < allowedCastTypes.size(); i++) {
642 if (allowedCastTypes[i] == childIndicator) {
643 canCast = true;
644 break;
645 }
646 }
647 });
648
649 if (!canCast) {
650 return sp<IChild>(nullptr); // cast failed.
651 }
652 if (parent->isRemote()) {
653 // binderized mode. Got BpChild. grab the remote and wrap it.
Yifan Hong1e265bb2016-11-08 12:33:44 -0800654 return sp<IChild>(new BpChild(toBinder<IParent, IHwParent>(parent)));
Yifan Hong190e4292016-10-21 10:34:25 -0700655 }
656 // Passthrough mode. Got BnChild and BsChild.
657 return sp<IChild>(static_cast<IChild *>(parent.get()));
658}
659
Steven Morelandbdf26662016-09-02 11:03:15 -0700660#if defined(__LP64__)
661#define HAL_LIBRARY_PATH_SYSTEM "/system/lib64/hw/"
662#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib64/hw/"
663#define HAL_LIBRARY_PATH_ODM "/odm/lib64/hw/"
664#else
665#define HAL_LIBRARY_PATH_SYSTEM "/system/lib/hw/"
666#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib/hw/"
667#define HAL_LIBRARY_PATH_ODM "/odm/lib/hw/"
668#endif
669
Martijn Coenenc28f1152016-08-22 14:06:56 +0200670#define DECLARE_REGISTER_AND_GET_SERVICE(INTERFACE) \
671 static ::android::sp<I##INTERFACE> getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700672 const std::string &serviceName, bool getStub=false); \
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700673 ::android::status_t registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200674 const std::string &serviceName); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200675
Steven Morelandf0cc0972016-11-02 17:51:46 -0700676#define IMPLEMENT_REGISTER_AND_GET_SERVICE(INTERFACE, PACKAGE) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200677 ::android::sp<I##INTERFACE> I##INTERFACE::getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700678 const std::string &serviceName, bool getStub) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200679 { \
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700680 using ::android::sp; \
681 using ::android::hardware::defaultServiceManager; \
682 using ::android::hardware::IBinder; \
683 using ::android::hidl::manager::V1_0::IServiceManager; \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200684 sp<I##INTERFACE> iface; \
Martijn Coenen270cb502016-10-25 00:19:56 +0200685 const sp<IServiceManager> sm = defaultServiceManager(); \
686 if (sm != nullptr && !getStub) { \
Steven Morelandb8573e12016-11-07 12:40:05 -0800687 sp<IBinder> binderIface; \
Steven Morelandf0cc0972016-11-02 17:51:46 -0700688 ::android::hardware::Return<void> ret = \
689 sm->get(PACKAGE "::I" #INTERFACE, serviceName.c_str(), \
690 [&binderIface](sp<IBinder> iface) { \
691 binderIface = iface; \
692 }); \
693 if (ret.getStatus().isOk()) { \
694 iface = IHw##INTERFACE::asInterface(binderIface); \
695 if (iface != nullptr) { \
696 return iface; \
697 } \
Steven Morelandb8573e12016-11-07 12:40:05 -0800698 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700699 } \
700 int dlMode = RTLD_LAZY; \
Steven Morelandf0cc0972016-11-02 17:51:46 -0700701 void *handle = dlopen(HAL_LIBRARY_PATH_ODM PACKAGE "-impl.so", dlMode); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700702 if (handle == nullptr) { \
Steven Morelandf0cc0972016-11-02 17:51:46 -0700703 handle = dlopen(HAL_LIBRARY_PATH_VENDOR PACKAGE "-impl.so", dlMode); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700704 } \
705 if (handle == nullptr) { \
Steven Morelandf0cc0972016-11-02 17:51:46 -0700706 handle = dlopen(HAL_LIBRARY_PATH_SYSTEM PACKAGE "-impl.so", dlMode); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700707 } \
708 if (handle == nullptr) { \
709 return iface; \
710 } \
711 I##INTERFACE* (*generator)(const char* name); \
712 *(void **)(&generator) = dlsym(handle, "HIDL_FETCH_I"#INTERFACE); \
713 if (generator) { \
Martijn Coenenf7a651d2016-09-08 13:38:12 +0200714 iface = (*generator)(serviceName.c_str()); \
Steven Moreland7391bc32016-09-14 10:31:48 -0700715 if (iface != nullptr) { \
716 iface = new Bs##INTERFACE(iface); \
717 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700718 } \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200719 return iface; \
720 } \
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700721 ::android::status_t I##INTERFACE::registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200722 const std::string &serviceName) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200723 { \
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700724 using ::android::sp; \
725 using ::android::hardware::defaultServiceManager; \
Steven Morelandf0cc0972016-11-02 17:51:46 -0700726 using ::android::hardware::hidl_string; \
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700727 using ::android::hidl::manager::V1_0::IServiceManager; \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200728 sp<Bn##INTERFACE> binderIface = new Bn##INTERFACE(this); \
729 const sp<IServiceManager> sm = defaultServiceManager(); \
Steven Morelandf0cc0972016-11-02 17:51:46 -0700730 bool success = false; \
731 ::android::hardware::Return<void> ret = \
732 this->interfaceChain( \
733 [&success, &sm, &serviceName, &binderIface](const auto &chain) { \
734 success = sm->add(chain, serviceName.c_str(), binderIface); \
735 }); \
736 success = success && ret.getStatus().isOk(); \
737 return success ? ::android::OK : ::android::UNKNOWN_ERROR; \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200738 }
739
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700740// ----------------------------------------------------------------------
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700741// Class that provides Hidl instrumentation utilities.
742struct HidlInstrumentor {
743 // Event that triggers the instrumentation. e.g. enter of an API call on
744 // the server/client side, exit of an API call on the server/client side
745 // etc.
746 enum InstrumentationEvent {
747 SERVER_API_ENTRY = 0,
748 SERVER_API_EXIT,
749 CLIENT_API_ENTRY,
750 CLIENT_API_EXIT,
751 SYNC_CALLBACK_ENTRY,
752 SYNC_CALLBACK_EXIT,
753 ASYNC_CALLBACK_ENTRY,
754 ASYNC_CALLBACK_EXIT,
Steven Morelandcefbd6e2016-11-01 10:14:30 -0700755 PASSTHROUGH_ENTRY,
756 PASSTHROUGH_EXIT,
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700757 };
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700758
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700759 // Signature of the instrumentation callback function.
760 using InstrumentationCallback = std::function<void(
761 const InstrumentationEvent event,
762 const char *package,
763 const char *version,
764 const char *interface,
765 const char *method,
766 std::vector<void *> *args)>;
767
768 explicit HidlInstrumentor(const std::string &prefix);
769 virtual ~HidlInstrumentor();
770
771 protected:
772 // Function that lookup and dynamically loads the hidl instrumentation
773 // libraries and registers the instrumentation callback functions.
774 //
775 // The instrumentation libraries should be stored under any of the following
776 // directories: HAL_LIBRARY_PATH_SYSTEM, HAL_LIBRARY_PATH_VENDOR and
777 // HAL_LIBRARY_PATH_ODM. The name of instrumentation libraries should
778 // follow pattern: ^profilerPrefix(.*).profiler.so$
779 //
780 // Each instrumentation library is expected to implement the instrumentation
781 // function called HIDL_INSTRUMENTATION_FUNCTION.
782 //
783 // A no-op for user build.
784 void registerInstrumentationCallbacks(
785 const std::string &profilerPrefix,
786 std::vector<InstrumentationCallback> *instrumentationCallbacks);
787
788 // Utility function to determine whether a give file is a instrumentation
789 // library (i.e. the file name follow the expected pattern).
790 bool isInstrumentationLib(
791 const std::string &profilerPrefix,
792 const dirent *file);
793 // A list of registered instrumentation callbacks.
794 std::vector<InstrumentationCallback> mInstrumentationCallbacks;
795 // Flag whether to enable instrumentation.
796 bool mEnableInstrumentation;
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700797};
798
Martijn Coenen72110162016-08-19 14:28:25 +0200799} // namespace hardware
800} // namespace android
801
Martijn Coenenc28f1152016-08-22 14:06:56 +0200802
Martijn Coenen72110162016-08-19 14:28:25 +0200803#endif // ANDROID_HIDL_SUPPORT_H
804