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 #define HIDL_STRING_OPERATOR(OP)                                               \
    176     inline bool operator OP(const hidl_string &hs1, const hidl_string &hs2) {  \
    177         return strcmp(hs1.c_str(), hs2.c_str()) OP 0;                          \
    178     }                                                                          \
    179     inline bool operator OP(const hidl_string &hs, const char *s) {            \
    180         return strcmp(hs.c_str(), s) OP 0;                                     \
    181     }                                                                          \
    182     inline bool operator OP(const char *s, const hidl_string &hs) {            \
    183         return strcmp(hs.c_str(), s) OP 0;                                     \
    184     }
    185 
    186 HIDL_STRING_OPERATOR(==)
    187 HIDL_STRING_OPERATOR(!=)
    188 HIDL_STRING_OPERATOR(<)
    189 HIDL_STRING_OPERATOR(<=)
    190 HIDL_STRING_OPERATOR(>)
    191 HIDL_STRING_OPERATOR(>=)
    192 
    193 #undef HIDL_STRING_OPERATOR
    194 
    195 // Send our content to the output stream
    196 std::ostream& operator<<(std::ostream& os, const hidl_string& str);
    197 
    198 
    199 // hidl_memory is a structure that can be used to transfer
    200 // pieces of shared memory between processes. The assumption
    201 // of this object is that the memory remains accessible as
    202 // long as the file descriptors in the enclosed mHandle
    203 // - as well as all of its cross-process dups() - remain opened.
    204 struct hidl_memory {
    205 
    206     hidl_memory() : mHandle(nullptr), mSize(0), mName("") {
    207     }
    208 
    209     /**
    210      * Creates a hidl_memory object, but doesn't take ownership of
    211      * the passed in native_handle_t; callers are responsible for
    212      * making sure the handle remains valid while this object is
    213      * used.
    214      */
    215     hidl_memory(const hidl_string &name, const native_handle_t *handle, size_t size)
    216       :  mHandle(handle),
    217          mSize(size),
    218          mName(name)
    219     {}
    220 
    221     // copy constructor
    222     hidl_memory(const hidl_memory& other) {
    223         *this = other;
    224     }
    225 
    226     // copy assignment
    227     hidl_memory &operator=(const hidl_memory &other) {
    228         if (this != &other) {
    229             mHandle = other.mHandle;
    230             mSize = other.mSize;
    231             mName = other.mName;
    232         }
    233 
    234         return *this;
    235     }
    236 
    237     // move constructor
    238     hidl_memory(hidl_memory&& other) noexcept {
    239         *this = std::move(other);
    240     }
    241 
    242     // move assignment
    243     hidl_memory &operator=(hidl_memory &&other) noexcept {
    244         if (this != &other) {
    245             mHandle = std::move(other.mHandle);
    246             mSize = other.mSize;
    247             mName = std::move(other.mName);
    248             other.mSize = 0;
    249         }
    250 
    251         return *this;
    252     }
    253 
    254 
    255     ~hidl_memory() {
    256     }
    257 
    258     const native_handle_t* handle() const {
    259         return mHandle;
    260     }
    261 
    262     const hidl_string &name() const {
    263         return mName;
    264     }
    265 
    266     uint64_t size() const {
    267         return mSize;
    268     }
    269 
    270     // offsetof(hidl_memory, mHandle) exposed since mHandle is private.
    271     static const size_t kOffsetOfHandle;
    272     // offsetof(hidl_memory, mName) exposed since mHandle is private.
    273     static const size_t kOffsetOfName;
    274 
    275 private:
    276     hidl_handle mHandle __attribute__ ((aligned(8)));
    277     uint64_t mSize __attribute__ ((aligned(8)));
    278     hidl_string mName __attribute__ ((aligned(8)));
    279 };
    280 
    281 ////////////////////////////////////////////////////////////////////////////////
    282 
    283 template<typename T>
    284 struct hidl_vec {
    285     hidl_vec()
    286         : mBuffer(NULL),
    287           mSize(0),
    288           mOwnsBuffer(true) {
    289         static_assert(hidl_vec<T>::kOffsetOfBuffer == 0, "wrong offset");
    290     }
    291 
    292     hidl_vec(const hidl_vec<T> &other) : hidl_vec() {
    293         *this = other;
    294     }
    295 
    296     hidl_vec(hidl_vec<T> &&other) noexcept
    297     : mOwnsBuffer(false) {
    298         *this = std::move(other);
    299     }
    300 
    301     hidl_vec(const std::initializer_list<T> list)
    302             : mOwnsBuffer(true) {
    303         if (list.size() > UINT32_MAX) {
    304             details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
    305         }
    306         mSize = static_cast<uint32_t>(list.size());
    307         mBuffer = new T[mSize];
    308 
    309         size_t idx = 0;
    310         for (auto it = list.begin(); it != list.end(); ++it) {
    311             mBuffer[idx++] = *it;
    312         }
    313     }
    314 
    315     hidl_vec(const std::vector<T> &other) : hidl_vec() {
    316         *this = other;
    317     }
    318 
    319     template <typename InputIterator,
    320               typename = typename std::enable_if<std::is_convertible<
    321                   typename std::iterator_traits<InputIterator>::iterator_category,
    322                   std::input_iterator_tag>::value>::type>
    323     hidl_vec(InputIterator first, InputIterator last) : mOwnsBuffer(true) {
    324         auto size = std::distance(first, last);
    325         if (size > static_cast<int64_t>(UINT32_MAX)) {
    326             details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
    327         }
    328         if (size < 0) {
    329             details::logAlwaysFatal("size can't be negative.");
    330         }
    331         mSize = static_cast<uint32_t>(size);
    332         mBuffer = new T[mSize];
    333 
    334         size_t idx = 0;
    335         for (; first != last; ++first) {
    336             mBuffer[idx++] = static_cast<T>(*first);
    337         }
    338     }
    339 
    340     ~hidl_vec() {
    341         if (mOwnsBuffer) {
    342             delete[] mBuffer;
    343         }
    344         mBuffer = NULL;
    345     }
    346 
    347     // Reference an existing array, optionally taking ownership. It is the
    348     // caller's responsibility to ensure that the underlying memory stays
    349     // valid for the lifetime of this hidl_vec.
    350     void setToExternal(T *data, size_t size, bool shouldOwn = false) {
    351         if (mOwnsBuffer) {
    352             delete [] mBuffer;
    353         }
    354         mBuffer = data;
    355         if (size > UINT32_MAX) {
    356             details::logAlwaysFatal("external vector size exceeds 2^32 elements.");
    357         }
    358         mSize = static_cast<uint32_t>(size);
    359         mOwnsBuffer = shouldOwn;
    360     }
    361 
    362     T *data() {
    363         return mBuffer;
    364     }
    365 
    366     const T *data() const {
    367         return mBuffer;
    368     }
    369 
    370     T *releaseData() {
    371         if (!mOwnsBuffer && mSize > 0) {
    372             resize(mSize);
    373         }
    374         mOwnsBuffer = false;
    375         return mBuffer;
    376     }
    377 
    378     hidl_vec &operator=(hidl_vec &&other) noexcept {
    379         if (mOwnsBuffer) {
    380             delete[] mBuffer;
    381         }
    382         mBuffer = other.mBuffer;
    383         mSize = other.mSize;
    384         mOwnsBuffer = other.mOwnsBuffer;
    385         other.mOwnsBuffer = false;
    386         return *this;
    387     }
    388 
    389     hidl_vec &operator=(const hidl_vec &other) {
    390         if (this != &other) {
    391             if (mOwnsBuffer) {
    392                 delete[] mBuffer;
    393             }
    394             copyFrom(other, other.mSize);
    395         }
    396 
    397         return *this;
    398     }
    399 
    400     // copy from an std::vector.
    401     hidl_vec &operator=(const std::vector<T> &other) {
    402         if (mOwnsBuffer) {
    403             delete[] mBuffer;
    404         }
    405         copyFrom(other, other.size());
    406         return *this;
    407     }
    408 
    409     // cast to an std::vector.
    410     operator std::vector<T>() const {
    411         std::vector<T> v(mSize);
    412         for (size_t i = 0; i < mSize; ++i) {
    413             v[i] = mBuffer[i];
    414         }
    415         return v;
    416     }
    417 
    418     // equality check, assuming that T::operator== is defined.
    419     bool operator==(const hidl_vec &other) const {
    420         if (mSize != other.size()) {
    421             return false;
    422         }
    423         for (size_t i = 0; i < mSize; ++i) {
    424             if (!(mBuffer[i] == other.mBuffer[i])) {
    425                 return false;
    426             }
    427         }
    428         return true;
    429     }
    430 
    431     // inequality check, assuming that T::operator== is defined.
    432     inline bool operator!=(const hidl_vec &other) const {
    433         return !((*this) == other);
    434     }
    435 
    436     size_t size() const {
    437         return mSize;
    438     }
    439 
    440     T &operator[](size_t index) {
    441         return mBuffer[index];
    442     }
    443 
    444     const T &operator[](size_t index) const {
    445         return mBuffer[index];
    446     }
    447 
    448     void resize(size_t size) {
    449         if (size > UINT32_MAX) {
    450             details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
    451         }
    452         T *newBuffer = new T[size];
    453 
    454         for (size_t i = 0; i < std::min(static_cast<uint32_t>(size), mSize); ++i) {
    455             newBuffer[i] = mBuffer[i];
    456         }
    457 
    458         if (mOwnsBuffer) {
    459             delete[] mBuffer;
    460         }
    461         mBuffer = newBuffer;
    462 
    463         mSize = static_cast<uint32_t>(size);
    464         mOwnsBuffer = true;
    465     }
    466 
    467     // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
    468     static const size_t kOffsetOfBuffer;
    469 
    470 private:
    471     // Define std interator interface for walking the array contents
    472     template<bool is_const>
    473     class iter : public std::iterator<
    474             std::random_access_iterator_tag, /* Category */
    475             T,
    476             ptrdiff_t, /* Distance */
    477             typename std::conditional<is_const, const T *, T *>::type /* Pointer */,
    478             typename std::conditional<is_const, const T &, T &>::type /* Reference */>
    479     {
    480         using traits = std::iterator_traits<iter>;
    481         using ptr_type = typename traits::pointer;
    482         using ref_type = typename traits::reference;
    483         using diff_type = typename traits::difference_type;
    484     public:
    485         iter(ptr_type ptr) : mPtr(ptr) { }
    486         inline iter &operator++()    { mPtr++; return *this; }
    487         inline iter  operator++(int) { iter i = *this; mPtr++; return i; }
    488         inline iter &operator--()    { mPtr--; return *this; }
    489         inline iter  operator--(int) { iter i = *this; mPtr--; return i; }
    490         inline friend iter operator+(diff_type n, const iter &it) { return it.mPtr + n; }
    491         inline iter  operator+(diff_type n) const { return mPtr + n; }
    492         inline iter  operator-(diff_type n) const { return mPtr - n; }
    493         inline diff_type operator-(const iter &other) const { return mPtr - other.mPtr; }
    494         inline iter &operator+=(diff_type n) { mPtr += n; return *this; }
    495         inline iter &operator-=(diff_type n) { mPtr -= n; return *this; }
    496         inline ref_type operator*() const  { return *mPtr; }
    497         inline ptr_type operator->() const { return mPtr; }
    498         inline bool operator==(const iter &rhs) const { return mPtr == rhs.mPtr; }
    499         inline bool operator!=(const iter &rhs) const { return mPtr != rhs.mPtr; }
    500         inline bool operator< (const iter &rhs) const { return mPtr <  rhs.mPtr; }
    501         inline bool operator> (const iter &rhs) const { return mPtr >  rhs.mPtr; }
    502         inline bool operator<=(const iter &rhs) const { return mPtr <= rhs.mPtr; }
    503         inline bool operator>=(const iter &rhs) const { return mPtr >= rhs.mPtr; }
    504         inline ref_type operator[](size_t n) const { return mPtr[n]; }
    505     private:
    506         ptr_type mPtr;
    507     };
    508 public:
    509     using iterator       = iter<false /* is_const */>;
    510     using const_iterator = iter<true  /* is_const */>;
    511 
    512     iterator begin() { return data(); }
    513     iterator end() { return data()+mSize; }
    514     const_iterator begin() const { return data(); }
    515     const_iterator end() const { return data()+mSize; }
    516 
    517 private:
    518     details::hidl_pointer<T> mBuffer;
    519     uint32_t mSize;
    520     bool mOwnsBuffer;
    521 
    522     // copy from an array-like object, assuming my resources are freed.
    523     template <typename Array>
    524     void copyFrom(const Array &data, size_t size) {
    525         mSize = static_cast<uint32_t>(size);
    526         mOwnsBuffer = true;
    527         if (mSize > 0) {
    528             mBuffer = new T[size];
    529             for (size_t i = 0; i < size; ++i) {
    530                 mBuffer[i] = data[i];
    531             }
    532         } else {
    533             mBuffer = NULL;
    534         }
    535     }
    536 };
    537 
    538 template <typename T>
    539 const size_t hidl_vec<T>::kOffsetOfBuffer = offsetof(hidl_vec<T>, mBuffer);
    540 
    541 ////////////////////////////////////////////////////////////////////////////////
    542 
    543 namespace details {
    544 
    545     template<size_t SIZE1, size_t... SIZES>
    546     struct product {
    547         static constexpr size_t value = SIZE1 * product<SIZES...>::value;
    548     };
    549 
    550     template<size_t SIZE1>
    551     struct product<SIZE1> {
    552         static constexpr size_t value = SIZE1;
    553     };
    554 
    555     template<typename T, size_t SIZE1, size_t... SIZES>
    556     struct std_array {
    557         using type = std::array<typename std_array<T, SIZES...>::type, SIZE1>;
    558     };
    559 
    560     template<typename T, size_t SIZE1>
    561     struct std_array<T, SIZE1> {
    562         using type = std::array<T, SIZE1>;
    563     };
    564 
    565     template<typename T, size_t SIZE1, size_t... SIZES>
    566     struct accessor {
    567 
    568         using std_array_type = typename std_array<T, SIZE1, SIZES...>::type;
    569 
    570         explicit accessor(T *base)
    571             : mBase(base) {
    572         }
    573 
    574         accessor<T, SIZES...> operator[](size_t index) {
    575             return accessor<T, SIZES...>(
    576                     &mBase[index * product<SIZES...>::value]);
    577         }
    578 
    579         accessor &operator=(const std_array_type &other) {
    580             for (size_t i = 0; i < SIZE1; ++i) {
    581                 (*this)[i] = other[i];
    582             }
    583             return *this;
    584         }
    585 
    586     private:
    587         T *mBase;
    588     };
    589 
    590     template<typename T, size_t SIZE1>
    591     struct accessor<T, SIZE1> {
    592 
    593         using std_array_type = typename std_array<T, SIZE1>::type;
    594 
    595         explicit accessor(T *base)
    596             : mBase(base) {
    597         }
    598 
    599         T &operator[](size_t index) {
    600             return mBase[index];
    601         }
    602 
    603         accessor &operator=(const std_array_type &other) {
    604             for (size_t i = 0; i < SIZE1; ++i) {
    605                 (*this)[i] = other[i];
    606             }
    607             return *this;
    608         }
    609 
    610     private:
    611         T *mBase;
    612     };
    613 
    614     template<typename T, size_t SIZE1, size_t... SIZES>
    615     struct const_accessor {
    616 
    617         using std_array_type = typename std_array<T, SIZE1, SIZES...>::type;
    618 
    619         explicit const_accessor(const T *base)
    620             : mBase(base) {
    621         }
    622 
    623         const_accessor<T, SIZES...> operator[](size_t index) const {
    624             return const_accessor<T, SIZES...>(
    625                     &mBase[index * product<SIZES...>::value]);
    626         }
    627 
    628         operator std_array_type() {
    629             std_array_type array;
    630             for (size_t i = 0; i < SIZE1; ++i) {
    631                 array[i] = (*this)[i];
    632             }
    633             return array;
    634         }
    635 
    636     private:
    637         const T *mBase;
    638     };
    639 
    640     template<typename T, size_t SIZE1>
    641     struct const_accessor<T, SIZE1> {
    642 
    643         using std_array_type = typename std_array<T, SIZE1>::type;
    644 
    645         explicit const_accessor(const T *base)
    646             : mBase(base) {
    647         }
    648 
    649         const T &operator[](size_t index) const {
    650             return mBase[index];
    651         }
    652 
    653         operator std_array_type() {
    654             std_array_type array;
    655             for (size_t i = 0; i < SIZE1; ++i) {
    656                 array[i] = (*this)[i];
    657             }
    658             return array;
    659         }
    660 
    661     private:
    662         const T *mBase;
    663     };
    664 
    665 }  // namespace details
    666 
    667 ////////////////////////////////////////////////////////////////////////////////
    668 
    669 // A multidimensional array of T's. Assumes that T::operator=(const T &) is defined.
    670 template<typename T, size_t SIZE1, size_t... SIZES>
    671 struct hidl_array {
    672 
    673     using std_array_type = typename details::std_array<T, SIZE1, SIZES...>::type;
    674 
    675     hidl_array() = default;
    676 
    677     // Copies the data from source, using T::operator=(const T &).
    678     hidl_array(const T *source) {
    679         for (size_t i = 0; i < elementCount(); ++i) {
    680             mBuffer[i] = source[i];
    681         }
    682     }
    683 
    684     // Copies the data from the given std::array, using T::operator=(const T &).
    685     hidl_array(const std_array_type &array) {
    686         details::accessor<T, SIZE1, SIZES...> modifier(mBuffer);
    687         modifier = array;
    688     }
    689 
    690     T *data() { return mBuffer; }
    691     const T *data() const { return mBuffer; }
    692 
    693     details::accessor<T, SIZES...> operator[](size_t index) {
    694         return details::accessor<T, SIZES...>(
    695                 &mBuffer[index * details::product<SIZES...>::value]);
    696     }
    697 
    698     details::const_accessor<T, SIZES...> operator[](size_t index) const {
    699         return details::const_accessor<T, SIZES...>(
    700                 &mBuffer[index * details::product<SIZES...>::value]);
    701     }
    702 
    703     // equality check, assuming that T::operator== is defined.
    704     bool operator==(const hidl_array &other) const {
    705         for (size_t i = 0; i < elementCount(); ++i) {
    706             if (!(mBuffer[i] == other.mBuffer[i])) {
    707                 return false;
    708             }
    709         }
    710         return true;
    711     }
    712 
    713     inline bool operator!=(const hidl_array &other) const {
    714         return !((*this) == other);
    715     }
    716 
    717     using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;
    718 
    719     static constexpr size_tuple_type size() {
    720         return std::make_tuple(SIZE1, SIZES...);
    721     }
    722 
    723     static constexpr size_t elementCount() {
    724         return details::product<SIZE1, SIZES...>::value;
    725     }
    726 
    727     operator std_array_type() const {
    728         return details::const_accessor<T, SIZE1, SIZES...>(mBuffer);
    729     }
    730 
    731 private:
    732     T mBuffer[elementCount()];
    733 };
    734 
    735 // An array of T's. Assumes that T::operator=(const T &) is defined.
    736 template<typename T, size_t SIZE1>
    737 struct hidl_array<T, SIZE1> {
    738 
    739     using std_array_type = typename details::std_array<T, SIZE1>::type;
    740 
    741     hidl_array() = default;
    742 
    743     // Copies the data from source, using T::operator=(const T &).
    744     hidl_array(const T *source) {
    745         for (size_t i = 0; i < elementCount(); ++i) {
    746             mBuffer[i] = source[i];
    747         }
    748     }
    749 
    750     // Copies the data from the given std::array, using T::operator=(const T &).
    751     hidl_array(const std_array_type &array) : hidl_array(array.data()) {}
    752 
    753     T *data() { return mBuffer; }
    754     const T *data() const { return mBuffer; }
    755 
    756     T &operator[](size_t index) {
    757         return mBuffer[index];
    758     }
    759 
    760     const T &operator[](size_t index) const {
    761         return mBuffer[index];
    762     }
    763 
    764     // equality check, assuming that T::operator== is defined.
    765     bool operator==(const hidl_array &other) const {
    766         for (size_t i = 0; i < elementCount(); ++i) {
    767             if (!(mBuffer[i] == other.mBuffer[i])) {
    768                 return false;
    769             }
    770         }
    771         return true;
    772     }
    773 
    774     inline bool operator!=(const hidl_array &other) const {
    775         return !((*this) == other);
    776     }
    777 
    778     static constexpr size_t size() { return SIZE1; }
    779     static constexpr size_t elementCount() { return SIZE1; }
    780 
    781     // Copies the data to an std::array, using T::operator=(T).
    782     operator std_array_type() const {
    783         std_array_type array;
    784         for (size_t i = 0; i < SIZE1; ++i) {
    785             array[i] = mBuffer[i];
    786         }
    787         return array;
    788     }
    789 
    790 private:
    791     T mBuffer[SIZE1];
    792 };
    793 
    794 // ----------------------------------------------------------------------
    795 // Version functions
    796 struct hidl_version {
    797 public:
    798     constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {}
    799 
    800     bool operator==(const hidl_version& other) const {
    801         return (mMajor == other.get_major() && mMinor == other.get_minor());
    802     }
    803 
    804     bool operator<(const hidl_version& other) const {
    805         return (mMajor < other.get_major() ||
    806                 (mMajor == other.get_major() && mMinor < other.get_minor()));
    807     }
    808 
    809     bool operator>(const hidl_version& other) const {
    810         return other < *this;
    811     }
    812 
    813     bool operator<=(const hidl_version& other) const {
    814         return !(*this > other);
    815     }
    816 
    817     bool operator>=(const hidl_version& other) const {
    818         return !(*this < other);
    819     }
    820 
    821     constexpr uint16_t get_major() const { return mMajor; }
    822     constexpr uint16_t get_minor() const { return mMinor; }
    823 
    824 private:
    825     uint16_t mMajor;
    826     uint16_t mMinor;
    827 };
    828 
    829 inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
    830     return hidl_version(major,minor);
    831 }
    832 
    833 ///////////////////// toString functions
    834 
    835 std::string toString(const void *t);
    836 
    837 // toString alias for numeric types
    838 template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
    839 inline std::string toString(T t) {
    840     return std::to_string(t);
    841 }
    842 
    843 namespace details {
    844 
    845 template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
    846 inline std::string toHexString(T t, bool prefix = true) {
    847     std::ostringstream os;
    848     if (prefix) { os << std::showbase; }
    849     os << std::hex << t;
    850     return os.str();
    851 }
    852 
    853 template<>
    854 inline std::string toHexString(uint8_t t, bool prefix) {
    855     return toHexString(static_cast<int32_t>(t), prefix);
    856 }
    857 
    858 template<>
    859 inline std::string toHexString(int8_t t, bool prefix) {
    860     return toHexString(static_cast<int32_t>(t), prefix);
    861 }
    862 
    863 template<typename Array>
    864 std::string arrayToString(const Array &a, size_t size);
    865 
    866 template<size_t SIZE1>
    867 std::string arraySizeToString() {
    868     return std::string{"["} + toString(SIZE1) + "]";
    869 }
    870 
    871 template<size_t SIZE1, size_t SIZE2, size_t... SIZES>
    872 std::string arraySizeToString() {
    873     return std::string{"["} + toString(SIZE1) + "]" + arraySizeToString<SIZE2, SIZES...>();
    874 }
    875 
    876 template<typename T, size_t SIZE1>
    877 std::string toString(details::const_accessor<T, SIZE1> a) {
    878     return arrayToString(a, SIZE1);
    879 }
    880 
    881 template<typename Array>
    882 std::string arrayToString(const Array &a, size_t size) {
    883     using android::hardware::toString;
    884     std::string os;
    885     os += "{";
    886     for (size_t i = 0; i < size; ++i) {
    887         if (i > 0) {
    888             os += ", ";
    889         }
    890         os += toString(a[i]);
    891     }
    892     os += "}";
    893     return os;
    894 }
    895 
    896 template<typename T, size_t SIZE1, size_t SIZE2, size_t... SIZES>
    897 std::string toString(details::const_accessor<T, SIZE1, SIZE2, SIZES...> a) {
    898     return arrayToString(a, SIZE1);
    899 }
    900 
    901 }  //namespace details
    902 
    903 inline std::string toString(const void *t) {
    904     return details::toHexString(reinterpret_cast<uintptr_t>(t));
    905 }
    906 
    907 // debug string dump. There will be quotes around the string!
    908 inline std::string toString(const hidl_string &hs) {
    909     return std::string{"\""} + hs.c_str() + "\"";
    910 }
    911 
    912 // debug string dump
    913 inline std::string toString(const hidl_handle &hs) {
    914     return toString(hs.getNativeHandle());
    915 }
    916 
    917 inline std::string toString(const hidl_memory &mem) {
    918     return std::string{"memory {.name = "} + toString(mem.name()) + ", .size = "
    919               + toString(mem.size())
    920               + ", .handle = " + toString(mem.handle()) + "}";
    921 }
    922 
    923 inline std::string toString(const sp<hidl_death_recipient> &dr) {
    924     return std::string{"death_recipient@"} + toString(dr.get());
    925 }
    926 
    927 // debug string dump, assuming that toString(T) is defined.
    928 template<typename T>
    929 std::string toString(const hidl_vec<T> &a) {
    930     std::string os;
    931     os += "[" + toString(a.size()) + "]";
    932     os += details::arrayToString(a, a.size());
    933     return os;
    934 }
    935 
    936 template<typename T, size_t SIZE1>
    937 std::string toString(const hidl_array<T, SIZE1> &a) {
    938     return details::arraySizeToString<SIZE1>()
    939             + details::toString(details::const_accessor<T, SIZE1>(a.data()));
    940 }
    941 
    942 template<typename T, size_t SIZE1, size_t SIZE2, size_t... SIZES>
    943 std::string toString(const hidl_array<T, SIZE1, SIZE2, SIZES...> &a) {
    944     return details::arraySizeToString<SIZE1, SIZE2, SIZES...>()
    945             + details::toString(details::const_accessor<T, SIZE1, SIZE2, SIZES...>(a.data()));
    946 }
    947 
    948 }  // namespace hardware
    949 }  // namespace android
    950 
    951 
    952 #endif  // ANDROID_HIDL_SUPPORT_H
    953