• 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 : public std::iterator<
536             std::random_access_iterator_tag, /* Category */
537             T,
538             ptrdiff_t, /* Distance */
539             typename std::conditional<is_const, const T *, T *>::type /* Pointer */,
540             typename std::conditional<is_const, const T &, T &>::type /* Reference */>
541     {
542         using traits = std::iterator_traits<iter>;
543         using ptr_type = typename traits::pointer;
544         using ref_type = typename traits::reference;
545         using diff_type = typename traits::difference_type;
546     public:
iterhidl_vec547         iter(ptr_type ptr) : mPtr(ptr) { }
548         inline iter &operator++()    { mPtr++; return *this; }
549         inline iter  operator++(int) { iter i = *this; mPtr++; return i; }
550         inline iter &operator--()    { mPtr--; return *this; }
551         inline iter  operator--(int) { iter i = *this; mPtr--; return i; }
552         inline friend iter operator+(diff_type n, const iter &it) { return it.mPtr + n; }
553         inline iter  operator+(diff_type n) const { return mPtr + n; }
554         inline iter  operator-(diff_type n) const { return mPtr - n; }
555         inline diff_type operator-(const iter &other) const { return mPtr - other.mPtr; }
556         inline iter &operator+=(diff_type n) { mPtr += n; return *this; }
557         inline iter &operator-=(diff_type n) { mPtr -= n; return *this; }
558         inline ref_type operator*() const  { return *mPtr; }
559         inline ptr_type operator->() const { return mPtr; }
560         inline bool operator==(const iter &rhs) const { return mPtr == rhs.mPtr; }
561         inline bool operator!=(const iter &rhs) const { return mPtr != rhs.mPtr; }
562         inline bool operator< (const iter &rhs) const { return mPtr <  rhs.mPtr; }
563         inline bool operator> (const iter &rhs) const { return mPtr >  rhs.mPtr; }
564         inline bool operator<=(const iter &rhs) const { return mPtr <= rhs.mPtr; }
565         inline bool operator>=(const iter &rhs) const { return mPtr >= rhs.mPtr; }
566         inline ref_type operator[](size_t n) const { return mPtr[n]; }
567     private:
568         ptr_type mPtr;
569     };
570 public:
571     using iterator       = iter<false /* is_const */>;
572     using const_iterator = iter<true  /* is_const */>;
573 
beginhidl_vec574     iterator begin() { return data(); }
endhidl_vec575     iterator end() { return data()+mSize; }
beginhidl_vec576     const_iterator begin() const { return data(); }
endhidl_vec577     const_iterator end() const { return data()+mSize; }
findhidl_vec578     iterator find(const T& v) { return std::find(begin(), end(), v); }
findhidl_vec579     const_iterator find(const T& v) const { return std::find(begin(), end(), v); }
containshidl_vec580     bool contains(const T& v) const { return find(v) != end(); }
581 
582   private:
583     details::hidl_pointer<T> mBuffer;
584     uint32_t mSize;
585     bool mOwnsBuffer;
586     uint8_t mPad[3];
587 
588     // copy from an array-like object, assuming my resources are freed.
589     template <typename Array>
copyFromhidl_vec590     void copyFrom(const Array &data, size_t size) {
591         mSize = static_cast<uint32_t>(size);
592         mOwnsBuffer = true;
593         if (mSize > 0) {
594             mBuffer = new T[size]();
595             for (size_t i = 0; i < size; ++i) {
596                 mBuffer[i] = data[i];
597             }
598         } else {
599             mBuffer = nullptr;
600         }
601     }
602 };
603 
604 template <typename T>
605 const size_t hidl_vec<T>::kOffsetOfBuffer = offsetof(hidl_vec<T>, mBuffer);
606 
607 ////////////////////////////////////////////////////////////////////////////////
608 
609 namespace details {
610 
611     template<size_t SIZE1, size_t... SIZES>
612     struct product {
613         static constexpr size_t value = SIZE1 * product<SIZES...>::value;
614     };
615 
616     template<size_t SIZE1>
617     struct product<SIZE1> {
618         static constexpr size_t value = SIZE1;
619     };
620 
621     template<typename T, size_t SIZE1, size_t... SIZES>
622     struct std_array {
623         using type = std::array<typename std_array<T, SIZES...>::type, SIZE1>;
624     };
625 
626     template<typename T, size_t SIZE1>
627     struct std_array<T, SIZE1> {
628         using type = std::array<T, SIZE1>;
629     };
630 
631     template<typename T, size_t SIZE1, size_t... SIZES>
632     struct accessor {
633 
634         using std_array_type = typename std_array<T, SIZE1, SIZES...>::type;
635 
636         explicit accessor(T *base)
637             : mBase(base) {
638         }
639 
640         accessor<T, SIZES...> operator[](size_t index) {
641             return accessor<T, SIZES...>(
642                     &mBase[index * product<SIZES...>::value]);
643         }
644 
645         accessor &operator=(const std_array_type &other) {
646             for (size_t i = 0; i < SIZE1; ++i) {
647                 (*this)[i] = other[i];
648             }
649             return *this;
650         }
651 
652     private:
653         T *mBase;
654     };
655 
656     template<typename T, size_t SIZE1>
657     struct accessor<T, SIZE1> {
658 
659         using std_array_type = typename std_array<T, SIZE1>::type;
660 
661         explicit accessor(T *base)
662             : mBase(base) {
663         }
664 
665         T &operator[](size_t index) {
666             return mBase[index];
667         }
668 
669         accessor &operator=(const std_array_type &other) {
670             for (size_t i = 0; i < SIZE1; ++i) {
671                 (*this)[i] = other[i];
672             }
673             return *this;
674         }
675 
676     private:
677         T *mBase;
678     };
679 
680     template<typename T, size_t SIZE1, size_t... SIZES>
681     struct const_accessor {
682 
683         using std_array_type = typename std_array<T, SIZE1, SIZES...>::type;
684 
685         explicit const_accessor(const T *base)
686             : mBase(base) {
687         }
688 
689         const_accessor<T, SIZES...> operator[](size_t index) const {
690             return const_accessor<T, SIZES...>(
691                     &mBase[index * product<SIZES...>::value]);
692         }
693 
694         operator std_array_type() {
695             std_array_type array;
696             for (size_t i = 0; i < SIZE1; ++i) {
697                 array[i] = (*this)[i];
698             }
699             return array;
700         }
701 
702     private:
703         const T *mBase;
704     };
705 
706     template<typename T, size_t SIZE1>
707     struct const_accessor<T, SIZE1> {
708 
709         using std_array_type = typename std_array<T, SIZE1>::type;
710 
711         explicit const_accessor(const T *base)
712             : mBase(base) {
713         }
714 
715         const T &operator[](size_t index) const {
716             return mBase[index];
717         }
718 
719         operator std_array_type() {
720             std_array_type array;
721             for (size_t i = 0; i < SIZE1; ++i) {
722                 array[i] = (*this)[i];
723             }
724             return array;
725         }
726 
727     private:
728         const T *mBase;
729     };
730 
731 }  // namespace details
732 
733 ////////////////////////////////////////////////////////////////////////////////
734 
735 // A multidimensional array of T's. Assumes that T::operator=(const T &) is defined.
736 template<typename T, size_t SIZE1, size_t... SIZES>
737 struct hidl_array {
738 
739     using std_array_type = typename details::std_array<T, SIZE1, SIZES...>::type;
740 
741     hidl_array() = default;
742     hidl_array(const hidl_array&) noexcept = default;
743     hidl_array(hidl_array&&) noexcept = default;
744 
745     // Copies the data from source, using T::operator=(const T &).
746     hidl_array(const T *source) {
747         for (size_t i = 0; i < elementCount(); ++i) {
748             mBuffer[i] = source[i];
749         }
750     }
751 
752     // Copies the data from the given std::array, using T::operator=(const T &).
753     hidl_array(const std_array_type &array) {
754         details::accessor<T, SIZE1, SIZES...> modifier(mBuffer);
755         modifier = array;
756     }
757 
758     hidl_array& operator=(const hidl_array&) noexcept = default;
759     hidl_array& operator=(hidl_array&&) noexcept = default;
760 
761     T *data() { return mBuffer; }
762     const T *data() const { return mBuffer; }
763 
764     details::accessor<T, SIZES...> operator[](size_t index) {
765         return details::accessor<T, SIZES...>(
766                 &mBuffer[index * details::product<SIZES...>::value]);
767     }
768 
769     details::const_accessor<T, SIZES...> operator[](size_t index) const {
770         return details::const_accessor<T, SIZES...>(
771                 &mBuffer[index * details::product<SIZES...>::value]);
772     }
773 
774     // equality check, assuming that T::operator== is defined.
775     bool operator==(const hidl_array &other) const {
776         for (size_t i = 0; i < elementCount(); ++i) {
777             if (!(mBuffer[i] == other.mBuffer[i])) {
778                 return false;
779             }
780         }
781         return true;
782     }
783 
784     inline bool operator!=(const hidl_array &other) const {
785         return !((*this) == other);
786     }
787 
788     using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;
789 
790     static constexpr size_tuple_type size() {
791         return std::make_tuple(SIZE1, SIZES...);
792     }
793 
794     static constexpr size_t elementCount() {
795         return details::product<SIZE1, SIZES...>::value;
796     }
797 
798     operator std_array_type() const {
799         return details::const_accessor<T, SIZE1, SIZES...>(mBuffer);
800     }
801 
802 private:
803     T mBuffer[elementCount()];
804 };
805 
806 // An array of T's. Assumes that T::operator=(const T &) is defined.
807 template<typename T, size_t SIZE1>
808 struct hidl_array<T, SIZE1> {
809     using value_type = T;
810     using std_array_type = typename details::std_array<T, SIZE1>::type;
811 
812     hidl_array() = default;
813     hidl_array(const hidl_array&) noexcept = default;
814     hidl_array(hidl_array&&) noexcept = default;
815 
816     // Copies the data from source, using T::operator=(const T &).
817     hidl_array(const T *source) {
818         for (size_t i = 0; i < elementCount(); ++i) {
819             mBuffer[i] = source[i];
820         }
821     }
822 
823     // Copies the data from the given std::array, using T::operator=(const T &).
824     hidl_array(const std_array_type &array) : hidl_array(array.data()) {}
825 
826     hidl_array& operator=(const hidl_array&) noexcept = default;
827     hidl_array& operator=(hidl_array&&) noexcept = default;
828 
829     T *data() { return mBuffer; }
830     const T *data() const { return mBuffer; }
831 
832     T &operator[](size_t index) {
833         return mBuffer[index];
834     }
835 
836     const T &operator[](size_t index) const {
837         return mBuffer[index];
838     }
839 
840     // equality check, assuming that T::operator== is defined.
841     bool operator==(const hidl_array &other) const {
842         for (size_t i = 0; i < elementCount(); ++i) {
843             if (!(mBuffer[i] == other.mBuffer[i])) {
844                 return false;
845             }
846         }
847         return true;
848     }
849 
850     inline bool operator!=(const hidl_array &other) const {
851         return !((*this) == other);
852     }
853 
854     static constexpr size_t size() { return SIZE1; }
855     static constexpr size_t elementCount() { return SIZE1; }
856 
857     // Copies the data to an std::array, using T::operator=(T).
858     operator std_array_type() const {
859         std_array_type array;
860         for (size_t i = 0; i < SIZE1; ++i) {
861             array[i] = mBuffer[i];
862         }
863         return array;
864     }
865 
866 private:
867     T mBuffer[SIZE1];
868 };
869 
870 // ----------------------------------------------------------------------
871 // Version functions
872 struct hidl_version {
873 public:
874     constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {
875         static_assert(sizeof(*this) == 4, "wrong size");
876     }
877 
878     bool operator==(const hidl_version& other) const {
879         return (mMajor == other.get_major() && mMinor == other.get_minor());
880     }
881 
882     bool operator!=(const hidl_version& other) const {
883         return !(*this == other);
884     }
885 
886     bool operator<(const hidl_version& other) const {
887         return (mMajor < other.get_major() ||
888                 (mMajor == other.get_major() && mMinor < other.get_minor()));
889     }
890 
891     bool operator>(const hidl_version& other) const {
892         return other < *this;
893     }
894 
895     bool operator<=(const hidl_version& other) const {
896         return !(*this > other);
897     }
898 
899     bool operator>=(const hidl_version& other) const {
900         return !(*this < other);
901     }
902 
903     constexpr uint16_t get_major() const { return mMajor; }
904     constexpr uint16_t get_minor() const { return mMinor; }
905 
906 private:
907     uint16_t mMajor;
908     uint16_t mMinor;
909 };
910 
911 inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
912     return hidl_version(major,minor);
913 }
914 
915 ///////////////////// toString functions
916 
917 std::string toString(const void *t);
918 
919 // toString alias for numeric types
920 template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
921 inline std::string toString(T t) {
922     return std::to_string(t);
923 }
924 
925 namespace details {
926 
927 template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
928 inline std::string toHexString(T t, bool prefix = true) {
929     std::ostringstream os;
930     if (prefix) { os << std::showbase; }
931     os << std::hex << t;
932     return os.str();
933 }
934 
935 template<>
936 inline std::string toHexString(uint8_t t, bool prefix) {
937     return toHexString(static_cast<int32_t>(t), prefix);
938 }
939 
940 template<>
941 inline std::string toHexString(int8_t t, bool prefix) {
942     return toHexString(static_cast<int32_t>(t), prefix);
943 }
944 
945 template<typename Array>
946 std::string arrayToString(const Array &a, size_t size);
947 
948 template<size_t SIZE1>
949 std::string arraySizeToString() {
950     return std::string{"["} + toString(SIZE1) + "]";
951 }
952 
953 template<size_t SIZE1, size_t SIZE2, size_t... SIZES>
954 std::string arraySizeToString() {
955     return std::string{"["} + toString(SIZE1) + "]" + arraySizeToString<SIZE2, SIZES...>();
956 }
957 
958 template<typename T, size_t SIZE1>
959 std::string toString(details::const_accessor<T, SIZE1> a) {
960     return arrayToString(a, SIZE1);
961 }
962 
963 template<typename Array>
964 std::string arrayToString(const Array &a, size_t size) {
965     using android::hardware::toString;
966     std::string os;
967     os += "{";
968     for (size_t i = 0; i < size; ++i) {
969         if (i > 0) {
970             os += ", ";
971         }
972         os += toString(a[i]);
973     }
974     os += "}";
975     return os;
976 }
977 
978 template<typename T, size_t SIZE1, size_t SIZE2, size_t... SIZES>
979 std::string toString(details::const_accessor<T, SIZE1, SIZE2, SIZES...> a) {
980     return arrayToString(a, SIZE1);
981 }
982 
983 }  //namespace details
984 
985 inline std::string toString(const void *t) {
986     return details::toHexString(reinterpret_cast<uintptr_t>(t));
987 }
988 
989 // debug string dump. There will be quotes around the string!
990 inline std::string toString(const hidl_string &hs) {
991     return std::string{"\""} + hs.c_str() + "\"";
992 }
993 
994 // debug string dump
995 inline std::string toString(const hidl_handle &hs) {
996     return toString(hs.getNativeHandle());
997 }
998 
999 inline std::string toString(const hidl_memory &mem) {
1000     return std::string{"memory {.name = "} + toString(mem.name()) + ", .size = "
1001               + toString(mem.size())
1002               + ", .handle = " + toString(mem.handle()) + "}";
1003 }
1004 
1005 inline std::string toString(const sp<hidl_death_recipient> &dr) {
1006     return std::string{"death_recipient@"} + toString(dr.get());
1007 }
1008 
1009 // debug string dump, assuming that toString(T) is defined.
1010 template<typename T>
1011 std::string toString(const hidl_vec<T> &a) {
1012     std::string os;
1013     os += "[" + toString(a.size()) + "]";
1014     os += details::arrayToString(a, a.size());
1015     return os;
1016 }
1017 
1018 template<typename T, size_t SIZE1>
1019 std::string toString(const hidl_array<T, SIZE1> &a) {
1020     return details::arraySizeToString<SIZE1>()
1021             + details::toString(details::const_accessor<T, SIZE1>(a.data()));
1022 }
1023 
1024 template<typename T, size_t SIZE1, size_t SIZE2, size_t... SIZES>
1025 std::string toString(const hidl_array<T, SIZE1, SIZE2, SIZES...> &a) {
1026     return details::arraySizeToString<SIZE1, SIZE2, SIZES...>()
1027             + details::toString(details::const_accessor<T, SIZE1, SIZE2, SIZES...>(a.data()));
1028 }
1029 
1030 namespace details {
1031 // Never instantiated. Used as a placeholder for template variables.
1032 template <typename T>
1033 struct hidl_invalid_type;
1034 
1035 // HIDL generates specializations of this for enums. See hidl_enum_range.
1036 template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
1037 constexpr hidl_invalid_type<T> hidl_enum_values;
1038 }  // namespace details
1039 
1040 /**
1041  * Every HIDL generated enum supports this function.
1042  * E.x.: for(const auto v : hidl_enum_range<Enum>) { ... }
1043  */
1044 template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
1045 struct hidl_enum_range {
1046     // Container-like associated type.
1047     using value_type = T;
1048 
1049     constexpr auto begin() const { return std::begin(details::hidl_enum_values<T>); }
1050     constexpr auto cbegin() const { return begin(); }
1051     constexpr auto rbegin() const { return std::rbegin(details::hidl_enum_values<T>); }
1052     constexpr auto crbegin() const { return rbegin(); }
1053     constexpr auto end() const { return std::end(details::hidl_enum_values<T>); }
1054     constexpr auto cend() const { return end(); }
1055     constexpr auto rend() const { return std::rend(details::hidl_enum_values<T>); }
1056     constexpr auto crend() const { return rend(); }
1057 };
1058 
1059 template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
1060 struct hidl_enum_iterator {
1061     static_assert(!std::is_enum<T>::value,
1062                   "b/78573628: hidl_enum_iterator was renamed to hidl_enum_range because it is not "
1063                   "actually an iterator. Please use that type instead.");
1064 };
1065 
1066 /**
1067  * Bitfields in HIDL are the underlying type of the enumeration.
1068  */
1069 template <typename Enum>
1070 using hidl_bitfield = typename std::underlying_type<Enum>::type;
1071 
1072 }  // namespace hardware
1073 }  // namespace android
1074 
1075 
1076 #endif  // ANDROID_HIDL_SUPPORT_H
1077