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 
hidl_memoryhidl_memory206     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      */
hidl_memoryhidl_memory215     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
hidl_memoryhidl_memory222     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
hidl_memoryhidl_memory238     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 
~hidl_memoryhidl_memory255     ~hidl_memory() {
256     }
257 
handlehidl_memory258     const native_handle_t* handle() const {
259         return mHandle;
260     }
261 
namehidl_memory262     const hidl_string &name() const {
263         return mName;
264     }
265 
sizehidl_memory266     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 {
hidl_vechidl_vec285     hidl_vec()
286         : mBuffer(NULL),
287           mSize(0),
288           mOwnsBuffer(true) {
289         static_assert(hidl_vec<T>::kOffsetOfBuffer == 0, "wrong offset");
290     }
291 
hidl_vechidl_vec292     hidl_vec(const hidl_vec<T> &other) : hidl_vec() {
293         *this = other;
294     }
295 
hidl_vechidl_vec296     hidl_vec(hidl_vec<T> &&other) noexcept
297     : mOwnsBuffer(false) {
298         *this = std::move(other);
299     }
300 
hidl_vechidl_vec301     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 
hidl_vechidl_vec315     hidl_vec(const std::vector<T> &other) : hidl_vec() {
316         *this = other;
317     }
318 
~hidl_vechidl_vec319     ~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 
datahidl_vec341     T *data() {
342         return mBuffer;
343     }
344 
datahidl_vec345     const T *data() const {
346         return mBuffer;
347     }
348 
releaseDatahidl_vec349     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 
sizehidl_vec415     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 
resizehidl_vec427     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:
iterhidl_vec464         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 
beginhidl_vec491     iterator begin() { return data(); }
endhidl_vec492     iterator end() { return data()+mSize; }
beginhidl_vec493     const_iterator begin() const { return data(); }
endhidl_vec494     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>
copyFromhidl_vec503     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