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