• 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 <hidl/HidlInternal.h>
24 #include <map>
25 #include <sstream>
26 #include <stddef.h>
27 #include <tuple>
28 #include <type_traits>
29 #include <vector>
30 
31 // no requirements on types not used in scatter/gather
32 // no requirements on other libraries
33 #pragma clang diagnostic push
34 #pragma clang diagnostic ignored "-Wpadded"
35 #include <cutils/native_handle.h>
36 #include <hidl/Status.h>
37 #include <utils/Errors.h>
38 #include <utils/RefBase.h>
39 #include <utils/StrongPointer.h>
40 #pragma clang diagnostic pop
41 
42 namespace android {
43 
44 // this file is included by all hidl interface, so we must forward declare the
45 // IMemory and IBase types.
46 namespace hidl {
47 namespace memory {
48 namespace V1_0 {
49 
50 struct IMemory;
51 
52 }  // namespace V1_0
53 }  // namespace memory
54 }  // namespace hidl
55 
56 namespace hidl {
57 namespace base {
58 namespace V1_0 {
59 
60 struct IBase;
61 
62 }  // namespace V1_0
63 }  // namespace base
64 }  // namespace hidl
65 
66 namespace hardware {
67 
68 namespace details {
69 // Return true on userdebug / eng builds and false on user builds.
70 bool debuggable();
71 } //  namespace details
72 
73 // hidl_death_recipient is a callback interfaced that can be used with
74 // linkToDeath() / unlinkToDeath()
75 struct hidl_death_recipient : public virtual RefBase {
76     virtual void serviceDied(uint64_t cookie,
77             const ::android::wp<::android::hidl::base::V1_0::IBase>& who) = 0;
78 };
79 
80 // hidl_handle wraps a pointer to a native_handle_t in a hidl_pointer,
81 // so that it can safely be transferred between 32-bit and 64-bit processes.
82 // The ownership semantics for this are:
83 // 1) The conversion constructor and assignment operator taking a const native_handle_t*
84 //    do not take ownership of the handle; this is because these operations are usually
85 //    just done for IPC, and cloning by default is a waste of resources. If you want
86 //    a hidl_handle to take ownership, call setTo(handle, true /*shouldOwn*/);
87 // 2) The copy constructor/assignment operator taking a hidl_handle *DO* take ownership;
88 //    that is because it's not intuitive that this class encapsulates a native_handle_t
89 //    which needs cloning to be valid; in particular, this allows constructs like this:
90 //    hidl_handle copy;
91 //    foo->someHidlCall([&](auto incoming_handle) {
92 //            copy = incoming_handle;
93 //    });
94 //    // copy and its enclosed file descriptors will remain valid here.
95 // 3) The move constructor does what you would expect; it only owns the handle if the
96 //    original did.
97 struct hidl_handle {
98     hidl_handle();
99     ~hidl_handle();
100 
101     hidl_handle(const native_handle_t *handle);
102 
103     // copy constructor.
104     hidl_handle(const hidl_handle &other);
105 
106     // move constructor.
107     hidl_handle(hidl_handle &&other) noexcept;
108 
109     // assignment operators
110     hidl_handle &operator=(const hidl_handle &other);
111 
112     hidl_handle &operator=(const native_handle_t *native_handle);
113 
114     hidl_handle &operator=(hidl_handle &&other) noexcept;
115 
116     void setTo(native_handle_t* handle, bool shouldOwn = false);
117 
118     const native_handle_t* operator->() const;
119 
120     // implicit conversion to const native_handle_t*
121     operator const native_handle_t *() const;
122 
123     // explicit conversion
124     const native_handle_t *getNativeHandle() const;
125 
126     // offsetof(hidl_handle, mHandle) exposed since mHandle is private.
127     static const size_t kOffsetOfNativeHandle;
128 
129 private:
130     void freeHandle();
131 
132     details::hidl_pointer<const native_handle_t> mHandle;
133     bool mOwnsHandle;
134     uint8_t mPad[7];
135 };
136 
137 struct hidl_string {
138     hidl_string();
139     ~hidl_string();
140 
141     // copy constructor.
142     hidl_string(const hidl_string &);
143     // copy from a C-style string. nullptr will create an empty string
144     hidl_string(const char *);
145     // copy the first length characters from a C-style string.
146     hidl_string(const char *, size_t length);
147     // copy from an std::string.
148     hidl_string(const std::string &);
149 
150     // move constructor.
151     hidl_string(hidl_string &&) noexcept;
152 
153     const char *c_str() const;
154     size_t size() const;
155     bool empty() const;
156 
157     // copy assignment operator.
158     hidl_string &operator=(const hidl_string &);
159     // copy from a C-style string.
160     hidl_string &operator=(const char *s);
161     // copy from an std::string.
162     hidl_string &operator=(const std::string &);
163     // move assignment operator.
164     hidl_string &operator=(hidl_string &&other) noexcept;
165     // cast to std::string.
166     operator std::string() const;
167 
168     void clear();
169 
170     // Reference an external char array. Ownership is _not_ transferred.
171     // Caller is responsible for ensuring that underlying memory is valid
172     // for the lifetime of this hidl_string.
173     //
174     // size == strlen(data)
175     void setToExternal(const char *data, size_t size);
176 
177     // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
178     static const size_t kOffsetOfBuffer;
179 
180 private:
181     details::hidl_pointer<const char> mBuffer;
182     uint32_t mSize;  // NOT including the terminating '\0'.
183     bool mOwnsBuffer; // if true then mBuffer is a mutable char *
184     uint8_t mPad[3];
185 
186     // copy from data with size. Assume that my memory is freed
187     // (through clear(), for example)
188     void copyFrom(const char *data, size_t size);
189     // move from another hidl_string
190     void moveFrom(hidl_string &&);
191 };
192 
193 // Use NOLINT to suppress missing parentheses warnings around OP.
194 #define HIDL_STRING_OPERATOR(OP)                                              \
195     inline bool operator OP(const hidl_string& hs1, const hidl_string& hs2) { \
196         return strcmp(hs1.c_str(), hs2.c_str()) OP 0; /* NOLINT */            \
197     }                                                                         \
198     inline bool operator OP(const hidl_string& hs, const char* s) {           \
199         return strcmp(hs.c_str(), s) OP 0; /* NOLINT */                       \
200     }                                                                         \
201     inline bool operator OP(const char* s, const hidl_string& hs) {           \
202         return strcmp(s, hs.c_str()) OP 0; /* NOLINT */                       \
203     }
204 
205 HIDL_STRING_OPERATOR(==)
206 HIDL_STRING_OPERATOR(!=)
207 HIDL_STRING_OPERATOR(<)
208 HIDL_STRING_OPERATOR(<=)
209 HIDL_STRING_OPERATOR(>)
210 HIDL_STRING_OPERATOR(>=)
211 
212 #undef HIDL_STRING_OPERATOR
213 
214 // Send our content to the output stream
215 std::ostream& operator<<(std::ostream& os, const hidl_string& str);
216 
217 
218 // hidl_memory is a structure that can be used to transfer
219 // pieces of shared memory between processes. The assumption
220 // of this object is that the memory remains accessible as
221 // long as the file descriptors in the enclosed mHandle
222 // - as well as all of its cross-process dups() - remain opened.
223 struct hidl_memory {
224 
hidl_memoryhidl_memory225     hidl_memory() : mHandle(nullptr), mSize(0), mName("") {
226     }
227 
228     /**
229      * Creates a hidl_memory object whose handle has the same lifetime
230      * as the handle moved into it.
231      */
hidl_memoryhidl_memory232     hidl_memory(const hidl_string& name, hidl_handle&& handle, size_t size)
233         : mHandle(std::move(handle)), mSize(size), mName(name) {}
234 
235     /**
236      * Creates a hidl_memory object, but doesn't take ownership of
237      * the passed in native_handle_t; callers are responsible for
238      * making sure the handle remains valid while this object is
239      * used.
240      */
hidl_memoryhidl_memory241     hidl_memory(const hidl_string &name, const native_handle_t *handle, size_t size)
242       :  mHandle(handle),
243          mSize(size),
244          mName(name)
245     {}
246 
247     // copy constructor
hidl_memoryhidl_memory248     hidl_memory(const hidl_memory& other) {
249         *this = other;
250     }
251 
252     // copy assignment
253     hidl_memory &operator=(const hidl_memory &other) {
254         if (this != &other) {
255             mHandle = other.mHandle;
256             mSize = other.mSize;
257             mName = other.mName;
258         }
259 
260         return *this;
261     }
262 
263     // move constructor
hidl_memoryhidl_memory264     hidl_memory(hidl_memory&& other) noexcept {
265         *this = std::move(other);
266     }
267 
268     // move assignment
269     hidl_memory &operator=(hidl_memory &&other) noexcept {
270         if (this != &other) {
271             mHandle = std::move(other.mHandle);
272             mSize = other.mSize;
273             mName = std::move(other.mName);
274             other.mSize = 0;
275         }
276 
277         return *this;
278     }
279 
280 
~hidl_memoryhidl_memory281     ~hidl_memory() {
282     }
283 
handlehidl_memory284     const native_handle_t* handle() const {
285         return mHandle;
286     }
287 
namehidl_memory288     const hidl_string &name() const {
289         return mName;
290     }
291 
sizehidl_memory292     uint64_t size() const {
293         return mSize;
294     }
295 
296     // @return true if it's valid
validhidl_memory297     inline bool valid() const { return handle() != nullptr; }
298 
299     // offsetof(hidl_memory, mHandle) exposed since mHandle is private.
300     static const size_t kOffsetOfHandle;
301     // offsetof(hidl_memory, mName) exposed since mHandle is private.
302     static const size_t kOffsetOfName;
303 
304 private:
305     hidl_handle mHandle;
306     uint64_t mSize;
307     hidl_string mName;
308 };
309 
310 // HidlMemory is a wrapper class to support sp<> for hidl_memory. It also
311 // provides factory methods to create an instance from hidl_memory or
312 // from a opened file descriptor. The number of factory methods can be increase
313 // to support other type of hidl_memory without break the ABI.
314 class HidlMemory : public virtual hidl_memory, public virtual ::android::RefBase {
315 public:
316     static sp<HidlMemory> getInstance(const hidl_memory& mem);
317 
318     static sp<HidlMemory> getInstance(hidl_memory&& mem);
319 
320     static sp<HidlMemory> getInstance(const hidl_string& name, hidl_handle&& handle, uint64_t size);
321     // @param fd, shall be opened and points to the resource.
322     // @note this method takes the ownership of the fd and will close it in
323     //     destructor
324     // @return nullptr in failure with the fd closed
325     static sp<HidlMemory> getInstance(const hidl_string& name, int fd, uint64_t size);
326 
327     virtual ~HidlMemory();
328 
329 protected:
330     HidlMemory();
331     HidlMemory(const hidl_string& name, hidl_handle&& handle, size_t size);
332 };
333 ////////////////////////////////////////////////////////////////////////////////
334 
335 template<typename T>
336 struct hidl_vec {
337     using value_type = T;
338 
hidl_vechidl_vec339     hidl_vec() : mBuffer(nullptr), mSize(0), mOwnsBuffer(false) {
340         static_assert(hidl_vec<T>::kOffsetOfBuffer == 0, "wrong offset");
341 
342         memset(mPad, 0, sizeof(mPad));
343     }
344 
hidl_vechidl_vec345     hidl_vec(size_t size) : hidl_vec() { resize(size); }
346 
hidl_vechidl_vec347     hidl_vec(const hidl_vec<T> &other) : hidl_vec() {
348         *this = other;
349     }
350 
hidl_vechidl_vec351     hidl_vec(hidl_vec<T> &&other) noexcept : hidl_vec() {
352         *this = std::move(other);
353     }
354 
hidl_vechidl_vec355     hidl_vec(const std::initializer_list<T> list) : hidl_vec() { *this = list; }
356 
hidl_vechidl_vec357     hidl_vec(const std::vector<T> &other) : hidl_vec() {
358         *this = other;
359     }
360 
361     template <typename InputIterator,
362               typename = typename std::enable_if<std::is_convertible<
363                   typename std::iterator_traits<InputIterator>::iterator_category,
364                   std::input_iterator_tag>::value>::type>
hidl_vechidl_vec365     hidl_vec(InputIterator first, InputIterator last) : hidl_vec() {
366         auto size = std::distance(first, last);
367         if (size > static_cast<int64_t>(UINT32_MAX)) {
368             details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
369         }
370         if (size < 0) {
371             details::logAlwaysFatal("size can't be negative.");
372         }
373         mSize = static_cast<uint32_t>(size);
374         mBuffer = new T[mSize]();
375         mOwnsBuffer = true;
376 
377         size_t idx = 0;
378         for (; first != last; ++first) {
379             mBuffer[idx++] = static_cast<T>(*first);
380         }
381     }
382 
~hidl_vechidl_vec383     ~hidl_vec() {
384         if (mOwnsBuffer) {
385             delete[] mBuffer;
386         }
387         mBuffer = nullptr;
388     }
389 
390     // Reference an existing array, optionally taking ownership. It is the
391     // caller's responsibility to ensure that the underlying memory stays
392     // valid for the lifetime of this hidl_vec.
393     void setToExternal(T *data, size_t size, bool shouldOwn = false) {
394         if (mOwnsBuffer) {
395             delete [] mBuffer;
396         }
397         mBuffer = data;
398         if (size > UINT32_MAX) {
399             details::logAlwaysFatal("external vector size exceeds 2^32 elements.");
400         }
401         mSize = static_cast<uint32_t>(size);
402         mOwnsBuffer = shouldOwn;
403     }
404 
datahidl_vec405     T *data() {
406         return mBuffer;
407     }
408 
datahidl_vec409     const T *data() const {
410         return mBuffer;
411     }
412 
releaseDatahidl_vec413     T *releaseData() {
414         if (!mOwnsBuffer && mBuffer != nullptr) {
415             resize(mSize);
416         }
417         mOwnsBuffer = false;
418         return mBuffer;
419     }
420 
421     hidl_vec &operator=(hidl_vec &&other) noexcept {
422         if (mOwnsBuffer) {
423             delete[] mBuffer;
424         }
425         mBuffer = other.mBuffer;
426         mSize = other.mSize;
427         mOwnsBuffer = other.mOwnsBuffer;
428         other.mOwnsBuffer = false;
429         return *this;
430     }
431 
432     hidl_vec &operator=(const hidl_vec &other) {
433         if (this != &other) {
434             if (mOwnsBuffer) {
435                 delete[] mBuffer;
436             }
437             copyFrom(other, other.mSize);
438         }
439 
440         return *this;
441     }
442 
443     // copy from an std::vector.
444     hidl_vec &operator=(const std::vector<T> &other) {
445         if (mOwnsBuffer) {
446             delete[] mBuffer;
447         }
448         copyFrom(other, other.size());
449         return *this;
450     }
451 
452     hidl_vec& operator=(const std::initializer_list<T> list) {
453         if (list.size() > UINT32_MAX) {
454             details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
455         }
456         if (mOwnsBuffer) {
457             delete[] mBuffer;
458         }
459         mSize = static_cast<uint32_t>(list.size());
460         mBuffer = new T[mSize]();
461         mOwnsBuffer = true;
462 
463         size_t idx = 0;
464         for (auto it = list.begin(); it != list.end(); ++it) {
465             mBuffer[idx++] = *it;
466         }
467         return *this;
468     }
469 
470     // cast to an std::vector.
471     operator std::vector<T>() const {
472         std::vector<T> v(mSize);
473         for (size_t i = 0; i < mSize; ++i) {
474             v[i] = mBuffer[i];
475         }
476         return v;
477     }
478 
479     // equality check, assuming that T::operator== is defined.
480     bool operator==(const hidl_vec &other) const {
481         if (mSize != other.size()) {
482             return false;
483         }
484         for (size_t i = 0; i < mSize; ++i) {
485             if (!(mBuffer[i] == other.mBuffer[i])) {
486                 return false;
487             }
488         }
489         return true;
490     }
491 
492     // inequality check, assuming that T::operator== is defined.
493     inline bool operator!=(const hidl_vec &other) const {
494         return !((*this) == other);
495     }
496 
sizehidl_vec497     size_t size() const {
498         return mSize;
499     }
500 
501     T &operator[](size_t index) {
502         return mBuffer[index];
503     }
504 
505     const T &operator[](size_t index) const {
506         return mBuffer[index];
507     }
508 
509     // Copies over old elements fitting in new size. Value initializes the rest.
resizehidl_vec510     void resize(size_t size) {
511         if (size > UINT32_MAX) {
512             details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
513         }
514         T* newBuffer = new T[size]();
515 
516         for (size_t i = 0; i < std::min(static_cast<uint32_t>(size), mSize); ++i) {
517             newBuffer[i] = std::move(mBuffer[i]);
518         }
519 
520         if (mOwnsBuffer) {
521             delete[] mBuffer;
522         }
523         mBuffer = newBuffer;
524 
525         mSize = static_cast<uint32_t>(size);
526         mOwnsBuffer = true;
527     }
528 
529     // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
530     static const size_t kOffsetOfBuffer;
531 
532 private:
533     // Define std interator interface for walking the array contents
534     template<bool is_const>
535     class iter {
536     public:
537         using iterator_category = std::random_access_iterator_tag;
538         using value_type = T;
539         using difference_type = ptrdiff_t;
540         using pointer = std::conditional_t<is_const, const T *, T *>;
541         using reference = std::conditional_t<is_const, const T &, T &>;
iterhidl_vec542         iter(pointer ptr) : mPtr(ptr) { }
543         inline iter &operator++()    { mPtr++; return *this; }
544         inline iter  operator++(int) { iter i = *this; mPtr++; return i; }
545         inline iter &operator--()    { mPtr--; return *this; }
546         inline iter  operator--(int) { iter i = *this; mPtr--; return i; }
547         inline friend iter operator+(difference_type n, const iter &it) { return it.mPtr + n; }
548         inline iter  operator+(difference_type n) const { return mPtr + n; }
549         inline iter  operator-(difference_type n) const { return mPtr - n; }
550         inline difference_type operator-(const iter &other) const { return mPtr - other.mPtr; }
551         inline iter &operator+=(difference_type n) { mPtr += n; return *this; }
552         inline iter &operator-=(difference_type n) { mPtr -= n; return *this; }
553         inline reference operator*() const { return *mPtr; }
554         inline pointer operator->() const  { return mPtr; }
555         inline bool operator==(const iter &rhs) const { return mPtr == rhs.mPtr; }
556         inline bool operator!=(const iter &rhs) const { return mPtr != rhs.mPtr; }
557         inline bool operator< (const iter &rhs) const { return mPtr <  rhs.mPtr; }
558         inline bool operator> (const iter &rhs) const { return mPtr >  rhs.mPtr; }
559         inline bool operator<=(const iter &rhs) const { return mPtr <= rhs.mPtr; }
560         inline bool operator>=(const iter &rhs) const { return mPtr >= rhs.mPtr; }
561         inline reference operator[](size_t n) const { return mPtr[n]; }
562     private:
563         pointer mPtr;
564     };
565 public:
566     using iterator       = iter<false /* is_const */>;
567     using const_iterator = iter<true  /* is_const */>;
568 
beginhidl_vec569     iterator begin() { return data(); }
endhidl_vec570     iterator end() { return data()+mSize; }
beginhidl_vec571     const_iterator begin() const { return data(); }
endhidl_vec572     const_iterator end() const { return data()+mSize; }
findhidl_vec573     iterator find(const T& v) { return std::find(begin(), end(), v); }
findhidl_vec574     const_iterator find(const T& v) const { return std::find(begin(), end(), v); }
containshidl_vec575     bool contains(const T& v) const { return find(v) != end(); }
576 
577   private:
578     details::hidl_pointer<T> mBuffer;
579     uint32_t mSize;
580     bool mOwnsBuffer;
581     uint8_t mPad[3];
582 
583     // copy from an array-like object, assuming my resources are freed.
584     template <typename Array>
copyFromhidl_vec585     void copyFrom(const Array &data, size_t size) {
586         mSize = static_cast<uint32_t>(size);
587         mOwnsBuffer = true;
588         if (mSize > 0) {
589             mBuffer = new T[size]();
590             for (size_t i = 0; i < size; ++i) {
591                 mBuffer[i] = data[i];
592             }
593         } else {
594             mBuffer = nullptr;
595         }
596     }
597 };
598 
599 template <typename T>
600 const size_t hidl_vec<T>::kOffsetOfBuffer = offsetof(hidl_vec<T>, mBuffer);
601 
602 ////////////////////////////////////////////////////////////////////////////////
603 
604 namespace details {
605 
606     template<size_t SIZE1, size_t... SIZES>
607     struct product {
608         static constexpr size_t value = SIZE1 * product<SIZES...>::value;
609     };
610 
611     template<size_t SIZE1>
612     struct product<SIZE1> {
613         static constexpr size_t value = SIZE1;
614     };
615 
616     template<typename T, size_t SIZE1, size_t... SIZES>
617     struct std_array {
618         using type = std::array<typename std_array<T, SIZES...>::type, SIZE1>;
619     };
620 
621     template<typename T, size_t SIZE1>
622     struct std_array<T, SIZE1> {
623         using type = std::array<T, SIZE1>;
624     };
625 
626     template<typename T, size_t SIZE1, size_t... SIZES>
627     struct accessor {
628 
629         using std_array_type = typename std_array<T, SIZE1, SIZES...>::type;
630 
631         explicit accessor(T *base)
632             : mBase(base) {
633         }
634 
635         accessor<T, SIZES...> operator[](size_t index) {
636             return accessor<T, SIZES...>(
637                     &mBase[index * product<SIZES...>::value]);
638         }
639 
640         accessor &operator=(const std_array_type &other) {
641             for (size_t i = 0; i < SIZE1; ++i) {
642                 (*this)[i] = other[i];
643             }
644             return *this;
645         }
646 
647     private:
648         T *mBase;
649     };
650 
651     template<typename T, size_t SIZE1>
652     struct accessor<T, SIZE1> {
653 
654         using std_array_type = typename std_array<T, SIZE1>::type;
655 
656         explicit accessor(T *base)
657             : mBase(base) {
658         }
659 
660         T &operator[](size_t index) {
661             return mBase[index];
662         }
663 
664         accessor &operator=(const std_array_type &other) {
665             for (size_t i = 0; i < SIZE1; ++i) {
666                 (*this)[i] = other[i];
667             }
668             return *this;
669         }
670 
671     private:
672         T *mBase;
673     };
674 
675     template<typename T, size_t SIZE1, size_t... SIZES>
676     struct const_accessor {
677 
678         using std_array_type = typename std_array<T, SIZE1, SIZES...>::type;
679 
680         explicit const_accessor(const T *base)
681             : mBase(base) {
682         }
683 
684         const_accessor<T, SIZES...> operator[](size_t index) const {
685             return const_accessor<T, SIZES...>(
686                     &mBase[index * product<SIZES...>::value]);
687         }
688 
689         operator std_array_type() {
690             std_array_type array;
691             for (size_t i = 0; i < SIZE1; ++i) {
692                 array[i] = (*this)[i];
693             }
694             return array;
695         }
696 
697     private:
698         const T *mBase;
699     };
700 
701     template<typename T, size_t SIZE1>
702     struct const_accessor<T, SIZE1> {
703 
704         using std_array_type = typename std_array<T, SIZE1>::type;
705 
706         explicit const_accessor(const T *base)
707             : mBase(base) {
708         }
709 
710         const T &operator[](size_t index) const {
711             return mBase[index];
712         }
713 
714         operator std_array_type() {
715             std_array_type array;
716             for (size_t i = 0; i < SIZE1; ++i) {
717                 array[i] = (*this)[i];
718             }
719             return array;
720         }
721 
722     private:
723         const T *mBase;
724     };
725 
726 }  // namespace details
727 
728 ////////////////////////////////////////////////////////////////////////////////
729 
730 // A multidimensional array of T's. Assumes that T::operator=(const T &) is defined.
731 template<typename T, size_t SIZE1, size_t... SIZES>
732 struct hidl_array {
733 
734     using std_array_type = typename details::std_array<T, SIZE1, SIZES...>::type;
735 
736     hidl_array() = default;
737     hidl_array(const hidl_array&) noexcept = default;
738     hidl_array(hidl_array&&) noexcept = default;
739 
740     // Copies the data from source, using T::operator=(const T &).
741     hidl_array(const T *source) {
742         for (size_t i = 0; i < elementCount(); ++i) {
743             mBuffer[i] = source[i];
744         }
745     }
746 
747     // Copies the data from the given std::array, using T::operator=(const T &).
748     hidl_array(const std_array_type &array) {
749         details::accessor<T, SIZE1, SIZES...> modifier(mBuffer);
750         modifier = array;
751     }
752 
753     hidl_array& operator=(const hidl_array&) noexcept = default;
754     hidl_array& operator=(hidl_array&&) noexcept = default;
755 
756     T *data() { return mBuffer; }
757     const T *data() const { return mBuffer; }
758 
759     details::accessor<T, SIZES...> operator[](size_t index) {
760         return details::accessor<T, SIZES...>(
761                 &mBuffer[index * details::product<SIZES...>::value]);
762     }
763 
764     details::const_accessor<T, SIZES...> operator[](size_t index) const {
765         return details::const_accessor<T, SIZES...>(
766                 &mBuffer[index * details::product<SIZES...>::value]);
767     }
768 
769     // equality check, assuming that T::operator== is defined.
770     bool operator==(const hidl_array &other) const {
771         for (size_t i = 0; i < elementCount(); ++i) {
772             if (!(mBuffer[i] == other.mBuffer[i])) {
773                 return false;
774             }
775         }
776         return true;
777     }
778 
779     inline bool operator!=(const hidl_array &other) const {
780         return !((*this) == other);
781     }
782 
783     using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;
784 
785     static constexpr size_tuple_type size() {
786         return std::make_tuple(SIZE1, SIZES...);
787     }
788 
789     static constexpr size_t elementCount() {
790         return details::product<SIZE1, SIZES...>::value;
791     }
792 
793     operator std_array_type() const {
794         return details::const_accessor<T, SIZE1, SIZES...>(mBuffer);
795     }
796 
797 private:
798     T mBuffer[elementCount()];
799 };
800 
801 // An array of T's. Assumes that T::operator=(const T &) is defined.
802 template<typename T, size_t SIZE1>
803 struct hidl_array<T, SIZE1> {
804     using value_type = T;
805     using std_array_type = typename details::std_array<T, SIZE1>::type;
806 
807     hidl_array() = default;
808     hidl_array(const hidl_array&) noexcept = default;
809     hidl_array(hidl_array&&) noexcept = default;
810 
811     // Copies the data from source, using T::operator=(const T &).
812     hidl_array(const T *source) {
813         for (size_t i = 0; i < elementCount(); ++i) {
814             mBuffer[i] = source[i];
815         }
816     }
817 
818     // Copies the data from the given std::array, using T::operator=(const T &).
819     hidl_array(const std_array_type &array) : hidl_array(array.data()) {}
820 
821     hidl_array& operator=(const hidl_array&) noexcept = default;
822     hidl_array& operator=(hidl_array&&) noexcept = default;
823 
824     T *data() { return mBuffer; }
825     const T *data() const { return mBuffer; }
826 
827     T &operator[](size_t index) {
828         return mBuffer[index];
829     }
830 
831     const T &operator[](size_t index) const {
832         return mBuffer[index];
833     }
834 
835     // equality check, assuming that T::operator== is defined.
836     bool operator==(const hidl_array &other) const {
837         for (size_t i = 0; i < elementCount(); ++i) {
838             if (!(mBuffer[i] == other.mBuffer[i])) {
839                 return false;
840             }
841         }
842         return true;
843     }
844 
845     inline bool operator!=(const hidl_array &other) const {
846         return !((*this) == other);
847     }
848 
849     static constexpr size_t size() { return SIZE1; }
850     static constexpr size_t elementCount() { return SIZE1; }
851 
852     // Copies the data to an std::array, using T::operator=(T).
853     operator std_array_type() const {
854         std_array_type array;
855         for (size_t i = 0; i < SIZE1; ++i) {
856             array[i] = mBuffer[i];
857         }
858         return array;
859     }
860 
861 private:
862     T mBuffer[SIZE1];
863 };
864 
865 // ----------------------------------------------------------------------
866 // Version functions
867 struct hidl_version {
868 public:
869     constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {
870         static_assert(sizeof(*this) == 4, "wrong size");
871     }
872 
873     bool operator==(const hidl_version& other) const {
874         return (mMajor == other.get_major() && mMinor == other.get_minor());
875     }
876 
877     bool operator!=(const hidl_version& other) const {
878         return !(*this == other);
879     }
880 
881     bool operator<(const hidl_version& other) const {
882         return (mMajor < other.get_major() ||
883                 (mMajor == other.get_major() && mMinor < other.get_minor()));
884     }
885 
886     bool operator>(const hidl_version& other) const {
887         return other < *this;
888     }
889 
890     bool operator<=(const hidl_version& other) const {
891         return !(*this > other);
892     }
893 
894     bool operator>=(const hidl_version& other) const {
895         return !(*this < other);
896     }
897 
898     constexpr uint16_t get_major() const { return mMajor; }
899     constexpr uint16_t get_minor() const { return mMinor; }
900 
901 private:
902     uint16_t mMajor;
903     uint16_t mMinor;
904 };
905 
906 inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
907     return hidl_version(major,minor);
908 }
909 
910 ///////////////////// toString functions
911 
912 std::string toString(const void *t);
913 
914 // toString alias for numeric types
915 template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
916 inline std::string toString(T t) {
917     return std::to_string(t);
918 }
919 
920 namespace details {
921 
922 template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
923 inline std::string toHexString(T t, bool prefix = true) {
924     std::ostringstream os;
925     if (prefix) { os << std::showbase; }
926     os << std::hex << t;
927     return os.str();
928 }
929 
930 template<>
931 inline std::string toHexString(uint8_t t, bool prefix) {
932     return toHexString(static_cast<int32_t>(t), prefix);
933 }
934 
935 template<>
936 inline std::string toHexString(int8_t t, bool prefix) {
937     return toHexString(static_cast<int32_t>(t), prefix);
938 }
939 
940 template<typename Array>
941 std::string arrayToString(const Array &a, size_t size);
942 
943 template<size_t SIZE1>
944 std::string arraySizeToString() {
945     return std::string{"["} + toString(SIZE1) + "]";
946 }
947 
948 template<size_t SIZE1, size_t SIZE2, size_t... SIZES>
949 std::string arraySizeToString() {
950     return std::string{"["} + toString(SIZE1) + "]" + arraySizeToString<SIZE2, SIZES...>();
951 }
952 
953 template<typename T, size_t SIZE1>
954 std::string toString(details::const_accessor<T, SIZE1> a) {
955     return arrayToString(a, SIZE1);
956 }
957 
958 template<typename Array>
959 std::string arrayToString(const Array &a, size_t size) {
960     using android::hardware::toString;
961     std::string os;
962     os += "{";
963     for (size_t i = 0; i < size; ++i) {
964         if (i > 0) {
965             os += ", ";
966         }
967         os += toString(a[i]);
968     }
969     os += "}";
970     return os;
971 }
972 
973 template<typename T, size_t SIZE1, size_t SIZE2, size_t... SIZES>
974 std::string toString(details::const_accessor<T, SIZE1, SIZE2, SIZES...> a) {
975     return arrayToString(a, SIZE1);
976 }
977 
978 }  //namespace details
979 
980 inline std::string toString(const void *t) {
981     return details::toHexString(reinterpret_cast<uintptr_t>(t));
982 }
983 
984 // debug string dump. There will be quotes around the string!
985 inline std::string toString(const hidl_string &hs) {
986     return std::string{"\""} + hs.c_str() + "\"";
987 }
988 
989 // debug string dump
990 inline std::string toString(const hidl_handle &hs) {
991     return toString(hs.getNativeHandle());
992 }
993 
994 inline std::string toString(const hidl_memory &mem) {
995     return std::string{"memory {.name = "} + toString(mem.name()) + ", .size = "
996               + toString(mem.size())
997               + ", .handle = " + toString(mem.handle()) + "}";
998 }
999 
1000 inline std::string toString(const sp<hidl_death_recipient> &dr) {
1001     return std::string{"death_recipient@"} + toString(dr.get());
1002 }
1003 
1004 // debug string dump, assuming that toString(T) is defined.
1005 template<typename T>
1006 std::string toString(const hidl_vec<T> &a) {
1007     std::string os;
1008     os += "[" + toString(a.size()) + "]";
1009     os += details::arrayToString(a, a.size());
1010     return os;
1011 }
1012 
1013 template<typename T, size_t SIZE1>
1014 std::string toString(const hidl_array<T, SIZE1> &a) {
1015     return details::arraySizeToString<SIZE1>()
1016             + details::toString(details::const_accessor<T, SIZE1>(a.data()));
1017 }
1018 
1019 template<typename T, size_t SIZE1, size_t SIZE2, size_t... SIZES>
1020 std::string toString(const hidl_array<T, SIZE1, SIZE2, SIZES...> &a) {
1021     return details::arraySizeToString<SIZE1, SIZE2, SIZES...>()
1022             + details::toString(details::const_accessor<T, SIZE1, SIZE2, SIZES...>(a.data()));
1023 }
1024 
1025 namespace details {
1026 // Never instantiated. Used as a placeholder for template variables.
1027 template <typename T>
1028 struct hidl_invalid_type;
1029 
1030 // HIDL generates specializations of this for enums. See hidl_enum_range.
1031 template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
1032 constexpr hidl_invalid_type<T> hidl_enum_values;
1033 }  // namespace details
1034 
1035 /**
1036  * Every HIDL generated enum supports this function.
1037  * E.x.: for(const auto v : hidl_enum_range<Enum>) { ... }
1038  */
1039 template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
1040 struct hidl_enum_range {
1041     // Container-like associated type.
1042     using value_type = T;
1043 
1044     constexpr auto begin() const { return std::begin(details::hidl_enum_values<T>); }
1045     constexpr auto cbegin() const { return begin(); }
1046     constexpr auto rbegin() const { return std::rbegin(details::hidl_enum_values<T>); }
1047     constexpr auto crbegin() const { return rbegin(); }
1048     constexpr auto end() const { return std::end(details::hidl_enum_values<T>); }
1049     constexpr auto cend() const { return end(); }
1050     constexpr auto rend() const { return std::rend(details::hidl_enum_values<T>); }
1051     constexpr auto crend() const { return rend(); }
1052 };
1053 
1054 template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
1055 struct hidl_enum_iterator {
1056     static_assert(!std::is_enum<T>::value,
1057                   "b/78573628: hidl_enum_iterator was renamed to hidl_enum_range because it is not "
1058                   "actually an iterator. Please use that type instead.");
1059 };
1060 
1061 /**
1062  * Bitfields in HIDL are the underlying type of the enumeration.
1063  */
1064 template <typename Enum>
1065 using hidl_bitfield = typename std::underlying_type<Enum>::type;
1066 
1067 }  // namespace hardware
1068 }  // namespace android
1069 
1070 
1071 #endif  // ANDROID_HIDL_SUPPORT_H
1072