HidlSupport.h revision ca1d1bf76f0e38cbe8d301a761b1c428f83bf853
1/* 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 20#include <algorithm> 21#include <array> 22#include <dirent.h> 23#include <dlfcn.h> 24#include <iterator> 25#include <cutils/native_handle.h> 26#include <cutils/properties.h> 27#include <functional> 28#include <hidl/HidlInternal.h> 29#include <hidl/Status.h> 30#include <map> 31#include <stddef.h> 32#include <tuple> 33#include <type_traits> 34#include <utils/Errors.h> 35#include <utils/RefBase.h> 36#include <utils/StrongPointer.h> 37#include <vector> 38 39namespace android { 40 41// this file is included by all hidl interface, so we must forward declare the IMemory type. 42namespace hidl { 43namespace memory { 44namespace V1_0 { 45 struct IMemory; 46}; // namespace V1_0 47}; // namespace manager 48}; // namespace hidl 49 50namespace hardware { 51 52// hidl_handle wraps a pointer to a native_handle_t in a hidl_pointer, 53// so that it can safely be transferred between 32-bit and 64-bit processes. 54struct hidl_handle { 55 hidl_handle() { 56 mHandle = nullptr; 57 } 58 ~hidl_handle() { 59 } 60 61 // copy constructors. 62 hidl_handle(const native_handle_t *handle) { 63 mHandle = handle; 64 } 65 66 hidl_handle(const hidl_handle &other) { 67 mHandle = other.mHandle; 68 } 69 70 // move constructor. 71 hidl_handle(hidl_handle &&other) { 72 *this = std::move(other); 73 } 74 75 // assingment operators 76 hidl_handle &operator=(const hidl_handle &other) { 77 mHandle = other.mHandle; 78 return *this; 79 } 80 81 hidl_handle &operator=(const native_handle_t *native_handle) { 82 mHandle = native_handle; 83 return *this; 84 } 85 86 hidl_handle &operator=(hidl_handle &&other) { 87 mHandle = other.mHandle; 88 other.mHandle = nullptr; 89 return *this; 90 } 91 92 const native_handle_t* operator->() const { 93 return mHandle; 94 } 95 // implicit conversion to const native_handle_t* 96 operator const native_handle_t *() const { 97 return mHandle; 98 } 99 // explicit conversion 100 const native_handle_t *getNativeHandle() const { 101 return mHandle; 102 } 103private: 104 details::hidl_pointer<const native_handle_t> mHandle; 105}; 106 107struct hidl_string { 108 hidl_string(); 109 ~hidl_string(); 110 111 // copy constructor. 112 hidl_string(const hidl_string &); 113 // copy from a C-style string. 114 hidl_string(const char *); 115 // copy from an std::string. 116 hidl_string(const std::string &); 117 118 // move constructor. 119 hidl_string(hidl_string &&); 120 121 const char *c_str() const; 122 size_t size() const; 123 bool empty() const; 124 125 // copy assignment operator. 126 hidl_string &operator=(const hidl_string &); 127 // copy from a C-style string. 128 hidl_string &operator=(const char *s); 129 // copy from an std::string. 130 hidl_string &operator=(const std::string &); 131 // move assignment operator. 132 hidl_string &operator=(hidl_string &&other); 133 // cast to std::string. 134 operator std::string() const; 135 // cast to C-style string. Caller is responsible 136 // to maintain this hidl_string alive. 137 operator const char *() const; 138 139 void clear(); 140 141 // Reference an external char array. Ownership is _not_ transferred. 142 // Caller is responsible for ensuring that underlying memory is valid 143 // for the lifetime of this hidl_string. 144 void setToExternal(const char *data, size_t size); 145 146 // offsetof(hidl_string, mBuffer) exposed since mBuffer is private. 147 static const size_t kOffsetOfBuffer; 148 149private: 150 details::hidl_pointer<const char> mBuffer; 151 uint32_t mSize; // NOT including the terminating '\0'. 152 bool mOwnsBuffer; // if true then mBuffer is a mutable char * 153 154 // copy from data with size. Assume that my memory is freed 155 // (through clear(), for example) 156 void copyFrom(const char *data, size_t size); 157 // move from another hidl_string 158 void moveFrom(hidl_string &&); 159}; 160 161inline bool operator==(const hidl_string &hs1, const hidl_string &hs2) { 162 return strcmp(hs1.c_str(), hs2.c_str()) == 0; 163} 164 165inline bool operator!=(const hidl_string &hs1, const hidl_string &hs2) { 166 return !(hs1 == hs2); 167} 168 169inline bool operator==(const hidl_string &hs, const char *s) { 170 return strcmp(hs.c_str(), s) == 0; 171} 172 173inline bool operator!=(const hidl_string &hs, const char *s) { 174 return !(hs == s); 175} 176 177inline bool operator==(const char *s, const hidl_string &hs) { 178 return strcmp(hs.c_str(), s) == 0; 179} 180 181inline bool operator!=(const char *s, const hidl_string &hs) { 182 return !(s == hs); 183} 184 185// hidl_memory is a structure that can be used to transfer 186// pieces of shared memory between processes. The assumption 187// of this object is that the memory remains accessible as 188// long as the file descriptors in the enclosed mHandle 189// - as well as all of its cross-process dups() - remain opened. 190struct hidl_memory { 191 192 hidl_memory() : mOwnsHandle(false), mHandle(nullptr), mSize(0), mName("") { 193 } 194 195 /** 196 * Creates a hidl_memory object and takes ownership of the handle. 197 */ 198 hidl_memory(const hidl_string &name, const hidl_handle &handle, size_t size) 199 : mOwnsHandle(true), 200 mHandle(handle), 201 mSize(size), 202 mName(name) 203 {} 204 205 // copy constructor 206 hidl_memory(const hidl_memory& other) { 207 *this = other; 208 } 209 210 // copy assignment 211 hidl_memory &operator=(const hidl_memory &other) { 212 if (this != &other) { 213 mOwnsHandle = true; 214 mHandle = native_handle_clone(other.mHandle); 215 mSize = other.mSize; 216 mName = other.mName; 217 } 218 219 return *this; 220 } 221 222 // TODO move constructor/move assignment 223 224 ~hidl_memory() { 225 // TODO if we had previously mapped from this object, unmap 226 if (mOwnsHandle) { 227 native_handle_close(mHandle); 228 } 229 } 230 231 const native_handle_t* handle() const { 232 return mHandle; 233 } 234 235 const hidl_string &name() const { 236 return mName; 237 } 238 239 size_t size() const { 240 return mSize; 241 } 242 243 // offsetof(hidl_memory, mHandle) exposed since mHandle is private. 244 static const size_t kOffsetOfHandle; 245 // offsetof(hidl_memory, mName) exposed since mHandle is private. 246 static const size_t kOffsetOfName; 247private: 248 bool mOwnsHandle; 249 hidl_handle mHandle; 250 size_t mSize; 251 hidl_string mName; 252}; 253 254//////////////////////////////////////////////////////////////////////////////// 255 256template<typename T> 257struct hidl_vec : private details::hidl_log_base { 258 hidl_vec() 259 : mBuffer(NULL), 260 mSize(0), 261 mOwnsBuffer(true) { 262 } 263 264 hidl_vec(const hidl_vec<T> &other) : hidl_vec() { 265 *this = other; 266 } 267 268 hidl_vec(hidl_vec<T> &&other) 269 : mOwnsBuffer(false) { 270 *this = std::move(other); 271 } 272 273 hidl_vec(const std::initializer_list<T> list) 274 : mOwnsBuffer(true) { 275 if (list.size() > UINT32_MAX) { 276 logAlwaysFatal("hidl_vec can't hold more than 2^32 elements."); 277 } 278 mSize = static_cast<uint32_t>(list.size()); 279 mBuffer = new T[mSize]; 280 281 size_t idx = 0; 282 for (auto it = list.begin(); it != list.end(); ++it) { 283 mBuffer[idx++] = *it; 284 } 285 } 286 287 hidl_vec(const std::vector<T> &other) : hidl_vec() { 288 *this = other; 289 } 290 291 ~hidl_vec() { 292 if (mOwnsBuffer) { 293 delete[] mBuffer; 294 } 295 mBuffer = NULL; 296 } 297 298 // Reference an existing array, optionally taking ownership. It is the 299 // caller's responsibility to ensure that the underlying memory stays 300 // valid for the lifetime of this hidl_vec. 301 void setToExternal(T *data, size_t size, bool shouldOwn = false) { 302 if (mOwnsBuffer) { 303 delete [] mBuffer; 304 } 305 mBuffer = data; 306 if (size > UINT32_MAX) { 307 logAlwaysFatal("external vector size exceeds 2^32 elements."); 308 } 309 mSize = static_cast<uint32_t>(size); 310 mOwnsBuffer = shouldOwn; 311 } 312 313 T *data() { 314 return mBuffer; 315 } 316 317 const T *data() const { 318 return mBuffer; 319 } 320 321 T *releaseData() { 322 if (!mOwnsBuffer && mSize > 0) { 323 resize(mSize); 324 } 325 mOwnsBuffer = false; 326 return mBuffer; 327 } 328 329 hidl_vec &operator=(hidl_vec &&other) { 330 if (mOwnsBuffer) { 331 delete[] mBuffer; 332 } 333 mBuffer = other.mBuffer; 334 mSize = other.mSize; 335 mOwnsBuffer = other.mOwnsBuffer; 336 other.mOwnsBuffer = false; 337 return *this; 338 } 339 340 hidl_vec &operator=(const hidl_vec &other) { 341 if (this != &other) { 342 if (mOwnsBuffer) { 343 delete[] mBuffer; 344 } 345 copyFrom(other, other.mSize); 346 } 347 348 return *this; 349 } 350 351 // copy from an std::vector. 352 hidl_vec &operator=(const std::vector<T> &other) { 353 if (mOwnsBuffer) { 354 delete[] mBuffer; 355 } 356 copyFrom(other, other.size()); 357 return *this; 358 } 359 360 // cast to an std::vector. 361 operator std::vector<T>() const { 362 std::vector<T> v(mSize); 363 for (size_t i = 0; i < mSize; ++i) { 364 v[i] = mBuffer[i]; 365 } 366 return v; 367 } 368 369 size_t size() const { 370 return mSize; 371 } 372 373 T &operator[](size_t index) { 374 return mBuffer[index]; 375 } 376 377 const T &operator[](size_t index) const { 378 return mBuffer[index]; 379 } 380 381 void resize(size_t size) { 382 if (size > UINT32_MAX) { 383 logAlwaysFatal("hidl_vec can't hold more than 2^32 elements."); 384 } 385 T *newBuffer = new T[size]; 386 387 for (size_t i = 0; i < std::min(static_cast<uint32_t>(size), mSize); ++i) { 388 newBuffer[i] = mBuffer[i]; 389 } 390 391 if (mOwnsBuffer) { 392 delete[] mBuffer; 393 } 394 mBuffer = newBuffer; 395 396 mSize = static_cast<uint32_t>(size); 397 mOwnsBuffer = true; 398 } 399 400 // offsetof(hidl_string, mBuffer) exposed since mBuffer is private. 401 static const size_t kOffsetOfBuffer; 402 403private: 404 // Define std interator interface for walking the array contents 405 template<bool is_const> 406 class iter : public std::iterator< 407 std::random_access_iterator_tag, /* Category */ 408 T, 409 ptrdiff_t, /* Distance */ 410 typename std::conditional<is_const, const T *, T *>::type /* Pointer */, 411 typename std::conditional<is_const, const T &, T &>::type /* Reference */> 412 { 413 using traits = std::iterator_traits<iter>; 414 using ptr_type = typename traits::pointer; 415 using ref_type = typename traits::reference; 416 using diff_type = typename traits::difference_type; 417 public: 418 iter(ptr_type ptr) : mPtr(ptr) { } 419 inline iter &operator++() { mPtr++; return *this; } 420 inline iter operator++(int) { iter i = *this; mPtr++; return i; } 421 inline iter &operator--() { mPtr--; return *this; } 422 inline iter operator--(int) { iter i = *this; mPtr--; return i; } 423 inline friend iter operator+(diff_type n, const iter &it) { return it.mPtr + n; } 424 inline iter operator+(diff_type n) const { return mPtr + n; } 425 inline iter operator-(diff_type n) const { return mPtr - n; } 426 inline diff_type operator-(const iter &other) const { return mPtr - other.mPtr; } 427 inline iter &operator+=(diff_type n) { mPtr += n; return *this; } 428 inline iter &operator-=(diff_type n) { mPtr -= n; return *this; } 429 inline ref_type operator*() const { return *mPtr; } 430 inline ptr_type operator->() const { return mPtr; } 431 inline bool operator==(const iter &rhs) const { return mPtr == rhs.mPtr; } 432 inline bool operator!=(const iter &rhs) const { return mPtr != rhs.mPtr; } 433 inline bool operator< (const iter &rhs) const { return mPtr < rhs.mPtr; } 434 inline bool operator> (const iter &rhs) const { return mPtr > rhs.mPtr; } 435 inline bool operator<=(const iter &rhs) const { return mPtr <= rhs.mPtr; } 436 inline bool operator>=(const iter &rhs) const { return mPtr >= rhs.mPtr; } 437 inline ref_type operator[](size_t n) const { return mPtr[n]; } 438 private: 439 ptr_type mPtr; 440 }; 441public: 442 using iterator = iter<false /* is_const */>; 443 using const_iterator = iter<true /* is_const */>; 444 445 iterator begin() { return data(); } 446 iterator end() { return data()+mSize; } 447 const_iterator begin() const { return data(); } 448 const_iterator end() const { return data()+mSize; } 449 450private: 451 details::hidl_pointer<T> mBuffer; 452 uint32_t mSize; 453 bool mOwnsBuffer; 454 455 // copy from an array-like object, assuming my resources are freed. 456 template <typename Array> 457 void copyFrom(const Array &data, size_t size) { 458 mSize = static_cast<uint32_t>(size); 459 mOwnsBuffer = true; 460 if (mSize > 0) { 461 mBuffer = new T[size]; 462 for (size_t i = 0; i < size; ++i) { 463 mBuffer[i] = data[i]; 464 } 465 } else { 466 mBuffer = NULL; 467 } 468 } 469}; 470 471template <typename T> 472const size_t hidl_vec<T>::kOffsetOfBuffer = offsetof(hidl_vec<T>, mBuffer); 473 474//////////////////////////////////////////////////////////////////////////////// 475 476namespace details { 477 478 template<size_t SIZE1, size_t... SIZES> 479 struct product { 480 static constexpr size_t value = SIZE1 * product<SIZES...>::value; 481 }; 482 483 template<size_t SIZE1> 484 struct product<SIZE1> { 485 static constexpr size_t value = SIZE1; 486 }; 487 488 template<typename T, size_t SIZE1, size_t... SIZES> 489 struct std_array { 490 using type = std::array<typename std_array<T, SIZES...>::type, SIZE1>; 491 }; 492 493 template<typename T, size_t SIZE1> 494 struct std_array<T, SIZE1> { 495 using type = std::array<T, SIZE1>; 496 }; 497 498 template<typename T, size_t SIZE1, size_t... SIZES> 499 struct accessor { 500 501 using std_array_type = typename std_array<T, SIZE1, SIZES...>::type; 502 503 explicit accessor(T *base) 504 : mBase(base) { 505 } 506 507 accessor<T, SIZES...> operator[](size_t index) { 508 return accessor<T, SIZES...>( 509 &mBase[index * product<SIZES...>::value]); 510 } 511 512 accessor &operator=(const std_array_type &other) { 513 for (size_t i = 0; i < SIZE1; ++i) { 514 (*this)[i] = other[i]; 515 } 516 return *this; 517 } 518 519 private: 520 T *mBase; 521 }; 522 523 template<typename T, size_t SIZE1> 524 struct accessor<T, SIZE1> { 525 526 using std_array_type = typename std_array<T, SIZE1>::type; 527 528 explicit accessor(T *base) 529 : mBase(base) { 530 } 531 532 T &operator[](size_t index) { 533 return mBase[index]; 534 } 535 536 accessor &operator=(const std_array_type &other) { 537 for (size_t i = 0; i < SIZE1; ++i) { 538 (*this)[i] = other[i]; 539 } 540 return *this; 541 } 542 543 private: 544 T *mBase; 545 }; 546 547 template<typename T, size_t SIZE1, size_t... SIZES> 548 struct const_accessor { 549 550 using std_array_type = typename std_array<T, SIZE1, SIZES...>::type; 551 552 explicit const_accessor(const T *base) 553 : mBase(base) { 554 } 555 556 const_accessor<T, SIZES...> operator[](size_t index) { 557 return const_accessor<T, SIZES...>( 558 &mBase[index * product<SIZES...>::value]); 559 } 560 561 operator std_array_type() { 562 std_array_type array; 563 for (size_t i = 0; i < SIZE1; ++i) { 564 array[i] = (*this)[i]; 565 } 566 return array; 567 } 568 569 private: 570 const T *mBase; 571 }; 572 573 template<typename T, size_t SIZE1> 574 struct const_accessor<T, SIZE1> { 575 576 using std_array_type = typename std_array<T, SIZE1>::type; 577 578 explicit const_accessor(const T *base) 579 : mBase(base) { 580 } 581 582 const T &operator[](size_t index) const { 583 return mBase[index]; 584 } 585 586 operator std_array_type() { 587 std_array_type array; 588 for (size_t i = 0; i < SIZE1; ++i) { 589 array[i] = (*this)[i]; 590 } 591 return array; 592 } 593 594 private: 595 const T *mBase; 596 }; 597 598} // namespace details 599 600//////////////////////////////////////////////////////////////////////////////// 601 602// A multidimensional array of T's. Assumes that T::operator=(const T &) is defined. 603template<typename T, size_t SIZE1, size_t... SIZES> 604struct hidl_array { 605 606 using std_array_type = typename details::std_array<T, SIZE1, SIZES...>::type; 607 608 hidl_array() = default; 609 610 // Copies the data from source, using T::operator=(const T &). 611 hidl_array(const T *source) { 612 for (size_t i = 0; i < elementCount(); ++i) { 613 mBuffer[i] = source[i]; 614 } 615 } 616 617 // Copies the data from the given std::array, using T::operator=(const T &). 618 hidl_array(const std_array_type &array) { 619 details::accessor<T, SIZE1, SIZES...> modifier(mBuffer); 620 modifier = array; 621 } 622 623 T *data() { return mBuffer; } 624 const T *data() const { return mBuffer; } 625 626 details::accessor<T, SIZES...> operator[](size_t index) { 627 return details::accessor<T, SIZES...>( 628 &mBuffer[index * details::product<SIZES...>::value]); 629 } 630 631 details::const_accessor<T, SIZES...> operator[](size_t index) const { 632 return details::const_accessor<T, SIZES...>( 633 &mBuffer[index * details::product<SIZES...>::value]); 634 } 635 636 using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>; 637 638 static constexpr size_tuple_type size() { 639 return std::make_tuple(SIZE1, SIZES...); 640 } 641 642 static constexpr size_t elementCount() { 643 return details::product<SIZE1, SIZES...>::value; 644 } 645 646 operator std_array_type() const { 647 return details::const_accessor<T, SIZE1, SIZES...>(mBuffer); 648 } 649 650private: 651 T mBuffer[elementCount()]; 652}; 653 654// An array of T's. Assumes that T::operator=(const T &) is defined. 655template<typename T, size_t SIZE1> 656struct hidl_array<T, SIZE1> { 657 658 using std_array_type = typename details::std_array<T, SIZE1>::type; 659 660 hidl_array() = default; 661 662 // Copies the data from source, using T::operator=(const T &). 663 hidl_array(const T *source) { 664 for (size_t i = 0; i < elementCount(); ++i) { 665 mBuffer[i] = source[i]; 666 } 667 } 668 669 // Copies the data from the given std::array, using T::operator=(const T &). 670 hidl_array(const std_array_type &array) : hidl_array(array.data()) {} 671 672 T *data() { return mBuffer; } 673 const T *data() const { return mBuffer; } 674 675 T &operator[](size_t index) { 676 return mBuffer[index]; 677 } 678 679 const T &operator[](size_t index) const { 680 return mBuffer[index]; 681 } 682 683 static constexpr size_t size() { return SIZE1; } 684 static constexpr size_t elementCount() { return SIZE1; } 685 686 // Copies the data to an std::array, using T::operator=(T). 687 operator std_array_type() const { 688 std_array_type array; 689 for (size_t i = 0; i < SIZE1; ++i) { 690 array[i] = mBuffer[i]; 691 } 692 return array; 693 } 694 695private: 696 T mBuffer[SIZE1]; 697}; 698 699// ---------------------------------------------------------------------- 700// Version functions 701struct hidl_version { 702public: 703 constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {} 704 705 bool operator==(const hidl_version& other) const { 706 return (mMajor == other.get_major() && mMinor == other.get_minor()); 707 } 708 709 bool operator<(const hidl_version& other) const { 710 return (mMajor < other.get_major() || 711 (mMajor == other.get_major() && mMinor < other.get_minor())); 712 } 713 714 bool operator>(const hidl_version& other) const { 715 return other < *this; 716 } 717 718 bool operator<=(const hidl_version& other) const { 719 return !(*this > other); 720 } 721 722 bool operator>=(const hidl_version& other) const { 723 return !(*this < other); 724 } 725 726 constexpr uint16_t get_major() const { return mMajor; } 727 constexpr uint16_t get_minor() const { return mMinor; } 728 729private: 730 uint16_t mMajor; 731 uint16_t mMinor; 732}; 733 734inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) { 735 return hidl_version(major,minor); 736} 737 738#if defined(__LP64__) 739#define HAL_LIBRARY_PATH_SYSTEM "/system/lib64/hw/" 740#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib64/hw/" 741#define HAL_LIBRARY_PATH_ODM "/odm/lib64/hw/" 742#else 743#define HAL_LIBRARY_PATH_SYSTEM "/system/lib/hw/" 744#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib/hw/" 745#define HAL_LIBRARY_PATH_ODM "/odm/lib/hw/" 746#endif 747 748// ---------------------------------------------------------------------- 749// Class that provides Hidl instrumentation utilities. 750struct HidlInstrumentor { 751 // Event that triggers the instrumentation. e.g. enter of an API call on 752 // the server/client side, exit of an API call on the server/client side 753 // etc. 754 enum InstrumentationEvent { 755 SERVER_API_ENTRY = 0, 756 SERVER_API_EXIT, 757 CLIENT_API_ENTRY, 758 CLIENT_API_EXIT, 759 SYNC_CALLBACK_ENTRY, 760 SYNC_CALLBACK_EXIT, 761 ASYNC_CALLBACK_ENTRY, 762 ASYNC_CALLBACK_EXIT, 763 PASSTHROUGH_ENTRY, 764 PASSTHROUGH_EXIT, 765 }; 766 767 // Signature of the instrumentation callback function. 768 using InstrumentationCallback = std::function<void( 769 const InstrumentationEvent event, 770 const char *package, 771 const char *version, 772 const char *interface, 773 const char *method, 774 std::vector<void *> *args)>; 775 776 explicit HidlInstrumentor(const std::string &prefix); 777 virtual ~HidlInstrumentor(); 778 779 protected: 780 // Function that lookup and dynamically loads the hidl instrumentation 781 // libraries and registers the instrumentation callback functions. 782 // 783 // The instrumentation libraries should be stored under any of the following 784 // directories: HAL_LIBRARY_PATH_SYSTEM, HAL_LIBRARY_PATH_VENDOR and 785 // HAL_LIBRARY_PATH_ODM. The name of instrumentation libraries should 786 // follow pattern: ^profilerPrefix(.*).profiler.so$ 787 // 788 // Each instrumentation library is expected to implement the instrumentation 789 // function called HIDL_INSTRUMENTATION_FUNCTION. 790 // 791 // A no-op for user build. 792 void registerInstrumentationCallbacks( 793 const std::string &profilerPrefix, 794 std::vector<InstrumentationCallback> *instrumentationCallbacks); 795 796 // Utility function to determine whether a give file is a instrumentation 797 // library (i.e. the file name follow the expected pattern). 798 bool isInstrumentationLib( 799 const std::string &profilerPrefix, 800 const dirent *file); 801 // A list of registered instrumentation callbacks. 802 std::vector<InstrumentationCallback> mInstrumentationCallbacks; 803 // Flag whether to enable instrumentation. 804 bool mEnableInstrumentation; 805}; 806 807} // namespace hardware 808} // namespace android 809 810 811#endif // ANDROID_HIDL_SUPPORT_H 812