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