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 <iterator> 23 #include <cutils/native_handle.h> 24 #include <hidl/HidlInternal.h> 25 #include <hidl/Status.h> 26 #include <map> 27 #include <sstream> 28 #include <stddef.h> 29 #include <tuple> 30 #include <type_traits> 31 #include <utils/Errors.h> 32 #include <utils/RefBase.h> 33 #include <utils/StrongPointer.h> 34 #include <vector> 35 36 namespace android { 37 38 // this file is included by all hidl interface, so we must forward declare the 39 // IMemory and IBase types. 40 namespace hidl { 41 namespace memory { 42 namespace V1_0 { 43 struct IMemory; 44 }; // namespace V1_0 45 }; // namespace manager 46 }; // namespace hidl 47 48 namespace hidl { 49 namespace base { 50 namespace V1_0 { 51 struct IBase; 52 }; // namespace V1_0 53 }; // namespace base 54 }; // namespace hidl 55 56 namespace hardware { 57 58 namespace details { 59 // Return true on userdebug / eng builds and false on user builds. 60 bool debuggable(); 61 } // namespace details 62 63 // hidl_death_recipient is a callback interfaced that can be used with 64 // linkToDeath() / unlinkToDeath() 65 struct hidl_death_recipient : public virtual RefBase { 66 virtual void serviceDied(uint64_t cookie, 67 const ::android::wp<::android::hidl::base::V1_0::IBase>& who) = 0; 68 }; 69 70 // hidl_handle wraps a pointer to a native_handle_t in a hidl_pointer, 71 // so that it can safely be transferred between 32-bit and 64-bit processes. 72 // The ownership semantics for this are: 73 // 1) The conversion constructor and assignment operator taking a const native_handle_t* 74 // do not take ownership of the handle; this is because these operations are usually 75 // just done for IPC, and cloning by default is a waste of resources. If you want 76 // a hidl_handle to take ownership, call setTo(handle, true /*shouldOwn*/); 77 // 2) The copy constructor/assignment operator taking a hidl_handle *DO* take ownership; 78 // that is because it's not intuitive that this class encapsulates a native_handle_t 79 // which needs cloning to be valid; in particular, this allows constructs like this: 80 // hidl_handle copy; 81 // foo->someHidlCall([&](auto incoming_handle) { 82 // copy = incoming_handle; 83 // }); 84 // // copy and its enclosed file descriptors will remain valid here. 85 // 3) The move constructor does what you would expect; it only owns the handle if the 86 // original did. 87 struct hidl_handle { 88 hidl_handle(); 89 ~hidl_handle(); 90 91 hidl_handle(const native_handle_t *handle); 92 93 // copy constructor. 94 hidl_handle(const hidl_handle &other); 95 96 // move constructor. 97 hidl_handle(hidl_handle &&other) noexcept; 98 99 // assignment operators 100 hidl_handle &operator=(const hidl_handle &other); 101 102 hidl_handle &operator=(const native_handle_t *native_handle); 103 104 hidl_handle &operator=(hidl_handle &&other) noexcept; 105 106 void setTo(native_handle_t* handle, bool shouldOwn = false); 107 108 const native_handle_t* operator->() const; 109 110 // implicit conversion to const native_handle_t* 111 operator const native_handle_t *() const; 112 113 // explicit conversion 114 const native_handle_t *getNativeHandle() const; 115 private: 116 void freeHandle(); 117 118 details::hidl_pointer<const native_handle_t> mHandle __attribute__ ((aligned(8))); 119 bool mOwnsHandle __attribute ((aligned(8))); 120 }; 121 122 struct hidl_string { 123 hidl_string(); 124 ~hidl_string(); 125 126 // copy constructor. 127 hidl_string(const hidl_string &); 128 // copy from a C-style string. nullptr will create an empty string 129 hidl_string(const char *); 130 // copy the first length characters from a C-style string. 131 hidl_string(const char *, size_t length); 132 // copy from an std::string. 133 hidl_string(const std::string &); 134 135 // move constructor. 136 hidl_string(hidl_string &&) noexcept; 137 138 const char *c_str() const; 139 size_t size() const; 140 bool empty() const; 141 142 // copy assignment operator. 143 hidl_string &operator=(const hidl_string &); 144 // copy from a C-style string. 145 hidl_string &operator=(const char *s); 146 // copy from an std::string. 147 hidl_string &operator=(const std::string &); 148 // move assignment operator. 149 hidl_string &operator=(hidl_string &&other) noexcept; 150 // cast to std::string. 151 operator std::string() const; 152 153 void clear(); 154 155 // Reference an external char array. Ownership is _not_ transferred. 156 // Caller is responsible for ensuring that underlying memory is valid 157 // for the lifetime of this hidl_string. 158 void setToExternal(const char *data, size_t size); 159 160 // offsetof(hidl_string, mBuffer) exposed since mBuffer is private. 161 static const size_t kOffsetOfBuffer; 162 163 private: 164 details::hidl_pointer<const char> mBuffer; 165 uint32_t mSize; // NOT including the terminating '\0'. 166 bool mOwnsBuffer; // if true then mBuffer is a mutable char * 167 168 // copy from data with size. Assume that my memory is freed 169 // (through clear(), for example) 170 void copyFrom(const char *data, size_t size); 171 // move from another hidl_string 172 void moveFrom(hidl_string &&); 173 }; 174 175 // Use NOLINT to suppress missing parentheses warnings around OP. 176 #define HIDL_STRING_OPERATOR(OP) \ 177 inline bool operator OP(const hidl_string& hs1, const hidl_string& hs2) { \ 178 return strcmp(hs1.c_str(), hs2.c_str()) OP 0; /* NOLINT */ \ 179 } \ 180 inline bool operator OP(const hidl_string& hs, const char* s) { \ 181 return strcmp(hs.c_str(), s) OP 0; /* NOLINT */ \ 182 } \ 183 inline bool operator OP(const char* s, const hidl_string& hs) { \ 184 return strcmp(s, hs.c_str()) OP 0; /* NOLINT */ \ 185 } 186 187 HIDL_STRING_OPERATOR(==) 188 HIDL_STRING_OPERATOR(!=) 189 HIDL_STRING_OPERATOR(<) 190 HIDL_STRING_OPERATOR(<=) 191 HIDL_STRING_OPERATOR(>) 192 HIDL_STRING_OPERATOR(>=) 193 194 #undef HIDL_STRING_OPERATOR 195 196 // Send our content to the output stream 197 std::ostream& operator<<(std::ostream& os, const hidl_string& str); 198 199 200 // hidl_memory is a structure that can be used to transfer 201 // pieces of shared memory between processes. The assumption 202 // of this object is that the memory remains accessible as 203 // long as the file descriptors in the enclosed mHandle 204 // - as well as all of its cross-process dups() - remain opened. 205 struct hidl_memory { 206 hidl_memoryhidl_memory207 hidl_memory() : mHandle(nullptr), mSize(0), mName("") { 208 } 209 210 /** 211 * Creates a hidl_memory object whose handle has the same lifetime 212 * as the handle moved into it. 213 */ hidl_memoryhidl_memory214 hidl_memory(const hidl_string& name, hidl_handle&& handle, size_t size) 215 : mHandle(std::move(handle)), mSize(size), mName(name) {} 216 217 /** 218 * Creates a hidl_memory object, but doesn't take ownership of 219 * the passed in native_handle_t; callers are responsible for 220 * making sure the handle remains valid while this object is 221 * used. 222 */ hidl_memoryhidl_memory223 hidl_memory(const hidl_string &name, const native_handle_t *handle, size_t size) 224 : mHandle(handle), 225 mSize(size), 226 mName(name) 227 {} 228 229 // copy constructor hidl_memoryhidl_memory230 hidl_memory(const hidl_memory& other) { 231 *this = other; 232 } 233 234 // copy assignment 235 hidl_memory &operator=(const hidl_memory &other) { 236 if (this != &other) { 237 mHandle = other.mHandle; 238 mSize = other.mSize; 239 mName = other.mName; 240 } 241 242 return *this; 243 } 244 245 // move constructor hidl_memoryhidl_memory246 hidl_memory(hidl_memory&& other) noexcept { 247 *this = std::move(other); 248 } 249 250 // move assignment 251 hidl_memory &operator=(hidl_memory &&other) noexcept { 252 if (this != &other) { 253 mHandle = std::move(other.mHandle); 254 mSize = other.mSize; 255 mName = std::move(other.mName); 256 other.mSize = 0; 257 } 258 259 return *this; 260 } 261 262 ~hidl_memoryhidl_memory263 ~hidl_memory() { 264 } 265 handlehidl_memory266 const native_handle_t* handle() const { 267 return mHandle; 268 } 269 namehidl_memory270 const hidl_string &name() const { 271 return mName; 272 } 273 sizehidl_memory274 uint64_t size() const { 275 return mSize; 276 } 277 278 // @return true if it's valid validhidl_memory279 inline bool valid() const { return handle() != nullptr; } 280 281 // offsetof(hidl_memory, mHandle) exposed since mHandle is private. 282 static const size_t kOffsetOfHandle; 283 // offsetof(hidl_memory, mName) exposed since mHandle is private. 284 static const size_t kOffsetOfName; 285 286 private: 287 hidl_handle mHandle __attribute__ ((aligned(8))); 288 uint64_t mSize __attribute__ ((aligned(8))); 289 hidl_string mName __attribute__ ((aligned(8))); 290 }; 291 292 // HidlMemory is a wrapper class to support sp<> for hidl_memory. It also 293 // provides factory methods to create an instance from hidl_memory or 294 // from a opened file descriptor. The number of factory methods can be increase 295 // to support other type of hidl_memory without break the ABI. 296 class HidlMemory : public virtual hidl_memory, public virtual ::android::RefBase { 297 public: 298 static sp<HidlMemory> getInstance(const hidl_memory& mem); 299 300 static sp<HidlMemory> getInstance(hidl_memory&& mem); 301 302 static sp<HidlMemory> getInstance(const hidl_string& name, hidl_handle&& handle, uint64_t size); 303 // @param fd, shall be opened and points to the resource. 304 // @note this method takes the ownership of the fd and will close it in 305 // destructor 306 // @return nullptr in failure with the fd closed 307 static sp<HidlMemory> getInstance(const hidl_string& name, int fd, uint64_t size); 308 309 virtual ~HidlMemory(); 310 311 protected: 312 HidlMemory(); 313 HidlMemory(const hidl_string& name, hidl_handle&& handle, size_t size); 314 }; 315 //////////////////////////////////////////////////////////////////////////////// 316 317 template<typename T> 318 struct hidl_vec { hidl_vechidl_vec319 hidl_vec() { 320 static_assert(hidl_vec<T>::kOffsetOfBuffer == 0, "wrong offset"); 321 322 memset(this, 0, sizeof(*this)); 323 // mSize is 0 324 // mBuffer is nullptr 325 326 // this is for consistency with the original implementation 327 mOwnsBuffer = true; 328 } 329 330 // Note, does not initialize primitive types. hidl_vechidl_vec331 hidl_vec(size_t size) : hidl_vec() { resize(size); } 332 hidl_vechidl_vec333 hidl_vec(const hidl_vec<T> &other) : hidl_vec() { 334 *this = other; 335 } 336 hidl_vechidl_vec337 hidl_vec(hidl_vec<T> &&other) noexcept : hidl_vec() { 338 *this = std::move(other); 339 } 340 hidl_vechidl_vec341 hidl_vec(const std::initializer_list<T> list) : hidl_vec() { 342 if (list.size() > UINT32_MAX) { 343 details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements."); 344 } 345 mSize = static_cast<uint32_t>(list.size()); 346 mBuffer = new T[mSize](); 347 mOwnsBuffer = true; 348 349 size_t idx = 0; 350 for (auto it = list.begin(); it != list.end(); ++it) { 351 mBuffer[idx++] = *it; 352 } 353 } 354 hidl_vechidl_vec355 hidl_vec(const std::vector<T> &other) : hidl_vec() { 356 *this = other; 357 } 358 359 template <typename InputIterator, 360 typename = typename std::enable_if<std::is_convertible< 361 typename std::iterator_traits<InputIterator>::iterator_category, 362 std::input_iterator_tag>::value>::type> hidl_vechidl_vec363 hidl_vec(InputIterator first, InputIterator last) : hidl_vec() { 364 auto size = std::distance(first, last); 365 if (size > static_cast<int64_t>(UINT32_MAX)) { 366 details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements."); 367 } 368 if (size < 0) { 369 details::logAlwaysFatal("size can't be negative."); 370 } 371 mSize = static_cast<uint32_t>(size); 372 mBuffer = new T[mSize](); 373 mOwnsBuffer = true; 374 375 size_t idx = 0; 376 for (; first != last; ++first) { 377 mBuffer[idx++] = static_cast<T>(*first); 378 } 379 } 380 ~hidl_vechidl_vec381 ~hidl_vec() { 382 if (mOwnsBuffer) { 383 delete[] mBuffer; 384 } 385 mBuffer = nullptr; 386 } 387 388 // Reference an existing array, optionally taking ownership. It is the 389 // caller's responsibility to ensure that the underlying memory stays 390 // valid for the lifetime of this hidl_vec. 391 void setToExternal(T *data, size_t size, bool shouldOwn = false) { 392 if (mOwnsBuffer) { 393 delete [] mBuffer; 394 } 395 mBuffer = data; 396 if (size > UINT32_MAX) { 397 details::logAlwaysFatal("external vector size exceeds 2^32 elements."); 398 } 399 mSize = static_cast<uint32_t>(size); 400 mOwnsBuffer = shouldOwn; 401 } 402 datahidl_vec403 T *data() { 404 return mBuffer; 405 } 406 datahidl_vec407 const T *data() const { 408 return mBuffer; 409 } 410 releaseDatahidl_vec411 T *releaseData() { 412 if (!mOwnsBuffer && mSize > 0) { 413 resize(mSize); 414 } 415 mOwnsBuffer = false; 416 return mBuffer; 417 } 418 419 hidl_vec &operator=(hidl_vec &&other) noexcept { 420 if (mOwnsBuffer) { 421 delete[] mBuffer; 422 } 423 mBuffer = other.mBuffer; 424 mSize = other.mSize; 425 mOwnsBuffer = other.mOwnsBuffer; 426 other.mOwnsBuffer = false; 427 return *this; 428 } 429 430 hidl_vec &operator=(const hidl_vec &other) { 431 if (this != &other) { 432 if (mOwnsBuffer) { 433 delete[] mBuffer; 434 } 435 copyFrom(other, other.mSize); 436 } 437 438 return *this; 439 } 440 441 // copy from an std::vector. 442 hidl_vec &operator=(const std::vector<T> &other) { 443 if (mOwnsBuffer) { 444 delete[] mBuffer; 445 } 446 copyFrom(other, other.size()); 447 return *this; 448 } 449 450 // cast to an std::vector. 451 operator std::vector<T>() const { 452 std::vector<T> v(mSize); 453 for (size_t i = 0; i < mSize; ++i) { 454 v[i] = mBuffer[i]; 455 } 456 return v; 457 } 458 459 // equality check, assuming that T::operator== is defined. 460 bool operator==(const hidl_vec &other) const { 461 if (mSize != other.size()) { 462 return false; 463 } 464 for (size_t i = 0; i < mSize; ++i) { 465 if (!(mBuffer[i] == other.mBuffer[i])) { 466 return false; 467 } 468 } 469 return true; 470 } 471 472 // inequality check, assuming that T::operator== is defined. 473 inline bool operator!=(const hidl_vec &other) const { 474 return !((*this) == other); 475 } 476 sizehidl_vec477 size_t size() const { 478 return mSize; 479 } 480 481 T &operator[](size_t index) { 482 return mBuffer[index]; 483 } 484 485 const T &operator[](size_t index) const { 486 return mBuffer[index]; 487 } 488 489 // Does not initialize primitive types if new size > old size. resizehidl_vec490 void resize(size_t size) { 491 if (size > UINT32_MAX) { 492 details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements."); 493 } 494 T* newBuffer = new T[size](); 495 496 for (size_t i = 0; i < std::min(static_cast<uint32_t>(size), mSize); ++i) { 497 newBuffer[i] = mBuffer[i]; 498 } 499 500 if (mOwnsBuffer) { 501 delete[] mBuffer; 502 } 503 mBuffer = newBuffer; 504 505 mSize = static_cast<uint32_t>(size); 506 mOwnsBuffer = true; 507 } 508 509 // offsetof(hidl_string, mBuffer) exposed since mBuffer is private. 510 static const size_t kOffsetOfBuffer; 511 512 private: 513 // Define std interator interface for walking the array contents 514 template<bool is_const> 515 class iter : public std::iterator< 516 std::random_access_iterator_tag, /* Category */ 517 T, 518 ptrdiff_t, /* Distance */ 519 typename std::conditional<is_const, const T *, T *>::type /* Pointer */, 520 typename std::conditional<is_const, const T &, T &>::type /* Reference */> 521 { 522 using traits = std::iterator_traits<iter>; 523 using ptr_type = typename traits::pointer; 524 using ref_type = typename traits::reference; 525 using diff_type = typename traits::difference_type; 526 public: iterhidl_vec527 iter(ptr_type ptr) : mPtr(ptr) { } 528 inline iter &operator++() { mPtr++; return *this; } 529 inline iter operator++(int) { iter i = *this; mPtr++; return i; } 530 inline iter &operator--() { mPtr--; return *this; } 531 inline iter operator--(int) { iter i = *this; mPtr--; return i; } 532 inline friend iter operator+(diff_type n, const iter &it) { return it.mPtr + n; } 533 inline iter operator+(diff_type n) const { return mPtr + n; } 534 inline iter operator-(diff_type n) const { return mPtr - n; } 535 inline diff_type operator-(const iter &other) const { return mPtr - other.mPtr; } 536 inline iter &operator+=(diff_type n) { mPtr += n; return *this; } 537 inline iter &operator-=(diff_type n) { mPtr -= n; return *this; } 538 inline ref_type operator*() const { return *mPtr; } 539 inline ptr_type operator->() const { return mPtr; } 540 inline bool operator==(const iter &rhs) const { return mPtr == rhs.mPtr; } 541 inline bool operator!=(const iter &rhs) const { return mPtr != rhs.mPtr; } 542 inline bool operator< (const iter &rhs) const { return mPtr < rhs.mPtr; } 543 inline bool operator> (const iter &rhs) const { return mPtr > rhs.mPtr; } 544 inline bool operator<=(const iter &rhs) const { return mPtr <= rhs.mPtr; } 545 inline bool operator>=(const iter &rhs) const { return mPtr >= rhs.mPtr; } 546 inline ref_type operator[](size_t n) const { return mPtr[n]; } 547 private: 548 ptr_type mPtr; 549 }; 550 public: 551 using iterator = iter<false /* is_const */>; 552 using const_iterator = iter<true /* is_const */>; 553 beginhidl_vec554 iterator begin() { return data(); } endhidl_vec555 iterator end() { return data()+mSize; } beginhidl_vec556 const_iterator begin() const { return data(); } endhidl_vec557 const_iterator end() const { return data()+mSize; } 558 559 private: 560 details::hidl_pointer<T> mBuffer; 561 uint32_t mSize; 562 bool mOwnsBuffer; 563 564 // copy from an array-like object, assuming my resources are freed. 565 template <typename Array> copyFromhidl_vec566 void copyFrom(const Array &data, size_t size) { 567 mSize = static_cast<uint32_t>(size); 568 mOwnsBuffer = true; 569 if (mSize > 0) { 570 mBuffer = new T[size](); 571 for (size_t i = 0; i < size; ++i) { 572 mBuffer[i] = data[i]; 573 } 574 } else { 575 mBuffer = nullptr; 576 } 577 } 578 }; 579 580 template <typename T> 581 const size_t hidl_vec<T>::kOffsetOfBuffer = offsetof(hidl_vec<T>, mBuffer); 582 583 //////////////////////////////////////////////////////////////////////////////// 584 585 namespace details { 586 587 template<size_t SIZE1, size_t... SIZES> 588 struct product { 589 static constexpr size_t value = SIZE1 * product<SIZES...>::value; 590 }; 591 592 template<size_t SIZE1> 593 struct product<SIZE1> { 594 static constexpr size_t value = SIZE1; 595 }; 596 597 template<typename T, size_t SIZE1, size_t... SIZES> 598 struct std_array { 599 using type = std::array<typename std_array<T, SIZES...>::type, SIZE1>; 600 }; 601 602 template<typename T, size_t SIZE1> 603 struct std_array<T, SIZE1> { 604 using type = std::array<T, SIZE1>; 605 }; 606 607 template<typename T, size_t SIZE1, size_t... SIZES> 608 struct accessor { 609 610 using std_array_type = typename std_array<T, SIZE1, SIZES...>::type; 611 612 explicit accessor(T *base) 613 : mBase(base) { 614 } 615 616 accessor<T, SIZES...> operator[](size_t index) { 617 return accessor<T, SIZES...>( 618 &mBase[index * product<SIZES...>::value]); 619 } 620 621 accessor &operator=(const std_array_type &other) { 622 for (size_t i = 0; i < SIZE1; ++i) { 623 (*this)[i] = other[i]; 624 } 625 return *this; 626 } 627 628 private: 629 T *mBase; 630 }; 631 632 template<typename T, size_t SIZE1> 633 struct accessor<T, SIZE1> { 634 635 using std_array_type = typename std_array<T, SIZE1>::type; 636 637 explicit accessor(T *base) 638 : mBase(base) { 639 } 640 641 T &operator[](size_t index) { 642 return mBase[index]; 643 } 644 645 accessor &operator=(const std_array_type &other) { 646 for (size_t i = 0; i < SIZE1; ++i) { 647 (*this)[i] = other[i]; 648 } 649 return *this; 650 } 651 652 private: 653 T *mBase; 654 }; 655 656 template<typename T, size_t SIZE1, size_t... SIZES> 657 struct const_accessor { 658 659 using std_array_type = typename std_array<T, SIZE1, SIZES...>::type; 660 661 explicit const_accessor(const T *base) 662 : mBase(base) { 663 } 664 665 const_accessor<T, SIZES...> operator[](size_t index) const { 666 return const_accessor<T, SIZES...>( 667 &mBase[index * product<SIZES...>::value]); 668 } 669 670 operator std_array_type() { 671 std_array_type array; 672 for (size_t i = 0; i < SIZE1; ++i) { 673 array[i] = (*this)[i]; 674 } 675 return array; 676 } 677 678 private: 679 const T *mBase; 680 }; 681 682 template<typename T, size_t SIZE1> 683 struct const_accessor<T, SIZE1> { 684 685 using std_array_type = typename std_array<T, SIZE1>::type; 686 687 explicit const_accessor(const T *base) 688 : mBase(base) { 689 } 690 691 const T &operator[](size_t index) const { 692 return mBase[index]; 693 } 694 695 operator std_array_type() { 696 std_array_type array; 697 for (size_t i = 0; i < SIZE1; ++i) { 698 array[i] = (*this)[i]; 699 } 700 return array; 701 } 702 703 private: 704 const T *mBase; 705 }; 706 707 } // namespace details 708 709 //////////////////////////////////////////////////////////////////////////////// 710 711 // A multidimensional array of T's. Assumes that T::operator=(const T &) is defined. 712 template<typename T, size_t SIZE1, size_t... SIZES> 713 struct hidl_array { 714 715 using std_array_type = typename details::std_array<T, SIZE1, SIZES...>::type; 716 717 hidl_array() = default; 718 719 // Copies the data from source, using T::operator=(const T &). 720 hidl_array(const T *source) { 721 for (size_t i = 0; i < elementCount(); ++i) { 722 mBuffer[i] = source[i]; 723 } 724 } 725 726 // Copies the data from the given std::array, using T::operator=(const T &). 727 hidl_array(const std_array_type &array) { 728 details::accessor<T, SIZE1, SIZES...> modifier(mBuffer); 729 modifier = array; 730 } 731 732 T *data() { return mBuffer; } 733 const T *data() const { return mBuffer; } 734 735 details::accessor<T, SIZES...> operator[](size_t index) { 736 return details::accessor<T, SIZES...>( 737 &mBuffer[index * details::product<SIZES...>::value]); 738 } 739 740 details::const_accessor<T, SIZES...> operator[](size_t index) const { 741 return details::const_accessor<T, SIZES...>( 742 &mBuffer[index * details::product<SIZES...>::value]); 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 using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>; 760 761 static constexpr size_tuple_type size() { 762 return std::make_tuple(SIZE1, SIZES...); 763 } 764 765 static constexpr size_t elementCount() { 766 return details::product<SIZE1, SIZES...>::value; 767 } 768 769 operator std_array_type() const { 770 return details::const_accessor<T, SIZE1, SIZES...>(mBuffer); 771 } 772 773 private: 774 T mBuffer[elementCount()]; 775 }; 776 777 // An array of T's. Assumes that T::operator=(const T &) is defined. 778 template<typename T, size_t SIZE1> 779 struct hidl_array<T, SIZE1> { 780 781 using std_array_type = typename details::std_array<T, SIZE1>::type; 782 783 hidl_array() = default; 784 785 // Copies the data from source, using T::operator=(const T &). 786 hidl_array(const T *source) { 787 for (size_t i = 0; i < elementCount(); ++i) { 788 mBuffer[i] = source[i]; 789 } 790 } 791 792 // Copies the data from the given std::array, using T::operator=(const T &). 793 hidl_array(const std_array_type &array) : hidl_array(array.data()) {} 794 795 T *data() { return mBuffer; } 796 const T *data() const { return mBuffer; } 797 798 T &operator[](size_t index) { 799 return mBuffer[index]; 800 } 801 802 const T &operator[](size_t index) const { 803 return mBuffer[index]; 804 } 805 806 // equality check, assuming that T::operator== is defined. 807 bool operator==(const hidl_array &other) const { 808 for (size_t i = 0; i < elementCount(); ++i) { 809 if (!(mBuffer[i] == other.mBuffer[i])) { 810 return false; 811 } 812 } 813 return true; 814 } 815 816 inline bool operator!=(const hidl_array &other) const { 817 return !((*this) == other); 818 } 819 820 static constexpr size_t size() { return SIZE1; } 821 static constexpr size_t elementCount() { return SIZE1; } 822 823 // Copies the data to an std::array, using T::operator=(T). 824 operator std_array_type() const { 825 std_array_type array; 826 for (size_t i = 0; i < SIZE1; ++i) { 827 array[i] = mBuffer[i]; 828 } 829 return array; 830 } 831 832 private: 833 T mBuffer[SIZE1]; 834 }; 835 836 // ---------------------------------------------------------------------- 837 // Version functions 838 struct hidl_version { 839 public: 840 constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) { 841 static_assert(sizeof(*this) == 4, "wrong size"); 842 } 843 844 bool operator==(const hidl_version& other) const { 845 return (mMajor == other.get_major() && mMinor == other.get_minor()); 846 } 847 848 bool operator<(const hidl_version& other) const { 849 return (mMajor < other.get_major() || 850 (mMajor == other.get_major() && mMinor < other.get_minor())); 851 } 852 853 bool operator>(const hidl_version& other) const { 854 return other < *this; 855 } 856 857 bool operator<=(const hidl_version& other) const { 858 return !(*this > other); 859 } 860 861 bool operator>=(const hidl_version& other) const { 862 return !(*this < other); 863 } 864 865 constexpr uint16_t get_major() const { return mMajor; } 866 constexpr uint16_t get_minor() const { return mMinor; } 867 868 private: 869 uint16_t mMajor; 870 uint16_t mMinor; 871 }; 872 873 inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) { 874 return hidl_version(major,minor); 875 } 876 877 ///////////////////// toString functions 878 879 std::string toString(const void *t); 880 881 // toString alias for numeric types 882 template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type> 883 inline std::string toString(T t) { 884 return std::to_string(t); 885 } 886 887 namespace details { 888 889 template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type> 890 inline std::string toHexString(T t, bool prefix = true) { 891 std::ostringstream os; 892 if (prefix) { os << std::showbase; } 893 os << std::hex << t; 894 return os.str(); 895 } 896 897 template<> 898 inline std::string toHexString(uint8_t t, bool prefix) { 899 return toHexString(static_cast<int32_t>(t), prefix); 900 } 901 902 template<> 903 inline std::string toHexString(int8_t t, bool prefix) { 904 return toHexString(static_cast<int32_t>(t), prefix); 905 } 906 907 template<typename Array> 908 std::string arrayToString(const Array &a, size_t size); 909 910 template<size_t SIZE1> 911 std::string arraySizeToString() { 912 return std::string{"["} + toString(SIZE1) + "]"; 913 } 914 915 template<size_t SIZE1, size_t SIZE2, size_t... SIZES> 916 std::string arraySizeToString() { 917 return std::string{"["} + toString(SIZE1) + "]" + arraySizeToString<SIZE2, SIZES...>(); 918 } 919 920 template<typename T, size_t SIZE1> 921 std::string toString(details::const_accessor<T, SIZE1> a) { 922 return arrayToString(a, SIZE1); 923 } 924 925 template<typename Array> 926 std::string arrayToString(const Array &a, size_t size) { 927 using android::hardware::toString; 928 std::string os; 929 os += "{"; 930 for (size_t i = 0; i < size; ++i) { 931 if (i > 0) { 932 os += ", "; 933 } 934 os += toString(a[i]); 935 } 936 os += "}"; 937 return os; 938 } 939 940 template<typename T, size_t SIZE1, size_t SIZE2, size_t... SIZES> 941 std::string toString(details::const_accessor<T, SIZE1, SIZE2, SIZES...> a) { 942 return arrayToString(a, SIZE1); 943 } 944 945 } //namespace details 946 947 inline std::string toString(const void *t) { 948 return details::toHexString(reinterpret_cast<uintptr_t>(t)); 949 } 950 951 // debug string dump. There will be quotes around the string! 952 inline std::string toString(const hidl_string &hs) { 953 return std::string{"\""} + hs.c_str() + "\""; 954 } 955 956 // debug string dump 957 inline std::string toString(const hidl_handle &hs) { 958 return toString(hs.getNativeHandle()); 959 } 960 961 inline std::string toString(const hidl_memory &mem) { 962 return std::string{"memory {.name = "} + toString(mem.name()) + ", .size = " 963 + toString(mem.size()) 964 + ", .handle = " + toString(mem.handle()) + "}"; 965 } 966 967 inline std::string toString(const sp<hidl_death_recipient> &dr) { 968 return std::string{"death_recipient@"} + toString(dr.get()); 969 } 970 971 // debug string dump, assuming that toString(T) is defined. 972 template<typename T> 973 std::string toString(const hidl_vec<T> &a) { 974 std::string os; 975 os += "[" + toString(a.size()) + "]"; 976 os += details::arrayToString(a, a.size()); 977 return os; 978 } 979 980 template<typename T, size_t SIZE1> 981 std::string toString(const hidl_array<T, SIZE1> &a) { 982 return details::arraySizeToString<SIZE1>() 983 + details::toString(details::const_accessor<T, SIZE1>(a.data())); 984 } 985 986 template<typename T, size_t SIZE1, size_t SIZE2, size_t... SIZES> 987 std::string toString(const hidl_array<T, SIZE1, SIZE2, SIZES...> &a) { 988 return details::arraySizeToString<SIZE1, SIZE2, SIZES...>() 989 + details::toString(details::const_accessor<T, SIZE1, SIZE2, SIZES...>(a.data())); 990 } 991 992 /** 993 * Every HIDL generated enum generates an implementation of this function. 994 * E.x.: for(const auto v : hidl_enum_iterator<Enum>) { ... } 995 */ 996 template <typename> 997 struct hidl_enum_iterator; 998 999 /** 1000 * Bitfields in HIDL are the underlying type of the enumeration. 1001 */ 1002 template <typename Enum> 1003 using hidl_bitfield = typename std::underlying_type<Enum>::type; 1004 1005 } // namespace hardware 1006 } // namespace android 1007 1008 1009 #endif // ANDROID_HIDL_SUPPORT_H 1010