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