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