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