• 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 // Use NOLINT to suppress missing parentheses warnings around OP.
176 #define HIDL_STRING_OPERATOR(OP)                                              \
177     inline bool operator OP(const hidl_string& hs1, const hidl_string& hs2) { \
178         return strcmp(hs1.c_str(), hs2.c_str()) OP 0; /* NOLINT */            \
179     }                                                                         \
180     inline bool operator OP(const hidl_string& hs, const char* s) {           \
181         return strcmp(hs.c_str(), s) OP 0; /* NOLINT */                       \
182     }                                                                         \
183     inline bool operator OP(const char* s, const hidl_string& hs) {           \
184         return strcmp(s, hs.c_str()) OP 0; /* NOLINT */                       \
185     }
186 
187 HIDL_STRING_OPERATOR(==)
188 HIDL_STRING_OPERATOR(!=)
189 HIDL_STRING_OPERATOR(<)
190 HIDL_STRING_OPERATOR(<=)
191 HIDL_STRING_OPERATOR(>)
192 HIDL_STRING_OPERATOR(>=)
193 
194 #undef HIDL_STRING_OPERATOR
195 
196 // Send our content to the output stream
197 std::ostream& operator<<(std::ostream& os, const hidl_string& str);
198 
199 
200 // hidl_memory is a structure that can be used to transfer
201 // pieces of shared memory between processes. The assumption
202 // of this object is that the memory remains accessible as
203 // long as the file descriptors in the enclosed mHandle
204 // - as well as all of its cross-process dups() - remain opened.
205 struct hidl_memory {
206 
hidl_memoryhidl_memory207     hidl_memory() : mHandle(nullptr), mSize(0), mName("") {
208     }
209 
210     /**
211      * Creates a hidl_memory object whose handle has the same lifetime
212      * as the handle moved into it.
213      */
hidl_memoryhidl_memory214     hidl_memory(const hidl_string& name, hidl_handle&& handle, size_t size)
215         : mHandle(std::move(handle)), mSize(size), mName(name) {}
216 
217     /**
218      * Creates a hidl_memory object, but doesn't take ownership of
219      * the passed in native_handle_t; callers are responsible for
220      * making sure the handle remains valid while this object is
221      * used.
222      */
hidl_memoryhidl_memory223     hidl_memory(const hidl_string &name, const native_handle_t *handle, size_t size)
224       :  mHandle(handle),
225          mSize(size),
226          mName(name)
227     {}
228 
229     // copy constructor
hidl_memoryhidl_memory230     hidl_memory(const hidl_memory& other) {
231         *this = other;
232     }
233 
234     // copy assignment
235     hidl_memory &operator=(const hidl_memory &other) {
236         if (this != &other) {
237             mHandle = other.mHandle;
238             mSize = other.mSize;
239             mName = other.mName;
240         }
241 
242         return *this;
243     }
244 
245     // move constructor
hidl_memoryhidl_memory246     hidl_memory(hidl_memory&& other) noexcept {
247         *this = std::move(other);
248     }
249 
250     // move assignment
251     hidl_memory &operator=(hidl_memory &&other) noexcept {
252         if (this != &other) {
253             mHandle = std::move(other.mHandle);
254             mSize = other.mSize;
255             mName = std::move(other.mName);
256             other.mSize = 0;
257         }
258 
259         return *this;
260     }
261 
262 
~hidl_memoryhidl_memory263     ~hidl_memory() {
264     }
265 
handlehidl_memory266     const native_handle_t* handle() const {
267         return mHandle;
268     }
269 
namehidl_memory270     const hidl_string &name() const {
271         return mName;
272     }
273 
sizehidl_memory274     uint64_t size() const {
275         return mSize;
276     }
277 
278     // @return true if it's valid
validhidl_memory279     inline bool valid() const { return handle() != nullptr; }
280 
281     // offsetof(hidl_memory, mHandle) exposed since mHandle is private.
282     static const size_t kOffsetOfHandle;
283     // offsetof(hidl_memory, mName) exposed since mHandle is private.
284     static const size_t kOffsetOfName;
285 
286 private:
287     hidl_handle mHandle __attribute__ ((aligned(8)));
288     uint64_t mSize __attribute__ ((aligned(8)));
289     hidl_string mName __attribute__ ((aligned(8)));
290 };
291 
292 // HidlMemory is a wrapper class to support sp<> for hidl_memory. It also
293 // provides factory methods to create an instance from hidl_memory or
294 // from a opened file descriptor. The number of factory methods can be increase
295 // to support other type of hidl_memory without break the ABI.
296 class HidlMemory : public virtual hidl_memory, public virtual ::android::RefBase {
297 public:
298     static sp<HidlMemory> getInstance(const hidl_memory& mem);
299 
300     static sp<HidlMemory> getInstance(hidl_memory&& mem);
301 
302     static sp<HidlMemory> getInstance(const hidl_string& name, hidl_handle&& handle, uint64_t size);
303     // @param fd, shall be opened and points to the resource.
304     // @note this method takes the ownership of the fd and will close it in
305     //     destructor
306     // @return nullptr in failure with the fd closed
307     static sp<HidlMemory> getInstance(const hidl_string& name, int fd, uint64_t size);
308 
309     virtual ~HidlMemory();
310 
311 protected:
312     HidlMemory();
313     HidlMemory(const hidl_string& name, hidl_handle&& handle, size_t size);
314 };
315 ////////////////////////////////////////////////////////////////////////////////
316 
317 template<typename T>
318 struct hidl_vec {
hidl_vechidl_vec319     hidl_vec() {
320         static_assert(hidl_vec<T>::kOffsetOfBuffer == 0, "wrong offset");
321 
322         memset(this, 0, sizeof(*this));
323         // mSize is 0
324         // mBuffer is nullptr
325 
326         // this is for consistency with the original implementation
327         mOwnsBuffer = true;
328     }
329 
330     // Note, does not initialize primitive types.
hidl_vechidl_vec331     hidl_vec(size_t size) : hidl_vec() { resize(size); }
332 
hidl_vechidl_vec333     hidl_vec(const hidl_vec<T> &other) : hidl_vec() {
334         *this = other;
335     }
336 
hidl_vechidl_vec337     hidl_vec(hidl_vec<T> &&other) noexcept : hidl_vec() {
338         *this = std::move(other);
339     }
340 
hidl_vechidl_vec341     hidl_vec(const std::initializer_list<T> list) : hidl_vec() {
342         if (list.size() > UINT32_MAX) {
343             details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
344         }
345         mSize = static_cast<uint32_t>(list.size());
346         mBuffer = new T[mSize]();
347         mOwnsBuffer = true;
348 
349         size_t idx = 0;
350         for (auto it = list.begin(); it != list.end(); ++it) {
351             mBuffer[idx++] = *it;
352         }
353     }
354 
hidl_vechidl_vec355     hidl_vec(const std::vector<T> &other) : hidl_vec() {
356         *this = other;
357     }
358 
359     template <typename InputIterator,
360               typename = typename std::enable_if<std::is_convertible<
361                   typename std::iterator_traits<InputIterator>::iterator_category,
362                   std::input_iterator_tag>::value>::type>
hidl_vechidl_vec363     hidl_vec(InputIterator first, InputIterator last) : hidl_vec() {
364         auto size = std::distance(first, last);
365         if (size > static_cast<int64_t>(UINT32_MAX)) {
366             details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
367         }
368         if (size < 0) {
369             details::logAlwaysFatal("size can't be negative.");
370         }
371         mSize = static_cast<uint32_t>(size);
372         mBuffer = new T[mSize]();
373         mOwnsBuffer = true;
374 
375         size_t idx = 0;
376         for (; first != last; ++first) {
377             mBuffer[idx++] = static_cast<T>(*first);
378         }
379     }
380 
~hidl_vechidl_vec381     ~hidl_vec() {
382         if (mOwnsBuffer) {
383             delete[] mBuffer;
384         }
385         mBuffer = nullptr;
386     }
387 
388     // Reference an existing array, optionally taking ownership. It is the
389     // caller's responsibility to ensure that the underlying memory stays
390     // valid for the lifetime of this hidl_vec.
391     void setToExternal(T *data, size_t size, bool shouldOwn = false) {
392         if (mOwnsBuffer) {
393             delete [] mBuffer;
394         }
395         mBuffer = data;
396         if (size > UINT32_MAX) {
397             details::logAlwaysFatal("external vector size exceeds 2^32 elements.");
398         }
399         mSize = static_cast<uint32_t>(size);
400         mOwnsBuffer = shouldOwn;
401     }
402 
datahidl_vec403     T *data() {
404         return mBuffer;
405     }
406 
datahidl_vec407     const T *data() const {
408         return mBuffer;
409     }
410 
releaseDatahidl_vec411     T *releaseData() {
412         if (!mOwnsBuffer && mSize > 0) {
413             resize(mSize);
414         }
415         mOwnsBuffer = false;
416         return mBuffer;
417     }
418 
419     hidl_vec &operator=(hidl_vec &&other) noexcept {
420         if (mOwnsBuffer) {
421             delete[] mBuffer;
422         }
423         mBuffer = other.mBuffer;
424         mSize = other.mSize;
425         mOwnsBuffer = other.mOwnsBuffer;
426         other.mOwnsBuffer = false;
427         return *this;
428     }
429 
430     hidl_vec &operator=(const hidl_vec &other) {
431         if (this != &other) {
432             if (mOwnsBuffer) {
433                 delete[] mBuffer;
434             }
435             copyFrom(other, other.mSize);
436         }
437 
438         return *this;
439     }
440 
441     // copy from an std::vector.
442     hidl_vec &operator=(const std::vector<T> &other) {
443         if (mOwnsBuffer) {
444             delete[] mBuffer;
445         }
446         copyFrom(other, other.size());
447         return *this;
448     }
449 
450     // cast to an std::vector.
451     operator std::vector<T>() const {
452         std::vector<T> v(mSize);
453         for (size_t i = 0; i < mSize; ++i) {
454             v[i] = mBuffer[i];
455         }
456         return v;
457     }
458 
459     // equality check, assuming that T::operator== is defined.
460     bool operator==(const hidl_vec &other) const {
461         if (mSize != other.size()) {
462             return false;
463         }
464         for (size_t i = 0; i < mSize; ++i) {
465             if (!(mBuffer[i] == other.mBuffer[i])) {
466                 return false;
467             }
468         }
469         return true;
470     }
471 
472     // inequality check, assuming that T::operator== is defined.
473     inline bool operator!=(const hidl_vec &other) const {
474         return !((*this) == other);
475     }
476 
sizehidl_vec477     size_t size() const {
478         return mSize;
479     }
480 
481     T &operator[](size_t index) {
482         return mBuffer[index];
483     }
484 
485     const T &operator[](size_t index) const {
486         return mBuffer[index];
487     }
488 
489     // Does not initialize primitive types if new size > old size.
resizehidl_vec490     void resize(size_t size) {
491         if (size > UINT32_MAX) {
492             details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
493         }
494         T* newBuffer = new T[size]();
495 
496         for (size_t i = 0; i < std::min(static_cast<uint32_t>(size), mSize); ++i) {
497             newBuffer[i] = mBuffer[i];
498         }
499 
500         if (mOwnsBuffer) {
501             delete[] mBuffer;
502         }
503         mBuffer = newBuffer;
504 
505         mSize = static_cast<uint32_t>(size);
506         mOwnsBuffer = true;
507     }
508 
509     // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
510     static const size_t kOffsetOfBuffer;
511 
512 private:
513     // Define std interator interface for walking the array contents
514     template<bool is_const>
515     class iter : public std::iterator<
516             std::random_access_iterator_tag, /* Category */
517             T,
518             ptrdiff_t, /* Distance */
519             typename std::conditional<is_const, const T *, T *>::type /* Pointer */,
520             typename std::conditional<is_const, const T &, T &>::type /* Reference */>
521     {
522         using traits = std::iterator_traits<iter>;
523         using ptr_type = typename traits::pointer;
524         using ref_type = typename traits::reference;
525         using diff_type = typename traits::difference_type;
526     public:
iterhidl_vec527         iter(ptr_type ptr) : mPtr(ptr) { }
528         inline iter &operator++()    { mPtr++; return *this; }
529         inline iter  operator++(int) { iter i = *this; mPtr++; return i; }
530         inline iter &operator--()    { mPtr--; return *this; }
531         inline iter  operator--(int) { iter i = *this; mPtr--; return i; }
532         inline friend iter operator+(diff_type n, const iter &it) { return it.mPtr + n; }
533         inline iter  operator+(diff_type n) const { return mPtr + n; }
534         inline iter  operator-(diff_type n) const { return mPtr - n; }
535         inline diff_type operator-(const iter &other) const { return mPtr - other.mPtr; }
536         inline iter &operator+=(diff_type n) { mPtr += n; return *this; }
537         inline iter &operator-=(diff_type n) { mPtr -= n; return *this; }
538         inline ref_type operator*() const  { return *mPtr; }
539         inline ptr_type operator->() const { return mPtr; }
540         inline bool operator==(const iter &rhs) const { return mPtr == rhs.mPtr; }
541         inline bool operator!=(const iter &rhs) const { return mPtr != rhs.mPtr; }
542         inline bool operator< (const iter &rhs) const { return mPtr <  rhs.mPtr; }
543         inline bool operator> (const iter &rhs) const { return mPtr >  rhs.mPtr; }
544         inline bool operator<=(const iter &rhs) const { return mPtr <= rhs.mPtr; }
545         inline bool operator>=(const iter &rhs) const { return mPtr >= rhs.mPtr; }
546         inline ref_type operator[](size_t n) const { return mPtr[n]; }
547     private:
548         ptr_type mPtr;
549     };
550 public:
551     using iterator       = iter<false /* is_const */>;
552     using const_iterator = iter<true  /* is_const */>;
553 
beginhidl_vec554     iterator begin() { return data(); }
endhidl_vec555     iterator end() { return data()+mSize; }
beginhidl_vec556     const_iterator begin() const { return data(); }
endhidl_vec557     const_iterator end() const { return data()+mSize; }
558 
559 private:
560     details::hidl_pointer<T> mBuffer;
561     uint32_t mSize;
562     bool mOwnsBuffer;
563 
564     // copy from an array-like object, assuming my resources are freed.
565     template <typename Array>
copyFromhidl_vec566     void copyFrom(const Array &data, size_t size) {
567         mSize = static_cast<uint32_t>(size);
568         mOwnsBuffer = true;
569         if (mSize > 0) {
570             mBuffer = new T[size]();
571             for (size_t i = 0; i < size; ++i) {
572                 mBuffer[i] = data[i];
573             }
574         } else {
575             mBuffer = nullptr;
576         }
577     }
578 };
579 
580 template <typename T>
581 const size_t hidl_vec<T>::kOffsetOfBuffer = offsetof(hidl_vec<T>, mBuffer);
582 
583 ////////////////////////////////////////////////////////////////////////////////
584 
585 namespace details {
586 
587     template<size_t SIZE1, size_t... SIZES>
588     struct product {
589         static constexpr size_t value = SIZE1 * product<SIZES...>::value;
590     };
591 
592     template<size_t SIZE1>
593     struct product<SIZE1> {
594         static constexpr size_t value = SIZE1;
595     };
596 
597     template<typename T, size_t SIZE1, size_t... SIZES>
598     struct std_array {
599         using type = std::array<typename std_array<T, SIZES...>::type, SIZE1>;
600     };
601 
602     template<typename T, size_t SIZE1>
603     struct std_array<T, SIZE1> {
604         using type = std::array<T, SIZE1>;
605     };
606 
607     template<typename T, size_t SIZE1, size_t... SIZES>
608     struct accessor {
609 
610         using std_array_type = typename std_array<T, SIZE1, SIZES...>::type;
611 
612         explicit accessor(T *base)
613             : mBase(base) {
614         }
615 
616         accessor<T, SIZES...> operator[](size_t index) {
617             return accessor<T, SIZES...>(
618                     &mBase[index * product<SIZES...>::value]);
619         }
620 
621         accessor &operator=(const std_array_type &other) {
622             for (size_t i = 0; i < SIZE1; ++i) {
623                 (*this)[i] = other[i];
624             }
625             return *this;
626         }
627 
628     private:
629         T *mBase;
630     };
631 
632     template<typename T, size_t SIZE1>
633     struct accessor<T, SIZE1> {
634 
635         using std_array_type = typename std_array<T, SIZE1>::type;
636 
637         explicit accessor(T *base)
638             : mBase(base) {
639         }
640 
641         T &operator[](size_t index) {
642             return mBase[index];
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, size_t... SIZES>
657     struct const_accessor {
658 
659         using std_array_type = typename std_array<T, SIZE1, SIZES...>::type;
660 
661         explicit const_accessor(const T *base)
662             : mBase(base) {
663         }
664 
665         const_accessor<T, SIZES...> operator[](size_t index) const {
666             return const_accessor<T, SIZES...>(
667                     &mBase[index * product<SIZES...>::value]);
668         }
669 
670         operator std_array_type() {
671             std_array_type array;
672             for (size_t i = 0; i < SIZE1; ++i) {
673                 array[i] = (*this)[i];
674             }
675             return array;
676         }
677 
678     private:
679         const T *mBase;
680     };
681 
682     template<typename T, size_t SIZE1>
683     struct const_accessor<T, SIZE1> {
684 
685         using std_array_type = typename std_array<T, SIZE1>::type;
686 
687         explicit const_accessor(const T *base)
688             : mBase(base) {
689         }
690 
691         const T &operator[](size_t index) const {
692             return mBase[index];
693         }
694 
695         operator std_array_type() {
696             std_array_type array;
697             for (size_t i = 0; i < SIZE1; ++i) {
698                 array[i] = (*this)[i];
699             }
700             return array;
701         }
702 
703     private:
704         const T *mBase;
705     };
706 
707 }  // namespace details
708 
709 ////////////////////////////////////////////////////////////////////////////////
710 
711 // A multidimensional array of T's. Assumes that T::operator=(const T &) is defined.
712 template<typename T, size_t SIZE1, size_t... SIZES>
713 struct hidl_array {
714 
715     using std_array_type = typename details::std_array<T, SIZE1, SIZES...>::type;
716 
717     hidl_array() = default;
718 
719     // Copies the data from source, using T::operator=(const T &).
720     hidl_array(const T *source) {
721         for (size_t i = 0; i < elementCount(); ++i) {
722             mBuffer[i] = source[i];
723         }
724     }
725 
726     // Copies the data from the given std::array, using T::operator=(const T &).
727     hidl_array(const std_array_type &array) {
728         details::accessor<T, SIZE1, SIZES...> modifier(mBuffer);
729         modifier = array;
730     }
731 
732     T *data() { return mBuffer; }
733     const T *data() const { return mBuffer; }
734 
735     details::accessor<T, SIZES...> operator[](size_t index) {
736         return details::accessor<T, SIZES...>(
737                 &mBuffer[index * details::product<SIZES...>::value]);
738     }
739 
740     details::const_accessor<T, SIZES...> operator[](size_t index) const {
741         return details::const_accessor<T, SIZES...>(
742                 &mBuffer[index * details::product<SIZES...>::value]);
743     }
744 
745     // equality check, assuming that T::operator== is defined.
746     bool operator==(const hidl_array &other) const {
747         for (size_t i = 0; i < elementCount(); ++i) {
748             if (!(mBuffer[i] == other.mBuffer[i])) {
749                 return false;
750             }
751         }
752         return true;
753     }
754 
755     inline bool operator!=(const hidl_array &other) const {
756         return !((*this) == other);
757     }
758 
759     using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;
760 
761     static constexpr size_tuple_type size() {
762         return std::make_tuple(SIZE1, SIZES...);
763     }
764 
765     static constexpr size_t elementCount() {
766         return details::product<SIZE1, SIZES...>::value;
767     }
768 
769     operator std_array_type() const {
770         return details::const_accessor<T, SIZE1, SIZES...>(mBuffer);
771     }
772 
773 private:
774     T mBuffer[elementCount()];
775 };
776 
777 // An array of T's. Assumes that T::operator=(const T &) is defined.
778 template<typename T, size_t SIZE1>
779 struct hidl_array<T, SIZE1> {
780 
781     using std_array_type = typename details::std_array<T, SIZE1>::type;
782 
783     hidl_array() = default;
784 
785     // Copies the data from source, using T::operator=(const T &).
786     hidl_array(const T *source) {
787         for (size_t i = 0; i < elementCount(); ++i) {
788             mBuffer[i] = source[i];
789         }
790     }
791 
792     // Copies the data from the given std::array, using T::operator=(const T &).
793     hidl_array(const std_array_type &array) : hidl_array(array.data()) {}
794 
795     T *data() { return mBuffer; }
796     const T *data() const { return mBuffer; }
797 
798     T &operator[](size_t index) {
799         return mBuffer[index];
800     }
801 
802     const T &operator[](size_t index) const {
803         return mBuffer[index];
804     }
805 
806     // equality check, assuming that T::operator== is defined.
807     bool operator==(const hidl_array &other) const {
808         for (size_t i = 0; i < elementCount(); ++i) {
809             if (!(mBuffer[i] == other.mBuffer[i])) {
810                 return false;
811             }
812         }
813         return true;
814     }
815 
816     inline bool operator!=(const hidl_array &other) const {
817         return !((*this) == other);
818     }
819 
820     static constexpr size_t size() { return SIZE1; }
821     static constexpr size_t elementCount() { return SIZE1; }
822 
823     // Copies the data to an std::array, using T::operator=(T).
824     operator std_array_type() const {
825         std_array_type array;
826         for (size_t i = 0; i < SIZE1; ++i) {
827             array[i] = mBuffer[i];
828         }
829         return array;
830     }
831 
832 private:
833     T mBuffer[SIZE1];
834 };
835 
836 // ----------------------------------------------------------------------
837 // Version functions
838 struct hidl_version {
839 public:
840     constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {
841         static_assert(sizeof(*this) == 4, "wrong size");
842     }
843 
844     bool operator==(const hidl_version& other) const {
845         return (mMajor == other.get_major() && mMinor == other.get_minor());
846     }
847 
848     bool operator<(const hidl_version& other) const {
849         return (mMajor < other.get_major() ||
850                 (mMajor == other.get_major() && mMinor < other.get_minor()));
851     }
852 
853     bool operator>(const hidl_version& other) const {
854         return other < *this;
855     }
856 
857     bool operator<=(const hidl_version& other) const {
858         return !(*this > other);
859     }
860 
861     bool operator>=(const hidl_version& other) const {
862         return !(*this < other);
863     }
864 
865     constexpr uint16_t get_major() const { return mMajor; }
866     constexpr uint16_t get_minor() const { return mMinor; }
867 
868 private:
869     uint16_t mMajor;
870     uint16_t mMinor;
871 };
872 
873 inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
874     return hidl_version(major,minor);
875 }
876 
877 ///////////////////// toString functions
878 
879 std::string toString(const void *t);
880 
881 // toString alias for numeric types
882 template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
883 inline std::string toString(T t) {
884     return std::to_string(t);
885 }
886 
887 namespace details {
888 
889 template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
890 inline std::string toHexString(T t, bool prefix = true) {
891     std::ostringstream os;
892     if (prefix) { os << std::showbase; }
893     os << std::hex << t;
894     return os.str();
895 }
896 
897 template<>
898 inline std::string toHexString(uint8_t t, bool prefix) {
899     return toHexString(static_cast<int32_t>(t), prefix);
900 }
901 
902 template<>
903 inline std::string toHexString(int8_t t, bool prefix) {
904     return toHexString(static_cast<int32_t>(t), prefix);
905 }
906 
907 template<typename Array>
908 std::string arrayToString(const Array &a, size_t size);
909 
910 template<size_t SIZE1>
911 std::string arraySizeToString() {
912     return std::string{"["} + toString(SIZE1) + "]";
913 }
914 
915 template<size_t SIZE1, size_t SIZE2, size_t... SIZES>
916 std::string arraySizeToString() {
917     return std::string{"["} + toString(SIZE1) + "]" + arraySizeToString<SIZE2, SIZES...>();
918 }
919 
920 template<typename T, size_t SIZE1>
921 std::string toString(details::const_accessor<T, SIZE1> a) {
922     return arrayToString(a, SIZE1);
923 }
924 
925 template<typename Array>
926 std::string arrayToString(const Array &a, size_t size) {
927     using android::hardware::toString;
928     std::string os;
929     os += "{";
930     for (size_t i = 0; i < size; ++i) {
931         if (i > 0) {
932             os += ", ";
933         }
934         os += toString(a[i]);
935     }
936     os += "}";
937     return os;
938 }
939 
940 template<typename T, size_t SIZE1, size_t SIZE2, size_t... SIZES>
941 std::string toString(details::const_accessor<T, SIZE1, SIZE2, SIZES...> a) {
942     return arrayToString(a, SIZE1);
943 }
944 
945 }  //namespace details
946 
947 inline std::string toString(const void *t) {
948     return details::toHexString(reinterpret_cast<uintptr_t>(t));
949 }
950 
951 // debug string dump. There will be quotes around the string!
952 inline std::string toString(const hidl_string &hs) {
953     return std::string{"\""} + hs.c_str() + "\"";
954 }
955 
956 // debug string dump
957 inline std::string toString(const hidl_handle &hs) {
958     return toString(hs.getNativeHandle());
959 }
960 
961 inline std::string toString(const hidl_memory &mem) {
962     return std::string{"memory {.name = "} + toString(mem.name()) + ", .size = "
963               + toString(mem.size())
964               + ", .handle = " + toString(mem.handle()) + "}";
965 }
966 
967 inline std::string toString(const sp<hidl_death_recipient> &dr) {
968     return std::string{"death_recipient@"} + toString(dr.get());
969 }
970 
971 // debug string dump, assuming that toString(T) is defined.
972 template<typename T>
973 std::string toString(const hidl_vec<T> &a) {
974     std::string os;
975     os += "[" + toString(a.size()) + "]";
976     os += details::arrayToString(a, a.size());
977     return os;
978 }
979 
980 template<typename T, size_t SIZE1>
981 std::string toString(const hidl_array<T, SIZE1> &a) {
982     return details::arraySizeToString<SIZE1>()
983             + details::toString(details::const_accessor<T, SIZE1>(a.data()));
984 }
985 
986 template<typename T, size_t SIZE1, size_t SIZE2, size_t... SIZES>
987 std::string toString(const hidl_array<T, SIZE1, SIZE2, SIZES...> &a) {
988     return details::arraySizeToString<SIZE1, SIZE2, SIZES...>()
989             + details::toString(details::const_accessor<T, SIZE1, SIZE2, SIZES...>(a.data()));
990 }
991 
992 /**
993  * Every HIDL generated enum generates an implementation of this function.
994  * E.x.: for(const auto v : hidl_enum_iterator<Enum>) { ... }
995  */
996 template <typename>
997 struct hidl_enum_iterator;
998 
999 /**
1000  * Bitfields in HIDL are the underlying type of the enumeration.
1001  */
1002 template <typename Enum>
1003 using hidl_bitfield = typename std::underlying_type<Enum>::type;
1004 
1005 }  // namespace hardware
1006 }  // namespace android
1007 
1008 
1009 #endif  // ANDROID_HIDL_SUPPORT_H
1010