Home | History | Annotate | Download | only in hidl
      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 
    207     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      */
    214     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      */
    223     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
    230     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
    246     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 
    263     ~hidl_memory() {
    264     }
    265 
    266     const native_handle_t* handle() const {
    267         return mHandle;
    268     }
    269 
    270     const hidl_string &name() const {
    271         return mName;
    272     }
    273 
    274     uint64_t size() const {
    275         return mSize;
    276     }
    277 
    278     // @return true if it's valid
    279     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 {
    319     hidl_vec()
    320         : mBuffer(nullptr),
    321           mSize(0),
    322           mOwnsBuffer(true) {
    323         static_assert(hidl_vec<T>::kOffsetOfBuffer == 0, "wrong offset");
    324     }
    325 
    326     // Note, does not initialize primitive types.
    327     hidl_vec(size_t size) : hidl_vec() { resize(size); }
    328 
    329     hidl_vec(const hidl_vec<T> &other) : hidl_vec() {
    330         *this = other;
    331     }
    332 
    333     hidl_vec(hidl_vec<T> &&other) noexcept
    334     : mOwnsBuffer(false) {
    335         *this = std::move(other);
    336     }
    337 
    338     hidl_vec(const std::initializer_list<T> list)
    339             : mOwnsBuffer(true) {
    340         if (list.size() > UINT32_MAX) {
    341             details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
    342         }
    343         mSize = static_cast<uint32_t>(list.size());
    344         mBuffer = new T[mSize];
    345 
    346         size_t idx = 0;
    347         for (auto it = list.begin(); it != list.end(); ++it) {
    348             mBuffer[idx++] = *it;
    349         }
    350     }
    351 
    352     hidl_vec(const std::vector<T> &other) : hidl_vec() {
    353         *this = other;
    354     }
    355 
    356     template <typename InputIterator,
    357               typename = typename std::enable_if<std::is_convertible<
    358                   typename std::iterator_traits<InputIterator>::iterator_category,
    359                   std::input_iterator_tag>::value>::type>
    360     hidl_vec(InputIterator first, InputIterator last) : mOwnsBuffer(true) {
    361         auto size = std::distance(first, last);
    362         if (size > static_cast<int64_t>(UINT32_MAX)) {
    363             details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
    364         }
    365         if (size < 0) {
    366             details::logAlwaysFatal("size can't be negative.");
    367         }
    368         mSize = static_cast<uint32_t>(size);
    369         mBuffer = new T[mSize];
    370 
    371         size_t idx = 0;
    372         for (; first != last; ++first) {
    373             mBuffer[idx++] = static_cast<T>(*first);
    374         }
    375     }
    376 
    377     ~hidl_vec() {
    378         if (mOwnsBuffer) {
    379             delete[] mBuffer;
    380         }
    381         mBuffer = nullptr;
    382     }
    383 
    384     // Reference an existing array, optionally taking ownership. It is the
    385     // caller's responsibility to ensure that the underlying memory stays
    386     // valid for the lifetime of this hidl_vec.
    387     void setToExternal(T *data, size_t size, bool shouldOwn = false) {
    388         if (mOwnsBuffer) {
    389             delete [] mBuffer;
    390         }
    391         mBuffer = data;
    392         if (size > UINT32_MAX) {
    393             details::logAlwaysFatal("external vector size exceeds 2^32 elements.");
    394         }
    395         mSize = static_cast<uint32_t>(size);
    396         mOwnsBuffer = shouldOwn;
    397     }
    398 
    399     T *data() {
    400         return mBuffer;
    401     }
    402 
    403     const T *data() const {
    404         return mBuffer;
    405     }
    406 
    407     T *releaseData() {
    408         if (!mOwnsBuffer && mSize > 0) {
    409             resize(mSize);
    410         }
    411         mOwnsBuffer = false;
    412         return mBuffer;
    413     }
    414 
    415     hidl_vec &operator=(hidl_vec &&other) noexcept {
    416         if (mOwnsBuffer) {
    417             delete[] mBuffer;
    418         }
    419         mBuffer = other.mBuffer;
    420         mSize = other.mSize;
    421         mOwnsBuffer = other.mOwnsBuffer;
    422         other.mOwnsBuffer = false;
    423         return *this;
    424     }
    425 
    426     hidl_vec &operator=(const hidl_vec &other) {
    427         if (this != &other) {
    428             if (mOwnsBuffer) {
    429                 delete[] mBuffer;
    430             }
    431             copyFrom(other, other.mSize);
    432         }
    433 
    434         return *this;
    435     }
    436 
    437     // copy from an std::vector.
    438     hidl_vec &operator=(const std::vector<T> &other) {
    439         if (mOwnsBuffer) {
    440             delete[] mBuffer;
    441         }
    442         copyFrom(other, other.size());
    443         return *this;
    444     }
    445 
    446     // cast to an std::vector.
    447     operator std::vector<T>() const {
    448         std::vector<T> v(mSize);
    449         for (size_t i = 0; i < mSize; ++i) {
    450             v[i] = mBuffer[i];
    451         }
    452         return v;
    453     }
    454 
    455     // equality check, assuming that T::operator== is defined.
    456     bool operator==(const hidl_vec &other) const {
    457         if (mSize != other.size()) {
    458             return false;
    459         }
    460         for (size_t i = 0; i < mSize; ++i) {
    461             if (!(mBuffer[i] == other.mBuffer[i])) {
    462                 return false;
    463             }
    464         }
    465         return true;
    466     }
    467 
    468     // inequality check, assuming that T::operator== is defined.
    469     inline bool operator!=(const hidl_vec &other) const {
    470         return !((*this) == other);
    471     }
    472 
    473     size_t size() const {
    474         return mSize;
    475     }
    476 
    477     T &operator[](size_t index) {
    478         return mBuffer[index];
    479     }
    480 
    481     const T &operator[](size_t index) const {
    482         return mBuffer[index];
    483     }
    484 
    485     // Does not initialize primitive types if new size > old size.
    486     void resize(size_t size) {
    487         if (size > UINT32_MAX) {
    488             details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
    489         }
    490         T *newBuffer = new T[size];
    491 
    492         for (size_t i = 0; i < std::min(static_cast<uint32_t>(size), mSize); ++i) {
    493             newBuffer[i] = mBuffer[i];
    494         }
    495 
    496         if (mOwnsBuffer) {
    497             delete[] mBuffer;
    498         }
    499         mBuffer = newBuffer;
    500 
    501         mSize = static_cast<uint32_t>(size);
    502         mOwnsBuffer = true;
    503     }
    504 
    505     // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
    506     static const size_t kOffsetOfBuffer;
    507 
    508 private:
    509     // Define std interator interface for walking the array contents
    510     template<bool is_const>
    511     class iter : public std::iterator<
    512             std::random_access_iterator_tag, /* Category */
    513             T,
    514             ptrdiff_t, /* Distance */
    515             typename std::conditional<is_const, const T *, T *>::type /* Pointer */,
    516             typename std::conditional<is_const, const T &, T &>::type /* Reference */>
    517     {
    518         using traits = std::iterator_traits<iter>;
    519         using ptr_type = typename traits::pointer;
    520         using ref_type = typename traits::reference;
    521         using diff_type = typename traits::difference_type;
    522     public:
    523         iter(ptr_type ptr) : mPtr(ptr) { }
    524         inline iter &operator++()    { mPtr++; return *this; }
    525         inline iter  operator++(int) { iter i = *this; mPtr++; return i; }
    526         inline iter &operator--()    { mPtr--; return *this; }
    527         inline iter  operator--(int) { iter i = *this; mPtr--; return i; }
    528         inline friend iter operator+(diff_type n, const iter &it) { return it.mPtr + n; }
    529         inline iter  operator+(diff_type n) const { return mPtr + n; }
    530         inline iter  operator-(diff_type n) const { return mPtr - n; }
    531         inline diff_type operator-(const iter &other) const { return mPtr - other.mPtr; }
    532         inline iter &operator+=(diff_type n) { mPtr += n; return *this; }
    533         inline iter &operator-=(diff_type n) { mPtr -= n; return *this; }
    534         inline ref_type operator*() const  { return *mPtr; }
    535         inline ptr_type operator->() const { return mPtr; }
    536         inline bool operator==(const iter &rhs) const { return mPtr == rhs.mPtr; }
    537         inline bool operator!=(const iter &rhs) const { return mPtr != rhs.mPtr; }
    538         inline bool operator< (const iter &rhs) const { return mPtr <  rhs.mPtr; }
    539         inline bool operator> (const iter &rhs) const { return mPtr >  rhs.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 ref_type operator[](size_t n) const { return mPtr[n]; }
    543     private:
    544         ptr_type mPtr;
    545     };
    546 public:
    547     using iterator       = iter<false /* is_const */>;
    548     using const_iterator = iter<true  /* is_const */>;
    549 
    550     iterator begin() { return data(); }
    551     iterator end() { return data()+mSize; }
    552     const_iterator begin() const { return data(); }
    553     const_iterator end() const { return data()+mSize; }
    554 
    555 private:
    556     details::hidl_pointer<T> mBuffer;
    557     uint32_t mSize;
    558     bool mOwnsBuffer;
    559 
    560     // copy from an array-like object, assuming my resources are freed.
    561     template <typename Array>
    562     void copyFrom(const Array &data, size_t size) {
    563         mSize = static_cast<uint32_t>(size);
    564         mOwnsBuffer = true;
    565         if (mSize > 0) {
    566             mBuffer = new T[size];
    567             for (size_t i = 0; i < size; ++i) {
    568                 mBuffer[i] = data[i];
    569             }
    570         } else {
    571             mBuffer = nullptr;
    572         }
    573     }
    574 };
    575 
    576 template <typename T>
    577 const size_t hidl_vec<T>::kOffsetOfBuffer = offsetof(hidl_vec<T>, mBuffer);
    578 
    579 ////////////////////////////////////////////////////////////////////////////////
    580 
    581 namespace details {
    582 
    583     template<size_t SIZE1, size_t... SIZES>
    584     struct product {
    585         static constexpr size_t value = SIZE1 * product<SIZES...>::value;
    586     };
    587 
    588     template<size_t SIZE1>
    589     struct product<SIZE1> {
    590         static constexpr size_t value = SIZE1;
    591     };
    592 
    593     template<typename T, size_t SIZE1, size_t... SIZES>
    594     struct std_array {
    595         using type = std::array<typename std_array<T, SIZES...>::type, SIZE1>;
    596     };
    597 
    598     template<typename T, size_t SIZE1>
    599     struct std_array<T, SIZE1> {
    600         using type = std::array<T, SIZE1>;
    601     };
    602 
    603     template<typename T, size_t SIZE1, size_t... SIZES>
    604     struct accessor {
    605 
    606         using std_array_type = typename std_array<T, SIZE1, SIZES...>::type;
    607 
    608         explicit accessor(T *base)
    609             : mBase(base) {
    610         }
    611 
    612         accessor<T, SIZES...> operator[](size_t index) {
    613             return accessor<T, SIZES...>(
    614                     &mBase[index * product<SIZES...>::value]);
    615         }
    616 
    617         accessor &operator=(const std_array_type &other) {
    618             for (size_t i = 0; i < SIZE1; ++i) {
    619                 (*this)[i] = other[i];
    620             }
    621             return *this;
    622         }
    623 
    624     private:
    625         T *mBase;
    626     };
    627 
    628     template<typename T, size_t SIZE1>
    629     struct accessor<T, SIZE1> {
    630 
    631         using std_array_type = typename std_array<T, SIZE1>::type;
    632 
    633         explicit accessor(T *base)
    634             : mBase(base) {
    635         }
    636 
    637         T &operator[](size_t index) {
    638             return mBase[index];
    639         }
    640 
    641         accessor &operator=(const std_array_type &other) {
    642             for (size_t i = 0; i < SIZE1; ++i) {
    643                 (*this)[i] = other[i];
    644             }
    645             return *this;
    646         }
    647 
    648     private:
    649         T *mBase;
    650     };
    651 
    652     template<typename T, size_t SIZE1, size_t... SIZES>
    653     struct const_accessor {
    654 
    655         using std_array_type = typename std_array<T, SIZE1, SIZES...>::type;
    656 
    657         explicit const_accessor(const T *base)
    658             : mBase(base) {
    659         }
    660 
    661         const_accessor<T, SIZES...> operator[](size_t index) const {
    662             return const_accessor<T, SIZES...>(
    663                     &mBase[index * product<SIZES...>::value]);
    664         }
    665 
    666         operator std_array_type() {
    667             std_array_type array;
    668             for (size_t i = 0; i < SIZE1; ++i) {
    669                 array[i] = (*this)[i];
    670             }
    671             return array;
    672         }
    673 
    674     private:
    675         const T *mBase;
    676     };
    677 
    678     template<typename T, size_t SIZE1>
    679     struct const_accessor<T, SIZE1> {
    680 
    681         using std_array_type = typename std_array<T, SIZE1>::type;
    682 
    683         explicit const_accessor(const T *base)
    684             : mBase(base) {
    685         }
    686 
    687         const T &operator[](size_t index) const {
    688             return mBase[index];
    689         }
    690 
    691         operator std_array_type() {
    692             std_array_type array;
    693             for (size_t i = 0; i < SIZE1; ++i) {
    694                 array[i] = (*this)[i];
    695             }
    696             return array;
    697         }
    698 
    699     private:
    700         const T *mBase;
    701     };
    702 
    703 }  // namespace details
    704 
    705 ////////////////////////////////////////////////////////////////////////////////
    706 
    707 // A multidimensional array of T's. Assumes that T::operator=(const T &) is defined.
    708 template<typename T, size_t SIZE1, size_t... SIZES>
    709 struct hidl_array {
    710 
    711     using std_array_type = typename details::std_array<T, SIZE1, SIZES...>::type;
    712 
    713     hidl_array() = default;
    714 
    715     // Copies the data from source, using T::operator=(const T &).
    716     hidl_array(const T *source) {
    717         for (size_t i = 0; i < elementCount(); ++i) {
    718             mBuffer[i] = source[i];
    719         }
    720     }
    721 
    722     // Copies the data from the given std::array, using T::operator=(const T &).
    723     hidl_array(const std_array_type &array) {
    724         details::accessor<T, SIZE1, SIZES...> modifier(mBuffer);
    725         modifier = array;
    726     }
    727 
    728     T *data() { return mBuffer; }
    729     const T *data() const { return mBuffer; }
    730 
    731     details::accessor<T, SIZES...> operator[](size_t index) {
    732         return details::accessor<T, SIZES...>(
    733                 &mBuffer[index * details::product<SIZES...>::value]);
    734     }
    735 
    736     details::const_accessor<T, SIZES...> operator[](size_t index) const {
    737         return details::const_accessor<T, SIZES...>(
    738                 &mBuffer[index * details::product<SIZES...>::value]);
    739     }
    740 
    741     // equality check, assuming that T::operator== is defined.
    742     bool operator==(const hidl_array &other) const {
    743         for (size_t i = 0; i < elementCount(); ++i) {
    744             if (!(mBuffer[i] == other.mBuffer[i])) {
    745                 return false;
    746             }
    747         }
    748         return true;
    749     }
    750 
    751     inline bool operator!=(const hidl_array &other) const {
    752         return !((*this) == other);
    753     }
    754 
    755     using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;
    756 
    757     static constexpr size_tuple_type size() {
    758         return std::make_tuple(SIZE1, SIZES...);
    759     }
    760 
    761     static constexpr size_t elementCount() {
    762         return details::product<SIZE1, SIZES...>::value;
    763     }
    764 
    765     operator std_array_type() const {
    766         return details::const_accessor<T, SIZE1, SIZES...>(mBuffer);
    767     }
    768 
    769 private:
    770     T mBuffer[elementCount()];
    771 };
    772 
    773 // An array of T's. Assumes that T::operator=(const T &) is defined.
    774 template<typename T, size_t SIZE1>
    775 struct hidl_array<T, SIZE1> {
    776 
    777     using std_array_type = typename details::std_array<T, SIZE1>::type;
    778 
    779     hidl_array() = default;
    780 
    781     // Copies the data from source, using T::operator=(const T &).
    782     hidl_array(const T *source) {
    783         for (size_t i = 0; i < elementCount(); ++i) {
    784             mBuffer[i] = source[i];
    785         }
    786     }
    787 
    788     // Copies the data from the given std::array, using T::operator=(const T &).
    789     hidl_array(const std_array_type &array) : hidl_array(array.data()) {}
    790 
    791     T *data() { return mBuffer; }
    792     const T *data() const { return mBuffer; }
    793 
    794     T &operator[](size_t index) {
    795         return mBuffer[index];
    796     }
    797 
    798     const T &operator[](size_t index) const {
    799         return mBuffer[index];
    800     }
    801 
    802     // equality check, assuming that T::operator== is defined.
    803     bool operator==(const hidl_array &other) const {
    804         for (size_t i = 0; i < elementCount(); ++i) {
    805             if (!(mBuffer[i] == other.mBuffer[i])) {
    806                 return false;
    807             }
    808         }
    809         return true;
    810     }
    811 
    812     inline bool operator!=(const hidl_array &other) const {
    813         return !((*this) == other);
    814     }
    815 
    816     static constexpr size_t size() { return SIZE1; }
    817     static constexpr size_t elementCount() { return SIZE1; }
    818 
    819     // Copies the data to an std::array, using T::operator=(T).
    820     operator std_array_type() const {
    821         std_array_type array;
    822         for (size_t i = 0; i < SIZE1; ++i) {
    823             array[i] = mBuffer[i];
    824         }
    825         return array;
    826     }
    827 
    828 private:
    829     T mBuffer[SIZE1];
    830 };
    831 
    832 // ----------------------------------------------------------------------
    833 // Version functions
    834 struct hidl_version {
    835 public:
    836     constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {}
    837 
    838     bool operator==(const hidl_version& other) const {
    839         return (mMajor == other.get_major() && mMinor == other.get_minor());
    840     }
    841 
    842     bool operator<(const hidl_version& other) const {
    843         return (mMajor < other.get_major() ||
    844                 (mMajor == other.get_major() && mMinor < other.get_minor()));
    845     }
    846 
    847     bool operator>(const hidl_version& other) const {
    848         return other < *this;
    849     }
    850 
    851     bool operator<=(const hidl_version& other) const {
    852         return !(*this > other);
    853     }
    854 
    855     bool operator>=(const hidl_version& other) const {
    856         return !(*this < other);
    857     }
    858 
    859     constexpr uint16_t get_major() const { return mMajor; }
    860     constexpr uint16_t get_minor() const { return mMinor; }
    861 
    862 private:
    863     uint16_t mMajor;
    864     uint16_t mMinor;
    865 };
    866 
    867 inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
    868     return hidl_version(major,minor);
    869 }
    870 
    871 ///////////////////// toString functions
    872 
    873 std::string toString(const void *t);
    874 
    875 // toString alias for numeric types
    876 template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
    877 inline std::string toString(T t) {
    878     return std::to_string(t);
    879 }
    880 
    881 namespace details {
    882 
    883 template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
    884 inline std::string toHexString(T t, bool prefix = true) {
    885     std::ostringstream os;
    886     if (prefix) { os << std::showbase; }
    887     os << std::hex << t;
    888     return os.str();
    889 }
    890 
    891 template<>
    892 inline std::string toHexString(uint8_t t, bool prefix) {
    893     return toHexString(static_cast<int32_t>(t), prefix);
    894 }
    895 
    896 template<>
    897 inline std::string toHexString(int8_t t, bool prefix) {
    898     return toHexString(static_cast<int32_t>(t), prefix);
    899 }
    900 
    901 template<typename Array>
    902 std::string arrayToString(const Array &a, size_t size);
    903 
    904 template<size_t SIZE1>
    905 std::string arraySizeToString() {
    906     return std::string{"["} + toString(SIZE1) + "]";
    907 }
    908 
    909 template<size_t SIZE1, size_t SIZE2, size_t... SIZES>
    910 std::string arraySizeToString() {
    911     return std::string{"["} + toString(SIZE1) + "]" + arraySizeToString<SIZE2, SIZES...>();
    912 }
    913 
    914 template<typename T, size_t SIZE1>
    915 std::string toString(details::const_accessor<T, SIZE1> a) {
    916     return arrayToString(a, SIZE1);
    917 }
    918 
    919 template<typename Array>
    920 std::string arrayToString(const Array &a, size_t size) {
    921     using android::hardware::toString;
    922     std::string os;
    923     os += "{";
    924     for (size_t i = 0; i < size; ++i) {
    925         if (i > 0) {
    926             os += ", ";
    927         }
    928         os += toString(a[i]);
    929     }
    930     os += "}";
    931     return os;
    932 }
    933 
    934 template<typename T, size_t SIZE1, size_t SIZE2, size_t... SIZES>
    935 std::string toString(details::const_accessor<T, SIZE1, SIZE2, SIZES...> a) {
    936     return arrayToString(a, SIZE1);
    937 }
    938 
    939 }  //namespace details
    940 
    941 inline std::string toString(const void *t) {
    942     return details::toHexString(reinterpret_cast<uintptr_t>(t));
    943 }
    944 
    945 // debug string dump. There will be quotes around the string!
    946 inline std::string toString(const hidl_string &hs) {
    947     return std::string{"\""} + hs.c_str() + "\"";
    948 }
    949 
    950 // debug string dump
    951 inline std::string toString(const hidl_handle &hs) {
    952     return toString(hs.getNativeHandle());
    953 }
    954 
    955 inline std::string toString(const hidl_memory &mem) {
    956     return std::string{"memory {.name = "} + toString(mem.name()) + ", .size = "
    957               + toString(mem.size())
    958               + ", .handle = " + toString(mem.handle()) + "}";
    959 }
    960 
    961 inline std::string toString(const sp<hidl_death_recipient> &dr) {
    962     return std::string{"death_recipient@"} + toString(dr.get());
    963 }
    964 
    965 // debug string dump, assuming that toString(T) is defined.
    966 template<typename T>
    967 std::string toString(const hidl_vec<T> &a) {
    968     std::string os;
    969     os += "[" + toString(a.size()) + "]";
    970     os += details::arrayToString(a, a.size());
    971     return os;
    972 }
    973 
    974 template<typename T, size_t SIZE1>
    975 std::string toString(const hidl_array<T, SIZE1> &a) {
    976     return details::arraySizeToString<SIZE1>()
    977             + details::toString(details::const_accessor<T, SIZE1>(a.data()));
    978 }
    979 
    980 template<typename T, size_t SIZE1, size_t SIZE2, size_t... SIZES>
    981 std::string toString(const hidl_array<T, SIZE1, SIZE2, SIZES...> &a) {
    982     return details::arraySizeToString<SIZE1, SIZE2, SIZES...>()
    983             + details::toString(details::const_accessor<T, SIZE1, SIZE2, SIZES...>(a.data()));
    984 }
    985 
    986 /**
    987  * Every HIDL generated enum generates an implementation of this function.
    988  * E.x.: for(const auto v : hidl_enum_iterator<Enum>) { ... }
    989  */
    990 template <typename>
    991 struct hidl_enum_iterator;
    992 
    993 /**
    994  * Bitfields in HIDL are the underlying type of the enumeration.
    995  */
    996 template <typename Enum>
    997 using hidl_bitfield = typename std::underlying_type<Enum>::type;
    998 
    999 }  // namespace hardware
   1000 }  // namespace android
   1001 
   1002 
   1003 #endif  // ANDROID_HIDL_SUPPORT_H
   1004