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