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