blob: c3ec8f50c60b1b2e49dd1a3c4f0e6adcda64db9e [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>
Martijn Coenen72110162016-08-19 14:28:25 +020024#include <hwbinder/Parcel.h>
Andreas Huber00a985c2016-09-28 14:24:53 -070025#include <tuple>
Iliyan Malchev692070a2016-09-12 16:30:44 -070026#include <utils/Errors.h>
27#include <utils/RefBase.h>
28#include <utils/StrongPointer.h>
Martijn Coenen72110162016-08-19 14:28:25 +020029
30namespace android {
31namespace hardware {
32
33struct hidl_string {
34 hidl_string();
35 ~hidl_string();
36
37 hidl_string(const hidl_string &);
Steven Morelande03c0872016-10-24 10:43:50 -070038 hidl_string(const char *);
Martijn Coenen72110162016-08-19 14:28:25 +020039
40 const char *c_str() const;
41 size_t size() const;
42 bool empty() const;
43
Steven Morelande03c0872016-10-24 10:43:50 -070044 hidl_string &operator=(const hidl_string &);
Martijn Coenen72110162016-08-19 14:28:25 +020045 hidl_string &operator=(const char *s);
Steven Morelande03c0872016-10-24 10:43:50 -070046
Martijn Coenen72110162016-08-19 14:28:25 +020047 void clear();
48
49 // Reference an external char array. Ownership is _not_ transferred.
50 // Caller is responsible for ensuring that underlying memory is valid
51 // for the lifetime of this hidl_string.
52 void setToExternal(const char *data, size_t size);
53
54 status_t readEmbeddedFromParcel(
55 const Parcel &parcel, size_t parentHandle, size_t parentOffset);
56
57 status_t writeEmbeddedToParcel(
58 Parcel *parcel, size_t parentHandle, size_t parentOffset) const;
59
Andreas Huberebfeb362016-08-25 13:39:05 -070060 // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
61 static const size_t kOffsetOfBuffer;
62
Martijn Coenen72110162016-08-19 14:28:25 +020063private:
64 char *mBuffer;
65 size_t mSize; // NOT including the terminating '\0'.
66 bool mOwnsBuffer;
67
68 hidl_string &setTo(const char *data, size_t size);
69};
70
Andreas Huber20dce082016-09-22 19:39:13 -070071////////////////////////////////////////////////////////////////////////////////
72
Martijn Coenen72110162016-08-19 14:28:25 +020073template<typename T>
74struct hidl_vec {
75 hidl_vec()
76 : mBuffer(NULL),
77 mSize(0),
78 mOwnsBuffer(true) {
79 }
80
81 hidl_vec(const hidl_vec<T> &other)
82 : mBuffer(NULL),
83 mSize(0),
84 mOwnsBuffer(true) {
85 *this = other;
86 }
87
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -070088 hidl_vec(hidl_vec<T> &&other) {
89 *this = static_cast<hidl_vec &&>(other);
90 }
91
Martijn Coenen72110162016-08-19 14:28:25 +020092 ~hidl_vec() {
93 if (mOwnsBuffer) {
94 delete[] mBuffer;
95 }
96 mBuffer = NULL;
97 }
98
Alexey Polyudove2299012016-10-19 09:52:00 -070099 // Reference an existing array, optionally taking ownership. It is the
Martijn Coenen72110162016-08-19 14:28:25 +0200100 // caller's responsibility to ensure that the underlying memory stays
101 // valid for the lifetime of this hidl_vec.
Alexey Polyudove2299012016-10-19 09:52:00 -0700102 void setToExternal(T *data, size_t size, bool shouldOwn = false) {
Martijn Coenen72110162016-08-19 14:28:25 +0200103 if (mOwnsBuffer) {
104 delete [] mBuffer;
105 }
106 mBuffer = data;
107 mSize = size;
Alexey Polyudove2299012016-10-19 09:52:00 -0700108 mOwnsBuffer = shouldOwn;
Martijn Coenen72110162016-08-19 14:28:25 +0200109 }
110
Alexey Polyudov6f0c9a12016-10-18 09:37:35 -0700111 T *data() {
112 return mBuffer;
113 }
114
115 const T *data() const {
116 return mBuffer;
117 }
118
Alexey Polyudovc98a99c2016-10-18 09:43:56 -0700119 T *releaseData() {
120 if (!mOwnsBuffer && mSize > 0) {
121 resize(mSize);
122 }
123 mOwnsBuffer = false;
124 return mBuffer;
125 }
126
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700127 hidl_vec &operator=(hidl_vec &&other) {
128 mBuffer = other.mBuffer;
129 mSize = other.mSize;
130 mOwnsBuffer = other.mOwnsBuffer;
131 other.mOwnsBuffer = false;
132 return *this;
133 }
134
Martijn Coenen72110162016-08-19 14:28:25 +0200135 hidl_vec &operator=(const hidl_vec &other) {
136 if (this != &other) {
137 if (mOwnsBuffer) {
138 delete[] mBuffer;
139 }
140 mBuffer = NULL;
141 mSize = other.mSize;
142 mOwnsBuffer = true;
143 if (mSize > 0) {
144 mBuffer = new T[mSize];
145 for (size_t i = 0; i < mSize; ++i) {
146 mBuffer[i] = other.mBuffer[i];
147 }
148 }
149 }
150
151 return *this;
152 }
153
154 size_t size() const {
155 return mSize;
156 }
157
158 T &operator[](size_t index) {
159 return mBuffer[index];
160 }
161
162 const T &operator[](size_t index) const {
163 return mBuffer[index];
164 }
165
166 void resize(size_t size) {
167 T *newBuffer = new T[size];
168
169 for (size_t i = 0; i < std::min(size, mSize); ++i) {
170 newBuffer[i] = mBuffer[i];
171 }
172
173 if (mOwnsBuffer) {
174 delete[] mBuffer;
175 }
176 mBuffer = newBuffer;
177
178 mSize = size;
179 mOwnsBuffer = true;
180 }
181
182 status_t readEmbeddedFromParcel(
183 const Parcel &parcel,
184 size_t parentHandle,
185 size_t parentOffset,
186 size_t *handle);
187
188 status_t writeEmbeddedToParcel(
189 Parcel *parcel,
190 size_t parentHandle,
191 size_t parentOffset,
192 size_t *handle) const;
193
Yifan Hongb1d8d4c2016-08-23 17:39:06 -0700194 status_t findInParcel(const Parcel &parcel, size_t *handle) const {
195 return parcel.quickFindBuffer(mBuffer, handle);
196 }
197
198
Martijn Coenen72110162016-08-19 14:28:25 +0200199private:
200 T *mBuffer;
201 size_t mSize;
202 bool mOwnsBuffer;
203};
204
Andreas Huber20dce082016-09-22 19:39:13 -0700205////////////////////////////////////////////////////////////////////////////////
206
207namespace details {
208
209 template<size_t SIZE1, size_t... SIZES>
210 struct product {
211 static constexpr size_t value = SIZE1 * product<SIZES...>::value;
212 };
213
214 template<size_t SIZE1>
215 struct product<SIZE1> {
216 static constexpr size_t value = SIZE1;
217 };
218
219 template<typename T, size_t SIZE1, size_t... SIZES>
220 struct accessor {
221 explicit accessor(T *base)
222 : mBase(base) {
223 }
224
225 accessor<T, SIZES...> operator[](size_t index) {
226 return accessor<T, SIZES...>(
227 &mBase[index * product<SIZES...>::value]);
228 }
229
230 private:
231 T *mBase;
232 };
233
234 template<typename T, size_t SIZE1>
235 struct accessor<T, SIZE1> {
236 explicit accessor(T *base)
237 : mBase(base) {
238 }
239
240 T &operator[](size_t index) {
241 return mBase[index];
242 }
243
244 private:
245 T *mBase;
246 };
247
248 template<typename T, size_t SIZE1, size_t... SIZES>
249 struct const_accessor {
250 explicit const_accessor(const T *base)
251 : mBase(base) {
252 }
253
254 const_accessor<T, SIZES...> operator[](size_t index) {
255 return const_accessor<T, SIZES...>(
256 &mBase[index * product<SIZES...>::value]);
257 }
258
259 private:
260 const T *mBase;
261 };
262
263 template<typename T, size_t SIZE1>
264 struct const_accessor<T, SIZE1> {
265 explicit const_accessor(const T *base)
266 : mBase(base) {
267 }
268
269 const T &operator[](size_t index) const {
270 return mBase[index];
271 }
272
273 private:
274 const T *mBase;
275 };
276
277} // namespace details
278
279////////////////////////////////////////////////////////////////////////////////
280
281template<typename T, size_t SIZE1, size_t... SIZES>
282struct hidl_array {
283 hidl_array() = default;
284
285 T *data() { return mBuffer; }
286 const T *data() const { return mBuffer; }
287
288 details::accessor<T, SIZES...> operator[](size_t index) {
289 return details::accessor<T, SIZES...>(
290 &mBuffer[index * details::product<SIZES...>::value]);
291 }
292
293 details::const_accessor<T, SIZES...> operator[](size_t index) const {
294 return details::const_accessor<T, SIZES...>(
295 &mBuffer[index * details::product<SIZES...>::value]);
296 }
297
Andreas Huber00a985c2016-09-28 14:24:53 -0700298 using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;
299
300 static constexpr size_tuple_type size() {
301 return std::make_tuple(SIZE1, SIZES...);
302 }
303
Andreas Huber20dce082016-09-22 19:39:13 -0700304private:
305 T mBuffer[details::product<SIZE1, SIZES...>::value];
306};
307
308template<typename T, size_t SIZE1>
309struct hidl_array<T, SIZE1> {
310 hidl_array() = default;
311
312 T *data() { return mBuffer; }
313 const T *data() const { return mBuffer; }
314
315 T &operator[](size_t index) {
316 return mBuffer[index];
317 }
318
319 const T &operator[](size_t index) const {
320 return mBuffer[index];
321 }
322
Andreas Huber00a985c2016-09-28 14:24:53 -0700323 static constexpr size_t size() { return SIZE1; }
324
Andreas Huber20dce082016-09-22 19:39:13 -0700325private:
326 T mBuffer[SIZE1];
327};
328
329////////////////////////////////////////////////////////////////////////////////
330
Martijn Coenen72110162016-08-19 14:28:25 +0200331template<typename T>
332status_t hidl_vec<T>::readEmbeddedFromParcel(
333 const Parcel &parcel,
334 size_t parentHandle,
335 size_t parentOffset,
336 size_t *handle) {
337 const void *ptr = parcel.readEmbeddedBuffer(
338 handle,
339 parentHandle,
340 parentOffset + offsetof(hidl_vec<T>, mBuffer));
341
342 return ptr != NULL ? OK : UNKNOWN_ERROR;
343}
344
345template<typename T>
346status_t hidl_vec<T>::writeEmbeddedToParcel(
347 Parcel *parcel,
348 size_t parentHandle,
349 size_t parentOffset,
350 size_t *handle) const {
351 return parcel->writeEmbeddedBuffer(
352 mBuffer,
353 sizeof(T) * mSize,
354 handle,
355 parentHandle,
356 parentOffset + offsetof(hidl_vec<T>, mBuffer));
357}
358
Yifan Hongb1d8d4c2016-08-23 17:39:06 -0700359///////////////////////////// pointers for HIDL
360
361template <typename T>
362static status_t readEmbeddedReferenceFromParcel(
363 T const* * /* bufptr */,
364 const Parcel & parcel,
365 size_t parentHandle,
366 size_t parentOffset,
367 size_t *handle,
368 bool *shouldResolveRefInBuffer
369 ) {
370 // *bufptr is ignored because, if I am embedded in some
371 // other buffer, the kernel should have fixed me up already.
372 bool isPreviouslyWritten;
373 status_t result = parcel.readEmbeddedReference(
374 nullptr, // ignored, not written to bufptr.
375 handle,
376 parentHandle,
377 parentOffset,
378 &isPreviouslyWritten);
379 // tell caller to run T::readEmbeddedToParcel and
380 // T::readEmbeddedReferenceToParcel if necessary.
381 // It is not called here because we don't know if these two are valid methods.
382 *shouldResolveRefInBuffer = !isPreviouslyWritten;
383 return result;
384}
385
386template <typename T>
387static status_t writeEmbeddedReferenceToParcel(
388 T const* buf,
389 Parcel *parcel, size_t parentHandle, size_t parentOffset,
390 size_t *handle,
391 bool *shouldResolveRefInBuffer
392 ) {
393
394 if(buf == nullptr) {
395 *shouldResolveRefInBuffer = false;
396 return parcel->writeEmbeddedNullReference(handle, parentHandle, parentOffset);
397 }
398
399 // find whether the buffer exists
400 size_t childHandle, childOffset;
401 status_t result;
402 bool found;
403
404 result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);
405
406 // tell caller to run T::writeEmbeddedToParcel and
407 // T::writeEmbeddedReferenceToParcel if necessary.
408 // It is not called here because we don't know if these two are valid methods.
409 *shouldResolveRefInBuffer = !found;
410
411 if(result != OK) {
412 return result; // bad pointers and length given
413 }
414 if(!found) { // did not find it.
415 return parcel->writeEmbeddedBuffer(buf, sizeof(T), handle,
416 parentHandle, parentOffset);
417 }
418 // found the buffer. easy case.
419 return parcel->writeEmbeddedReference(
420 handle,
421 childHandle,
422 childOffset,
423 parentHandle,
424 parentOffset);
425}
426
427template <typename T>
428static status_t readReferenceFromParcel(
429 T const* *bufptr,
430 const Parcel & parcel,
431 size_t *handle,
432 bool *shouldResolveRefInBuffer
433 ) {
434 bool isPreviouslyWritten;
435 status_t result = parcel.readReference(reinterpret_cast<void const* *>(bufptr),
436 handle, &isPreviouslyWritten);
437 // tell caller to run T::readEmbeddedToParcel and
438 // T::readEmbeddedReferenceToParcel if necessary.
439 // It is not called here because we don't know if these two are valid methods.
440 *shouldResolveRefInBuffer = !isPreviouslyWritten;
441 return result;
442}
443
444template <typename T>
445static status_t writeReferenceToParcel(
446 T const *buf,
447 Parcel * parcel,
448 size_t *handle,
449 bool *shouldResolveRefInBuffer
450 ) {
451
452 if(buf == nullptr) {
453 *shouldResolveRefInBuffer = false;
454 return parcel->writeNullReference(handle);
455 }
456
457 // find whether the buffer exists
458 size_t childHandle, childOffset;
459 status_t result;
460 bool found;
461
462 result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);
463
464 // tell caller to run T::writeEmbeddedToParcel and
465 // T::writeEmbeddedReferenceToParcel if necessary.
466 // It is not called here because we don't know if these two are valid methods.
467 *shouldResolveRefInBuffer = !found;
468
469 if(result != OK) {
470 return result; // bad pointers and length given
471 }
472 if(!found) { // did not find it.
473 return parcel->writeBuffer(buf, sizeof(T), handle);
474 }
475 // found the buffer. easy case.
476 return parcel->writeReference(handle,
477 childHandle, childOffset);
478}
479
Martijn Coenen72110162016-08-19 14:28:25 +0200480// ----------------------------------------------------------------------
481// Version functions
482struct hidl_version {
483public:
Chia-I Wu666b76b2016-10-06 14:15:59 +0800484 constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {}
Martijn Coenen72110162016-08-19 14:28:25 +0200485
486 bool operator==(const hidl_version& other) {
487 return (mMajor == other.get_major() && mMinor == other.get_minor());
488 }
Martijn Coenenc28f1152016-08-22 14:06:56 +0200489
Martijn Coenen097a7672016-09-08 16:56:41 +0200490 constexpr uint16_t get_major() const { return mMajor; }
491 constexpr uint16_t get_minor() const { return mMinor; }
Martijn Coenen72110162016-08-19 14:28:25 +0200492
493 android::status_t writeToParcel(android::hardware::Parcel& parcel) const {
Chia-I Wu666b76b2016-10-06 14:15:59 +0800494 return parcel.writeUint32(static_cast<uint32_t>(mMajor) << 16 | mMinor);
Martijn Coenen72110162016-08-19 14:28:25 +0200495 }
496
497 static hidl_version* readFromParcel(const android::hardware::Parcel& parcel) {
498 uint32_t version;
499 android::status_t status = parcel.readUint32(&version);
500 if (status != OK) {
501 return nullptr;
502 } else {
503 return new hidl_version(version >> 16, version & 0xFFFF);
504 }
505 }
506
507private:
508 uint16_t mMajor;
509 uint16_t mMinor;
510};
511
512inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
513 return hidl_version(major,minor);
514}
515
Steven Morelandbdf26662016-09-02 11:03:15 -0700516#if defined(__LP64__)
517#define HAL_LIBRARY_PATH_SYSTEM "/system/lib64/hw/"
518#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib64/hw/"
519#define HAL_LIBRARY_PATH_ODM "/odm/lib64/hw/"
520#else
521#define HAL_LIBRARY_PATH_SYSTEM "/system/lib/hw/"
522#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib/hw/"
523#define HAL_LIBRARY_PATH_ODM "/odm/lib/hw/"
524#endif
525
Martijn Coenenc28f1152016-08-22 14:06:56 +0200526#define DECLARE_REGISTER_AND_GET_SERVICE(INTERFACE) \
527 static ::android::sp<I##INTERFACE> getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700528 const std::string &serviceName, bool getStub=false); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700529 status_t registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200530 const std::string &serviceName); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200531
Steven Morelandbdf26662016-09-02 11:03:15 -0700532#define IMPLEMENT_REGISTER_AND_GET_SERVICE(INTERFACE, LIB) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200533 ::android::sp<I##INTERFACE> I##INTERFACE::getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700534 const std::string &serviceName, bool getStub) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200535 { \
536 sp<I##INTERFACE> iface; \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700537 const struct timespec DELAY {1,0}; \
538 unsigned retries = 3; \
539 if (!getStub) { \
540 do { \
541 const sp<IServiceManager> sm = defaultServiceManager(); \
542 if (sm != nullptr) { \
543 sp<IBinder> binderIface = \
544 sm->checkService(String16(serviceName.c_str()), \
545 I##INTERFACE::version); \
546 iface = IHw##INTERFACE::asInterface(binderIface); \
547 } \
548 if (iface != nullptr) { \
549 return iface; \
550 } \
551 TEMP_FAILURE_RETRY(nanosleep(&DELAY, nullptr)); \
552 } while (retries--); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700553 } \
554 int dlMode = RTLD_LAZY; \
555 void *handle = dlopen(HAL_LIBRARY_PATH_ODM LIB, dlMode); \
556 if (handle == nullptr) { \
557 handle = dlopen(HAL_LIBRARY_PATH_VENDOR LIB, dlMode); \
558 } \
559 if (handle == nullptr) { \
560 handle = dlopen(HAL_LIBRARY_PATH_SYSTEM LIB, dlMode); \
561 } \
562 if (handle == nullptr) { \
563 return iface; \
564 } \
565 I##INTERFACE* (*generator)(const char* name); \
566 *(void **)(&generator) = dlsym(handle, "HIDL_FETCH_I"#INTERFACE); \
567 if (generator) { \
Martijn Coenenf7a651d2016-09-08 13:38:12 +0200568 iface = (*generator)(serviceName.c_str()); \
Steven Moreland7391bc32016-09-14 10:31:48 -0700569 if (iface != nullptr) { \
570 iface = new Bs##INTERFACE(iface); \
571 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700572 } \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200573 return iface; \
574 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700575 status_t I##INTERFACE::registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200576 const std::string &serviceName) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200577 { \
578 sp<Bn##INTERFACE> binderIface = new Bn##INTERFACE(this); \
579 const sp<IServiceManager> sm = defaultServiceManager(); \
Martijn Coenen097a7672016-09-08 16:56:41 +0200580 return sm->addService(String16(serviceName.c_str()), binderIface, \
581 I##INTERFACE::version); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200582 }
583
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700584// ----------------------------------------------------------------------
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700585// Class that provides Hidl instrumentation utilities.
586struct HidlInstrumentor {
587 // Event that triggers the instrumentation. e.g. enter of an API call on
588 // the server/client side, exit of an API call on the server/client side
589 // etc.
590 enum InstrumentationEvent {
591 SERVER_API_ENTRY = 0,
592 SERVER_API_EXIT,
593 CLIENT_API_ENTRY,
594 CLIENT_API_EXIT,
595 SYNC_CALLBACK_ENTRY,
596 SYNC_CALLBACK_EXIT,
597 ASYNC_CALLBACK_ENTRY,
598 ASYNC_CALLBACK_EXIT,
599 };
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700600
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700601 // Signature of the instrumentation callback function.
602 using InstrumentationCallback = std::function<void(
603 const InstrumentationEvent event,
604 const char *package,
605 const char *version,
606 const char *interface,
607 const char *method,
608 std::vector<void *> *args)>;
609
610 explicit HidlInstrumentor(const std::string &prefix);
611 virtual ~HidlInstrumentor();
612
613 protected:
614 // Function that lookup and dynamically loads the hidl instrumentation
615 // libraries and registers the instrumentation callback functions.
616 //
617 // The instrumentation libraries should be stored under any of the following
618 // directories: HAL_LIBRARY_PATH_SYSTEM, HAL_LIBRARY_PATH_VENDOR and
619 // HAL_LIBRARY_PATH_ODM. The name of instrumentation libraries should
620 // follow pattern: ^profilerPrefix(.*).profiler.so$
621 //
622 // Each instrumentation library is expected to implement the instrumentation
623 // function called HIDL_INSTRUMENTATION_FUNCTION.
624 //
625 // A no-op for user build.
626 void registerInstrumentationCallbacks(
627 const std::string &profilerPrefix,
628 std::vector<InstrumentationCallback> *instrumentationCallbacks);
629
630 // Utility function to determine whether a give file is a instrumentation
631 // library (i.e. the file name follow the expected pattern).
632 bool isInstrumentationLib(
633 const std::string &profilerPrefix,
634 const dirent *file);
635 // A list of registered instrumentation callbacks.
636 std::vector<InstrumentationCallback> mInstrumentationCallbacks;
637 // Flag whether to enable instrumentation.
638 bool mEnableInstrumentation;
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700639};
640
Martijn Coenen72110162016-08-19 14:28:25 +0200641} // namespace hardware
642} // namespace android
643
Martijn Coenenc28f1152016-08-22 14:06:56 +0200644
Martijn Coenen72110162016-08-19 14:28:25 +0200645#endif // ANDROID_HIDL_SUPPORT_H
646