blob: c604f56c468b07dfe2a299c8baa9fa978c2a1d3a [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>
Scott Randolphbb840f72016-11-21 14:39:26 -080023#include <iterator>
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -070024#include <cutils/properties.h>
Yifan Hong1e265bb2016-11-08 12:33:44 -080025#include <functional>
Yifan Honga3c31842016-10-21 10:33:14 -070026#include <hidl/Status.h>
Yifan Hong1e265bb2016-11-08 12:33:44 -080027#include <map>
Andreas Huber00a985c2016-09-28 14:24:53 -070028#include <tuple>
Iliyan Malchev692070a2016-09-12 16:30:44 -070029#include <utils/Errors.h>
30#include <utils/RefBase.h>
31#include <utils/StrongPointer.h>
Yifan Hong7f97f442016-11-14 18:31:05 -080032#include <vector>
Martijn Coenen72110162016-08-19 14:28:25 +020033
34namespace android {
35namespace hardware {
36
Martijn Coenen4ca39a02016-11-11 15:58:51 +010037namespace details {
38
39// hidl_log_base is a base class that templatized
40// classes implemented in a header can inherit from,
41// to avoid creating dependencies on liblog.
42struct hidl_log_base {
43 void logAlwaysFatal(const char *message);
44};
45
46// HIDL client/server code should *NOT* use this class.
47//
48// hidl_pointer wraps a pointer without taking ownership,
49// and stores it in a union with a uint64_t. This ensures
50// that we always have enough space to store a pointer,
51// regardless of whether we're running in a 32-bit or 64-bit
52// process.
53template<typename T>
54struct hidl_pointer {
55 hidl_pointer()
56 : mPointer(nullptr) {
57 }
58 hidl_pointer(T* ptr)
59 : mPointer(ptr) {
60 }
61 hidl_pointer(const hidl_pointer<T>& other) {
62 mPointer = other.mPointer;
63 }
64 hidl_pointer(hidl_pointer<T>&& other) {
65 *this = std::move(other);
66 }
67
68 hidl_pointer &operator=(const hidl_pointer<T>& other) {
69 mPointer = other.mPointer;
70 return *this;
71 }
72 hidl_pointer &operator=(hidl_pointer<T>&& other) {
73 mPointer = other.mPointer;
74 other.mPointer = nullptr;
75 return *this;
76 }
77 hidl_pointer &operator=(T* ptr) {
78 mPointer = ptr;
79 return *this;
80 }
81
82 operator T*() const {
83 return mPointer;
84 }
85 explicit operator void*() const { // requires explicit cast to avoid ambiguity
86 return mPointer;
87 }
88 T& operator*() const {
89 return *mPointer;
90 }
91 T* operator->() const {
92 return mPointer;
93 }
94 T &operator[](size_t index) {
95 return mPointer[index];
96 }
97 const T &operator[](size_t index) const {
98 return mPointer[index];
99 }
100private:
101 union {
102 T* mPointer;
103 uint64_t _pad;
104 };
105};
106} // namespace details
107
Martijn Coenen72110162016-08-19 14:28:25 +0200108struct hidl_string {
109 hidl_string();
110 ~hidl_string();
111
Yifan Hong602b85a2016-10-24 13:40:01 -0700112 // copy constructor.
Martijn Coenen72110162016-08-19 14:28:25 +0200113 hidl_string(const hidl_string &);
Yifan Hong602b85a2016-10-24 13:40:01 -0700114 // copy from a C-style string.
Steven Morelande03c0872016-10-24 10:43:50 -0700115 hidl_string(const char *);
Yifan Hong602b85a2016-10-24 13:40:01 -0700116 // copy from an std::string.
117 hidl_string(const std::string &);
118
119 // move constructor.
120 hidl_string(hidl_string &&);
Martijn Coenen72110162016-08-19 14:28:25 +0200121
122 const char *c_str() const;
123 size_t size() const;
124 bool empty() const;
125
Yifan Hong602b85a2016-10-24 13:40:01 -0700126 // copy assignment operator.
Steven Morelande03c0872016-10-24 10:43:50 -0700127 hidl_string &operator=(const hidl_string &);
Yifan Hong602b85a2016-10-24 13:40:01 -0700128 // copy from a C-style string.
Martijn Coenen72110162016-08-19 14:28:25 +0200129 hidl_string &operator=(const char *s);
Yifan Hong602b85a2016-10-24 13:40:01 -0700130 // copy from an std::string.
131 hidl_string &operator=(const std::string &);
132 // move assignment operator.
133 hidl_string &operator=(hidl_string &&other);
134 // cast to std::string.
135 operator std::string() const;
136 // cast to C-style string. Caller is responsible
137 // to maintain this hidl_string alive.
138 operator const char *() const;
Steven Morelande03c0872016-10-24 10:43:50 -0700139
Martijn Coenen72110162016-08-19 14:28:25 +0200140 void clear();
141
142 // Reference an external char array. Ownership is _not_ transferred.
143 // Caller is responsible for ensuring that underlying memory is valid
144 // for the lifetime of this hidl_string.
145 void setToExternal(const char *data, size_t size);
146
Andreas Huberebfeb362016-08-25 13:39:05 -0700147 // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
148 static const size_t kOffsetOfBuffer;
149
Martijn Coenen72110162016-08-19 14:28:25 +0200150private:
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100151 details::hidl_pointer<const char> mBuffer;
152 uint32_t mSize; // NOT including the terminating '\0'.
Yifan Hong602b85a2016-10-24 13:40:01 -0700153 bool mOwnsBuffer; // if true then mBuffer is a mutable char *
Martijn Coenen72110162016-08-19 14:28:25 +0200154
Yifan Hong602b85a2016-10-24 13:40:01 -0700155 // copy from data with size. Assume that my memory is freed
156 // (through clear(), for example)
157 void copyFrom(const char *data, size_t size);
158 // move from another hidl_string
159 void moveFrom(hidl_string &&);
Martijn Coenen72110162016-08-19 14:28:25 +0200160};
161
Scott Randolphbb840f72016-11-21 14:39:26 -0800162inline bool operator==(const hidl_string &hs1, const hidl_string &hs2) {
163 return strcmp(hs1.c_str(), hs2.c_str()) == 0;
164}
165
166inline bool operator!=(const hidl_string &hs1, const hidl_string &hs2) {
167 return !(hs1 == hs2);
168}
169
Yifan Hong5708fb42016-10-26 17:50:29 -0700170inline bool operator==(const hidl_string &hs, const char *s) {
171 return strcmp(hs.c_str(), s) == 0;
172}
173
174inline bool operator!=(const hidl_string &hs, const char *s) {
175 return !(hs == s);
176}
177
178inline bool operator==(const char *s, const hidl_string &hs) {
179 return strcmp(hs.c_str(), s) == 0;
180}
181
182inline bool operator!=(const char *s, const hidl_string &hs) {
183 return !(s == hs);
184}
185
Andreas Huber20dce082016-09-22 19:39:13 -0700186////////////////////////////////////////////////////////////////////////////////
187
Martijn Coenen72110162016-08-19 14:28:25 +0200188template<typename T>
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100189struct hidl_vec : private details::hidl_log_base {
Martijn Coenen72110162016-08-19 14:28:25 +0200190 hidl_vec()
191 : mBuffer(NULL),
192 mSize(0),
193 mOwnsBuffer(true) {
194 }
195
Yifan Hong602b85a2016-10-24 13:40:01 -0700196 hidl_vec(const hidl_vec<T> &other) : hidl_vec() {
Martijn Coenen72110162016-08-19 14:28:25 +0200197 *this = other;
198 }
199
Janis Danisevskisd3ddf622016-10-24 11:40:50 +0100200 hidl_vec(hidl_vec<T> &&other)
Steven Moreland9fbfe472016-11-14 16:49:17 -0800201 : mOwnsBuffer(false) {
Janis Danisevskisd3ddf622016-10-24 11:40:50 +0100202 *this = std::move(other);
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700203 }
204
Steven Morelandb69926a2016-11-15 10:02:57 -0800205 hidl_vec(const std::initializer_list<T> list)
Steven Moreland9fbfe472016-11-14 16:49:17 -0800206 : mSize(list.size()),
207 mOwnsBuffer(true) {
208 mBuffer = new T[mSize];
209
Steven Morelandb69926a2016-11-15 10:02:57 -0800210 size_t idx = 0;
Steven Moreland9fbfe472016-11-14 16:49:17 -0800211 for (auto it = list.begin(); it != list.end(); ++it) {
212 mBuffer[idx++] = *it;
213 }
214 }
215
Yifan Hong602b85a2016-10-24 13:40:01 -0700216 hidl_vec(const std::vector<T> &other) : hidl_vec() {
217 *this = other;
218 }
219
Martijn Coenen72110162016-08-19 14:28:25 +0200220 ~hidl_vec() {
221 if (mOwnsBuffer) {
222 delete[] mBuffer;
223 }
224 mBuffer = NULL;
225 }
226
Alexey Polyudove2299012016-10-19 09:52:00 -0700227 // Reference an existing array, optionally taking ownership. It is the
Martijn Coenen72110162016-08-19 14:28:25 +0200228 // caller's responsibility to ensure that the underlying memory stays
229 // valid for the lifetime of this hidl_vec.
Alexey Polyudove2299012016-10-19 09:52:00 -0700230 void setToExternal(T *data, size_t size, bool shouldOwn = false) {
Martijn Coenen72110162016-08-19 14:28:25 +0200231 if (mOwnsBuffer) {
232 delete [] mBuffer;
233 }
234 mBuffer = data;
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100235 if (size > UINT32_MAX) {
236 logAlwaysFatal("external vector size exceeds 2^32 elements.");
237 }
238 mSize = static_cast<uint32_t>(size);
Alexey Polyudove2299012016-10-19 09:52:00 -0700239 mOwnsBuffer = shouldOwn;
Martijn Coenen72110162016-08-19 14:28:25 +0200240 }
241
Alexey Polyudov6f0c9a12016-10-18 09:37:35 -0700242 T *data() {
243 return mBuffer;
244 }
245
246 const T *data() const {
247 return mBuffer;
248 }
249
Alexey Polyudovc98a99c2016-10-18 09:43:56 -0700250 T *releaseData() {
251 if (!mOwnsBuffer && mSize > 0) {
252 resize(mSize);
253 }
254 mOwnsBuffer = false;
255 return mBuffer;
256 }
257
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700258 hidl_vec &operator=(hidl_vec &&other) {
Janis Danisevskisd3ddf622016-10-24 11:40:50 +0100259 if (mOwnsBuffer) {
260 delete[] mBuffer;
261 }
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700262 mBuffer = other.mBuffer;
263 mSize = other.mSize;
264 mOwnsBuffer = other.mOwnsBuffer;
265 other.mOwnsBuffer = false;
266 return *this;
267 }
268
Martijn Coenen72110162016-08-19 14:28:25 +0200269 hidl_vec &operator=(const hidl_vec &other) {
270 if (this != &other) {
271 if (mOwnsBuffer) {
272 delete[] mBuffer;
273 }
Yifan Hong602b85a2016-10-24 13:40:01 -0700274 copyFrom(other, other.mSize);
Martijn Coenen72110162016-08-19 14:28:25 +0200275 }
276
277 return *this;
278 }
279
Yifan Hong602b85a2016-10-24 13:40:01 -0700280 // copy from an std::vector.
281 hidl_vec &operator=(const std::vector<T> &other) {
282 if (mOwnsBuffer) {
283 delete[] mBuffer;
284 }
285 copyFrom(other, other.size());
286 return *this;
287 }
288
289 // cast to an std::vector.
290 operator std::vector<T>() const {
291 std::vector<T> v(mSize);
292 for (size_t i = 0; i < mSize; ++i) {
293 v[i] = mBuffer[i];
294 }
295 return v;
296 }
297
Martijn Coenen72110162016-08-19 14:28:25 +0200298 size_t size() const {
299 return mSize;
300 }
301
302 T &operator[](size_t index) {
303 return mBuffer[index];
304 }
305
306 const T &operator[](size_t index) const {
307 return mBuffer[index];
308 }
309
310 void resize(size_t size) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100311 if (size > UINT32_MAX) {
312 logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
313 }
Martijn Coenen72110162016-08-19 14:28:25 +0200314 T *newBuffer = new T[size];
315
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100316 for (size_t i = 0; i < std::min(static_cast<uint32_t>(size), mSize); ++i) {
Martijn Coenen72110162016-08-19 14:28:25 +0200317 newBuffer[i] = mBuffer[i];
318 }
319
320 if (mOwnsBuffer) {
321 delete[] mBuffer;
322 }
323 mBuffer = newBuffer;
324
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100325 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200326 mOwnsBuffer = true;
327 }
328
Yifan Hong089ae132016-11-11 11:32:52 -0800329 // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
330 static const size_t kOffsetOfBuffer;
Scott Randolphbb840f72016-11-21 14:39:26 -0800331
332 // Define std interator interface for walking the array contents
333 // TODO: it might be nice to implement a full featured random access iterator...
334 class iterator : public std::iterator<std::bidirectional_iterator_tag, T>
335 {
336 public:
337 iterator(T* ptr) : mPtr(ptr) { }
338 iterator operator++() { iterator i = *this; mPtr++; return i; }
339 iterator operator++(int) { mPtr++; return *this; }
340 iterator operator--() { iterator i = *this; mPtr--; return i; }
341 iterator operator--(int) { mPtr--; return *this; }
342 T& operator*() { return *mPtr; }
343 T* operator->() { return mPtr; }
344 bool operator==(const iterator& rhs) const { return mPtr == rhs.mPtr; }
345 bool operator!=(const iterator& rhs) const { return mPtr != rhs.mPtr; }
346 private:
347 T* mPtr;
348 };
349 iterator begin() { return data(); }
350 iterator end() { return data()+mSize; }
351
Martijn Coenen72110162016-08-19 14:28:25 +0200352private:
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100353 details::hidl_pointer<T> mBuffer;
354 uint32_t mSize;
Martijn Coenen72110162016-08-19 14:28:25 +0200355 bool mOwnsBuffer;
Yifan Hong602b85a2016-10-24 13:40:01 -0700356
357 // copy from an array-like object, assuming my resources are freed.
358 template <typename Array>
359 void copyFrom(const Array &data, size_t size) {
360 mSize = size;
361 mOwnsBuffer = true;
362 if (mSize > 0) {
363 mBuffer = new T[size];
364 for (size_t i = 0; i < size; ++i) {
365 mBuffer[i] = data[i];
366 }
367 } else {
368 mBuffer = NULL;
369 }
370 }
Martijn Coenen72110162016-08-19 14:28:25 +0200371};
372
Yifan Hong089ae132016-11-11 11:32:52 -0800373template <typename T>
374const size_t hidl_vec<T>::kOffsetOfBuffer = offsetof(hidl_vec<T>, mBuffer);
375
Andreas Huber20dce082016-09-22 19:39:13 -0700376////////////////////////////////////////////////////////////////////////////////
377
378namespace details {
379
380 template<size_t SIZE1, size_t... SIZES>
381 struct product {
382 static constexpr size_t value = SIZE1 * product<SIZES...>::value;
383 };
384
385 template<size_t SIZE1>
386 struct product<SIZE1> {
387 static constexpr size_t value = SIZE1;
388 };
389
390 template<typename T, size_t SIZE1, size_t... SIZES>
391 struct accessor {
392 explicit accessor(T *base)
393 : mBase(base) {
394 }
395
396 accessor<T, SIZES...> operator[](size_t index) {
397 return accessor<T, SIZES...>(
398 &mBase[index * product<SIZES...>::value]);
399 }
400
401 private:
402 T *mBase;
403 };
404
405 template<typename T, size_t SIZE1>
406 struct accessor<T, SIZE1> {
407 explicit accessor(T *base)
408 : mBase(base) {
409 }
410
411 T &operator[](size_t index) {
412 return mBase[index];
413 }
414
415 private:
416 T *mBase;
417 };
418
419 template<typename T, size_t SIZE1, size_t... SIZES>
420 struct const_accessor {
421 explicit const_accessor(const T *base)
422 : mBase(base) {
423 }
424
425 const_accessor<T, SIZES...> operator[](size_t index) {
426 return const_accessor<T, SIZES...>(
427 &mBase[index * product<SIZES...>::value]);
428 }
429
430 private:
431 const T *mBase;
432 };
433
434 template<typename T, size_t SIZE1>
435 struct const_accessor<T, SIZE1> {
436 explicit const_accessor(const T *base)
437 : mBase(base) {
438 }
439
440 const T &operator[](size_t index) const {
441 return mBase[index];
442 }
443
444 private:
445 const T *mBase;
446 };
447
448} // namespace details
449
450////////////////////////////////////////////////////////////////////////////////
451
452template<typename T, size_t SIZE1, size_t... SIZES>
453struct hidl_array {
454 hidl_array() = default;
455
456 T *data() { return mBuffer; }
457 const T *data() const { return mBuffer; }
458
459 details::accessor<T, SIZES...> operator[](size_t index) {
460 return details::accessor<T, SIZES...>(
461 &mBuffer[index * details::product<SIZES...>::value]);
462 }
463
464 details::const_accessor<T, SIZES...> operator[](size_t index) const {
465 return details::const_accessor<T, SIZES...>(
466 &mBuffer[index * details::product<SIZES...>::value]);
467 }
468
Andreas Huber00a985c2016-09-28 14:24:53 -0700469 using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;
470
471 static constexpr size_tuple_type size() {
472 return std::make_tuple(SIZE1, SIZES...);
473 }
474
Andreas Huber20dce082016-09-22 19:39:13 -0700475private:
476 T mBuffer[details::product<SIZE1, SIZES...>::value];
477};
478
479template<typename T, size_t SIZE1>
480struct hidl_array<T, SIZE1> {
481 hidl_array() = default;
Sasha Levitskiy3da68482016-11-17 16:48:43 -0800482 hidl_array(const T *source) {
483 memcpy(mBuffer, source, SIZE1 * sizeof(T));
484 }
Andreas Huber20dce082016-09-22 19:39:13 -0700485
486 T *data() { return mBuffer; }
487 const T *data() const { return mBuffer; }
488
489 T &operator[](size_t index) {
490 return mBuffer[index];
491 }
492
493 const T &operator[](size_t index) const {
494 return mBuffer[index];
495 }
496
Andreas Huber00a985c2016-09-28 14:24:53 -0700497 static constexpr size_t size() { return SIZE1; }
498
Andreas Huber20dce082016-09-22 19:39:13 -0700499private:
500 T mBuffer[SIZE1];
501};
502
Martijn Coenen72110162016-08-19 14:28:25 +0200503// ----------------------------------------------------------------------
504// Version functions
505struct hidl_version {
506public:
Chia-I Wu666b76b2016-10-06 14:15:59 +0800507 constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {}
Martijn Coenen72110162016-08-19 14:28:25 +0200508
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700509 bool operator==(const hidl_version& other) const {
Martijn Coenen72110162016-08-19 14:28:25 +0200510 return (mMajor == other.get_major() && mMinor == other.get_minor());
511 }
Martijn Coenenc28f1152016-08-22 14:06:56 +0200512
Martijn Coenen097a7672016-09-08 16:56:41 +0200513 constexpr uint16_t get_major() const { return mMajor; }
514 constexpr uint16_t get_minor() const { return mMinor; }
Martijn Coenen72110162016-08-19 14:28:25 +0200515
Martijn Coenen72110162016-08-19 14:28:25 +0200516private:
517 uint16_t mMajor;
518 uint16_t mMinor;
519};
520
521inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
522 return hidl_version(major,minor);
523}
524
Yifan Hongc1a60ef2016-11-08 18:53:16 -0800525struct IBase : virtual public RefBase {
Yifan Honga3c31842016-10-21 10:33:14 -0700526 virtual bool isRemote() const = 0;
527 // HIDL reserved methods follow.
528 virtual ::android::hardware::Return<void> interfaceChain(
529 std::function<void(const hidl_vec<hidl_string>&)> _hidl_cb) = 0;
530 // descriptor for HIDL reserved methods.
Steven Moreland5a682322016-11-11 12:32:50 -0800531 static const char* descriptor;
Yifan Honga3c31842016-10-21 10:33:14 -0700532};
533
Steven Morelandbdf26662016-09-02 11:03:15 -0700534#if defined(__LP64__)
535#define HAL_LIBRARY_PATH_SYSTEM "/system/lib64/hw/"
536#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib64/hw/"
537#define HAL_LIBRARY_PATH_ODM "/odm/lib64/hw/"
538#else
539#define HAL_LIBRARY_PATH_SYSTEM "/system/lib/hw/"
540#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib/hw/"
541#define HAL_LIBRARY_PATH_ODM "/odm/lib/hw/"
542#endif
543
Steven Moreland40ede2c2016-11-09 13:51:53 -0800544#define DECLARE_SERVICE_MANAGER_INTERACTIONS(INTERFACE) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200545 static ::android::sp<I##INTERFACE> getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700546 const std::string &serviceName, bool getStub=false); \
Steven Moreland40ede2c2016-11-09 13:51:53 -0800547 ::android::status_t registerAsService(const std::string &serviceName); \
548 static bool registerForNotifications( \
549 const std::string &serviceName, \
550 const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> \
551 &notification); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200552
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700553// ----------------------------------------------------------------------
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700554// Class that provides Hidl instrumentation utilities.
555struct HidlInstrumentor {
556 // Event that triggers the instrumentation. e.g. enter of an API call on
557 // the server/client side, exit of an API call on the server/client side
558 // etc.
559 enum InstrumentationEvent {
560 SERVER_API_ENTRY = 0,
561 SERVER_API_EXIT,
562 CLIENT_API_ENTRY,
563 CLIENT_API_EXIT,
564 SYNC_CALLBACK_ENTRY,
565 SYNC_CALLBACK_EXIT,
566 ASYNC_CALLBACK_ENTRY,
567 ASYNC_CALLBACK_EXIT,
Steven Morelandcefbd6e2016-11-01 10:14:30 -0700568 PASSTHROUGH_ENTRY,
569 PASSTHROUGH_EXIT,
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700570 };
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700571
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700572 // Signature of the instrumentation callback function.
573 using InstrumentationCallback = std::function<void(
574 const InstrumentationEvent event,
575 const char *package,
576 const char *version,
577 const char *interface,
578 const char *method,
579 std::vector<void *> *args)>;
580
581 explicit HidlInstrumentor(const std::string &prefix);
582 virtual ~HidlInstrumentor();
583
584 protected:
585 // Function that lookup and dynamically loads the hidl instrumentation
586 // libraries and registers the instrumentation callback functions.
587 //
588 // The instrumentation libraries should be stored under any of the following
589 // directories: HAL_LIBRARY_PATH_SYSTEM, HAL_LIBRARY_PATH_VENDOR and
590 // HAL_LIBRARY_PATH_ODM. The name of instrumentation libraries should
591 // follow pattern: ^profilerPrefix(.*).profiler.so$
592 //
593 // Each instrumentation library is expected to implement the instrumentation
594 // function called HIDL_INSTRUMENTATION_FUNCTION.
595 //
596 // A no-op for user build.
597 void registerInstrumentationCallbacks(
598 const std::string &profilerPrefix,
599 std::vector<InstrumentationCallback> *instrumentationCallbacks);
600
601 // Utility function to determine whether a give file is a instrumentation
602 // library (i.e. the file name follow the expected pattern).
603 bool isInstrumentationLib(
604 const std::string &profilerPrefix,
605 const dirent *file);
606 // A list of registered instrumentation callbacks.
607 std::vector<InstrumentationCallback> mInstrumentationCallbacks;
608 // Flag whether to enable instrumentation.
609 bool mEnableInstrumentation;
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700610};
611
Martijn Coenen72110162016-08-19 14:28:25 +0200612} // namespace hardware
613} // namespace android
614
Martijn Coenenc28f1152016-08-22 14:06:56 +0200615
Martijn Coenen72110162016-08-19 14:28:25 +0200616#endif // ANDROID_HIDL_SUPPORT_H
617