HidlSupport.h revision 4b48edc21b333247a4b48cb12b82ab413040521a
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 <dirent.h>
23#include <dlfcn.h>
24#include <iterator>
25#include <cutils/native_handle.h>
26#include <cutils/properties.h>
27#include <functional>
28#include <hidl/HidlInternal.h>
29#include <hidl/Status.h>
30#include <map>
31#include <tuple>
32#include <utils/Errors.h>
33#include <utils/RefBase.h>
34#include <utils/StrongPointer.h>
35#include <vector>
36
37namespace android {
38
39// this file is included by all hidl interface, so we must forward declare the IMemory type.
40namespace hidl {
41namespace memory {
42namespace V1_0 {
43    struct IMemory;
44}; // namespace V1_0
45}; // namespace manager
46}; // namespace hidl
47
48namespace hardware {
49
50// hidl_handle wraps a pointer to a native_handle_t in a hidl_pointer,
51// so that it can safely be transferred between 32-bit and 64-bit processes.
52struct hidl_handle {
53    hidl_handle() {
54        mHandle = nullptr;
55    }
56    ~hidl_handle() {
57    }
58
59    // copy constructors.
60    hidl_handle(const native_handle_t *handle) {
61        mHandle = handle;
62    }
63
64    hidl_handle(const hidl_handle &other) {
65        mHandle = other.mHandle;
66    }
67
68    // move constructor.
69    hidl_handle(hidl_handle &&other) {
70        *this = std::move(other);
71    }
72
73    // assingment operators
74    hidl_handle &operator=(const hidl_handle &other) {
75        mHandle = other.mHandle;
76        return *this;
77    }
78
79    hidl_handle &operator=(const native_handle_t *native_handle) {
80        mHandle = native_handle;
81        return *this;
82    }
83
84    hidl_handle &operator=(hidl_handle &&other) {
85        mHandle = other.mHandle;
86        other.mHandle = nullptr;
87        return *this;
88    }
89
90    const native_handle_t* operator->() const {
91        return mHandle;
92    }
93    // implicit conversion to const native_handle_t*
94    operator const native_handle_t *() const {
95        return mHandle;
96    }
97    // explicit conversion
98    const native_handle_t *getNativeHandle() const {
99        return mHandle;
100    }
101private:
102    details::hidl_pointer<const native_handle_t> mHandle;
103};
104
105struct hidl_string {
106    hidl_string();
107    ~hidl_string();
108
109    // copy constructor.
110    hidl_string(const hidl_string &);
111    // copy from a C-style string.
112    hidl_string(const char *);
113    // copy from an std::string.
114    hidl_string(const std::string &);
115
116    // move constructor.
117    hidl_string(hidl_string &&);
118
119    const char *c_str() const;
120    size_t size() const;
121    bool empty() const;
122
123    // copy assignment operator.
124    hidl_string &operator=(const hidl_string &);
125    // copy from a C-style string.
126    hidl_string &operator=(const char *s);
127    // copy from an std::string.
128    hidl_string &operator=(const std::string &);
129    // move assignment operator.
130    hidl_string &operator=(hidl_string &&other);
131    // cast to std::string.
132    operator std::string() const;
133    // cast to C-style string. Caller is responsible
134    // to maintain this hidl_string alive.
135    operator const char *() const;
136
137    void clear();
138
139    // Reference an external char array. Ownership is _not_ transferred.
140    // Caller is responsible for ensuring that underlying memory is valid
141    // for the lifetime of this hidl_string.
142    void setToExternal(const char *data, size_t size);
143
144    // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
145    static const size_t kOffsetOfBuffer;
146
147private:
148    details::hidl_pointer<const char> mBuffer;
149    uint32_t mSize;  // NOT including the terminating '\0'.
150    bool mOwnsBuffer; // if true then mBuffer is a mutable char *
151
152    // copy from data with size. Assume that my memory is freed
153    // (through clear(), for example)
154    void copyFrom(const char *data, size_t size);
155    // move from another hidl_string
156    void moveFrom(hidl_string &&);
157};
158
159inline bool operator==(const hidl_string &hs1, const hidl_string &hs2) {
160    return strcmp(hs1.c_str(), hs2.c_str()) == 0;
161}
162
163inline bool operator!=(const hidl_string &hs1, const hidl_string &hs2) {
164    return !(hs1 == hs2);
165}
166
167inline bool operator==(const hidl_string &hs, const char *s) {
168    return strcmp(hs.c_str(), s) == 0;
169}
170
171inline bool operator!=(const hidl_string &hs, const char *s) {
172    return !(hs == s);
173}
174
175inline bool operator==(const char *s, const hidl_string &hs) {
176    return strcmp(hs.c_str(), s) == 0;
177}
178
179inline bool operator!=(const char *s, const hidl_string &hs) {
180    return !(s == hs);
181}
182
183// hidl_memory is a structure that can be used to transfer
184// pieces of shared memory between processes. The assumption
185// of this object is that the memory remains accessible as
186// long as the file descriptors in the enclosed mHandle
187// - as well as all of its cross-process dups() - remain opened.
188struct hidl_memory {
189
190    hidl_memory() : mOwnsHandle(false), mHandle(nullptr), mSize(0), mName("") {
191    }
192
193    /**
194     * Creates a hidl_memory object and takes ownership of the handle.
195     */
196    hidl_memory(const hidl_string &name, const hidl_handle &handle, size_t size)
197       : mOwnsHandle(true),
198         mHandle(handle),
199         mSize(size),
200         mName(name)
201    {}
202
203    // copy constructor
204    hidl_memory(const hidl_memory& other) {
205        *this = other;
206    }
207
208    // copy assignment
209    hidl_memory &operator=(const hidl_memory &other) {
210        if (this != &other) {
211            mOwnsHandle = true;
212            mHandle = native_handle_clone(other.mHandle);
213            mSize = other.mSize;
214            mName = other.mName;
215        }
216
217        return *this;
218    }
219
220    // TODO move constructor/move assignment
221
222    ~hidl_memory() {
223        // TODO if we had previously mapped from this object, unmap
224        if (mOwnsHandle) {
225            native_handle_close(mHandle);
226        }
227    }
228
229    const native_handle_t* handle() const {
230        return mHandle;
231    }
232
233    const hidl_string &name() const {
234        return mName;
235    }
236
237    size_t size() const {
238        return mSize;
239    }
240
241    // offsetof(hidl_memory, mHandle) exposed since mHandle is private.
242    static const size_t kOffsetOfHandle;
243    // offsetof(hidl_memory, mName) exposed since mHandle is private.
244    static const size_t kOffsetOfName;
245private:
246    bool mOwnsHandle;
247    hidl_handle mHandle;
248    size_t mSize;
249    hidl_string mName;
250};
251
252////////////////////////////////////////////////////////////////////////////////
253
254template<typename T>
255struct hidl_vec : private details::hidl_log_base {
256    hidl_vec()
257        : mBuffer(NULL),
258          mSize(0),
259          mOwnsBuffer(true) {
260    }
261
262    hidl_vec(const hidl_vec<T> &other) : hidl_vec() {
263        *this = other;
264    }
265
266    hidl_vec(hidl_vec<T> &&other)
267    : mOwnsBuffer(false) {
268        *this = std::move(other);
269    }
270
271    hidl_vec(const std::initializer_list<T> list)
272            : mSize(list.size()),
273              mOwnsBuffer(true) {
274        mBuffer = new T[mSize];
275
276        size_t idx = 0;
277        for (auto it = list.begin(); it != list.end(); ++it) {
278            mBuffer[idx++] = *it;
279        }
280    }
281
282    hidl_vec(const std::vector<T> &other) : hidl_vec() {
283        *this = other;
284    }
285
286    ~hidl_vec() {
287        if (mOwnsBuffer) {
288            delete[] mBuffer;
289        }
290        mBuffer = NULL;
291    }
292
293    // Reference an existing array, optionally taking ownership. It is the
294    // caller's responsibility to ensure that the underlying memory stays
295    // valid for the lifetime of this hidl_vec.
296    void setToExternal(T *data, size_t size, bool shouldOwn = false) {
297        if (mOwnsBuffer) {
298            delete [] mBuffer;
299        }
300        mBuffer = data;
301        if (size > UINT32_MAX) {
302            logAlwaysFatal("external vector size exceeds 2^32 elements.");
303        }
304        mSize = static_cast<uint32_t>(size);
305        mOwnsBuffer = shouldOwn;
306    }
307
308    T *data() {
309        return mBuffer;
310    }
311
312    const T *data() const {
313        return mBuffer;
314    }
315
316    T *releaseData() {
317        if (!mOwnsBuffer && mSize > 0) {
318            resize(mSize);
319        }
320        mOwnsBuffer = false;
321        return mBuffer;
322    }
323
324    hidl_vec &operator=(hidl_vec &&other) {
325        if (mOwnsBuffer) {
326            delete[] mBuffer;
327        }
328        mBuffer = other.mBuffer;
329        mSize = other.mSize;
330        mOwnsBuffer = other.mOwnsBuffer;
331        other.mOwnsBuffer = false;
332        return *this;
333    }
334
335    hidl_vec &operator=(const hidl_vec &other) {
336        if (this != &other) {
337            if (mOwnsBuffer) {
338                delete[] mBuffer;
339            }
340            copyFrom(other, other.mSize);
341        }
342
343        return *this;
344    }
345
346    // copy from an std::vector.
347    hidl_vec &operator=(const std::vector<T> &other) {
348        if (mOwnsBuffer) {
349            delete[] mBuffer;
350        }
351        copyFrom(other, other.size());
352        return *this;
353    }
354
355    // cast to an std::vector.
356    operator std::vector<T>() const {
357        std::vector<T> v(mSize);
358        for (size_t i = 0; i < mSize; ++i) {
359            v[i] = mBuffer[i];
360        }
361        return v;
362    }
363
364    size_t size() const {
365        return mSize;
366    }
367
368    T &operator[](size_t index) {
369        return mBuffer[index];
370    }
371
372    const T &operator[](size_t index) const {
373        return mBuffer[index];
374    }
375
376    void resize(size_t size) {
377        if (size > UINT32_MAX) {
378            logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
379        }
380        T *newBuffer = new T[size];
381
382        for (size_t i = 0; i < std::min(static_cast<uint32_t>(size), mSize); ++i) {
383            newBuffer[i] = mBuffer[i];
384        }
385
386        if (mOwnsBuffer) {
387            delete[] mBuffer;
388        }
389        mBuffer = newBuffer;
390
391        mSize = static_cast<uint32_t>(size);
392        mOwnsBuffer = true;
393    }
394
395    // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
396    static const size_t kOffsetOfBuffer;
397
398    // Define std interator interface for walking the array contents
399    // TODO:  it might be nice to implement a full featured random access iterator...
400    class iterator : public std::iterator<std::bidirectional_iterator_tag, T>
401    {
402    public:
403        iterator(T* ptr) : mPtr(ptr) { }
404        iterator operator++()    { iterator i = *this; mPtr++; return i; }
405        iterator operator++(int) { mPtr++; return *this; }
406        iterator operator--()    { iterator i = *this; mPtr--; return i; }
407        iterator operator--(int) { mPtr--; return *this; }
408        T& operator*()  { return *mPtr; }
409        T* operator->() { return mPtr; }
410        bool operator==(const iterator& rhs) const { return mPtr == rhs.mPtr; }
411        bool operator!=(const iterator& rhs) const { return mPtr != rhs.mPtr; }
412    private:
413        T* mPtr;
414    };
415    iterator begin() { return data(); }
416    iterator end() { return data()+mSize; }
417
418private:
419    details::hidl_pointer<T> mBuffer;
420    uint32_t mSize;
421    bool mOwnsBuffer;
422
423    // copy from an array-like object, assuming my resources are freed.
424    template <typename Array>
425    void copyFrom(const Array &data, size_t size) {
426        mSize = static_cast<uint32_t>(size);
427        mOwnsBuffer = true;
428        if (mSize > 0) {
429            mBuffer = new T[size];
430            for (size_t i = 0; i < size; ++i) {
431                mBuffer[i] = data[i];
432            }
433        } else {
434            mBuffer = NULL;
435        }
436    }
437};
438
439template <typename T>
440const size_t hidl_vec<T>::kOffsetOfBuffer = offsetof(hidl_vec<T>, mBuffer);
441
442////////////////////////////////////////////////////////////////////////////////
443
444namespace details {
445
446    template<size_t SIZE1, size_t... SIZES>
447    struct product {
448        static constexpr size_t value = SIZE1 * product<SIZES...>::value;
449    };
450
451    template<size_t SIZE1>
452    struct product<SIZE1> {
453        static constexpr size_t value = SIZE1;
454    };
455
456    template<typename T, size_t SIZE1, size_t... SIZES>
457    struct std_array {
458        using type = std::array<typename std_array<T, SIZES...>::type, SIZE1>;
459    };
460
461    template<typename T, size_t SIZE1>
462    struct std_array<T, SIZE1> {
463        using type = std::array<T, SIZE1>;
464    };
465
466    template<typename T, size_t SIZE1, size_t... SIZES>
467    struct accessor {
468
469        using std_array_type = typename std_array<T, SIZE1, SIZES...>::type;
470
471        explicit accessor(T *base)
472            : mBase(base) {
473        }
474
475        accessor<T, SIZES...> operator[](size_t index) {
476            return accessor<T, SIZES...>(
477                    &mBase[index * product<SIZES...>::value]);
478        }
479
480        accessor &operator=(const std_array_type &other) {
481            for (size_t i = 0; i < SIZE1; ++i) {
482                (*this)[i] = other[i];
483            }
484            return *this;
485        }
486
487    private:
488        T *mBase;
489    };
490
491    template<typename T, size_t SIZE1>
492    struct accessor<T, SIZE1> {
493
494        using std_array_type = typename std_array<T, SIZE1>::type;
495
496        explicit accessor(T *base)
497            : mBase(base) {
498        }
499
500        T &operator[](size_t index) {
501            return mBase[index];
502        }
503
504        accessor &operator=(const std_array_type &other) {
505            for (size_t i = 0; i < SIZE1; ++i) {
506                (*this)[i] = other[i];
507            }
508            return *this;
509        }
510
511    private:
512        T *mBase;
513    };
514
515    template<typename T, size_t SIZE1, size_t... SIZES>
516    struct const_accessor {
517
518        using std_array_type = typename std_array<T, SIZE1, SIZES...>::type;
519
520        explicit const_accessor(const T *base)
521            : mBase(base) {
522        }
523
524        const_accessor<T, SIZES...> operator[](size_t index) {
525            return const_accessor<T, SIZES...>(
526                    &mBase[index * product<SIZES...>::value]);
527        }
528
529        operator std_array_type() {
530            std_array_type array;
531            for (size_t i = 0; i < SIZE1; ++i) {
532                array[i] = (*this)[i];
533            }
534            return array;
535        }
536
537    private:
538        const T *mBase;
539    };
540
541    template<typename T, size_t SIZE1>
542    struct const_accessor<T, SIZE1> {
543
544        using std_array_type = typename std_array<T, SIZE1>::type;
545
546        explicit const_accessor(const T *base)
547            : mBase(base) {
548        }
549
550        const T &operator[](size_t index) const {
551            return mBase[index];
552        }
553
554        operator std_array_type() {
555            std_array_type array;
556            for (size_t i = 0; i < SIZE1; ++i) {
557                array[i] = (*this)[i];
558            }
559            return array;
560        }
561
562    private:
563        const T *mBase;
564    };
565
566}  // namespace details
567
568////////////////////////////////////////////////////////////////////////////////
569
570// A multidimensional array of T's. Assumes that T::operator=(const T &) is defined.
571template<typename T, size_t SIZE1, size_t... SIZES>
572struct hidl_array {
573
574    using std_array_type = typename details::std_array<T, SIZE1, SIZES...>::type;
575
576    hidl_array() = default;
577
578    // Copies the data from source, using T::operator=(const T &).
579    hidl_array(const T *source) {
580        for (size_t i = 0; i < elementCount(); ++i) {
581            mBuffer[i] = source[i];
582        }
583    }
584
585    // Copies the data from the given std::array, using T::operator=(const T &).
586    hidl_array(const std_array_type &array) {
587        details::accessor<T, SIZE1, SIZES...> modifier(mBuffer);
588        modifier = array;
589    }
590
591    T *data() { return mBuffer; }
592    const T *data() const { return mBuffer; }
593
594    details::accessor<T, SIZES...> operator[](size_t index) {
595        return details::accessor<T, SIZES...>(
596                &mBuffer[index * details::product<SIZES...>::value]);
597    }
598
599    details::const_accessor<T, SIZES...> operator[](size_t index) const {
600        return details::const_accessor<T, SIZES...>(
601                &mBuffer[index * details::product<SIZES...>::value]);
602    }
603
604    using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;
605
606    static constexpr size_tuple_type size() {
607        return std::make_tuple(SIZE1, SIZES...);
608    }
609
610    static constexpr size_t elementCount() {
611        return details::product<SIZE1, SIZES...>::value;
612    }
613
614    operator std_array_type() const {
615        return details::const_accessor<T, SIZE1, SIZES...>(mBuffer);
616    }
617
618private:
619    T mBuffer[elementCount()];
620};
621
622// An array of T's. Assumes that T::operator=(const T &) is defined.
623template<typename T, size_t SIZE1>
624struct hidl_array<T, SIZE1> {
625
626    using std_array_type = typename details::std_array<T, SIZE1>::type;
627
628    hidl_array() = default;
629
630    // Copies the data from source, using T::operator=(const T &).
631    hidl_array(const T *source) {
632        for (size_t i = 0; i < elementCount(); ++i) {
633            mBuffer[i] = source[i];
634        }
635    }
636
637    // Copies the data from the given std::array, using T::operator=(const T &).
638    hidl_array(const std_array_type &array) : hidl_array(array.data()) {}
639
640    T *data() { return mBuffer; }
641    const T *data() const { return mBuffer; }
642
643    T &operator[](size_t index) {
644        return mBuffer[index];
645    }
646
647    const T &operator[](size_t index) const {
648        return mBuffer[index];
649    }
650
651    static constexpr size_t size() { return SIZE1; }
652    static constexpr size_t elementCount() { return SIZE1; }
653
654    // Copies the data to an std::array, using T::operator=(T).
655    operator std_array_type() const {
656        std_array_type array;
657        for (size_t i = 0; i < SIZE1; ++i) {
658            array[i] = mBuffer[i];
659        }
660        return array;
661    }
662
663private:
664    T mBuffer[SIZE1];
665};
666
667// ----------------------------------------------------------------------
668// Version functions
669struct hidl_version {
670public:
671    constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {}
672
673    bool operator==(const hidl_version& other) const {
674        return (mMajor == other.get_major() && mMinor == other.get_minor());
675    }
676
677    constexpr uint16_t get_major() const { return mMajor; }
678    constexpr uint16_t get_minor() const { return mMinor; }
679
680private:
681    uint16_t mMajor;
682    uint16_t mMinor;
683};
684
685inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
686    return hidl_version(major,minor);
687}
688
689#if defined(__LP64__)
690#define HAL_LIBRARY_PATH_SYSTEM "/system/lib64/hw/"
691#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib64/hw/"
692#define HAL_LIBRARY_PATH_ODM "/odm/lib64/hw/"
693#else
694#define HAL_LIBRARY_PATH_SYSTEM "/system/lib/hw/"
695#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib/hw/"
696#define HAL_LIBRARY_PATH_ODM "/odm/lib/hw/"
697#endif
698
699#define DECLARE_SERVICE_MANAGER_INTERACTIONS(INTERFACE)                                  \
700    static ::android::sp<I##INTERFACE> getService(                                       \
701            const std::string &serviceName, bool getStub=false);                         \
702    ::android::status_t registerAsService(const std::string &serviceName);               \
703    static bool registerForNotifications(                                                \
704        const std::string &serviceName,                                                  \
705        const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification>        \
706                  &notification);                                                        \
707
708// ----------------------------------------------------------------------
709// Class that provides Hidl instrumentation utilities.
710struct HidlInstrumentor {
711    // Event that triggers the instrumentation. e.g. enter of an API call on
712    // the server/client side, exit of an API call on the server/client side
713    // etc.
714    enum InstrumentationEvent {
715        SERVER_API_ENTRY = 0,
716        SERVER_API_EXIT,
717        CLIENT_API_ENTRY,
718        CLIENT_API_EXIT,
719        SYNC_CALLBACK_ENTRY,
720        SYNC_CALLBACK_EXIT,
721        ASYNC_CALLBACK_ENTRY,
722        ASYNC_CALLBACK_EXIT,
723        PASSTHROUGH_ENTRY,
724        PASSTHROUGH_EXIT,
725    };
726
727    // Signature of the instrumentation callback function.
728    using InstrumentationCallback = std::function<void(
729            const InstrumentationEvent event,
730            const char *package,
731            const char *version,
732            const char *interface,
733            const char *method,
734            std::vector<void *> *args)>;
735
736    explicit HidlInstrumentor(const std::string &prefix);
737    virtual ~HidlInstrumentor();
738
739 protected:
740    // Function that lookup and dynamically loads the hidl instrumentation
741    // libraries and registers the instrumentation callback functions.
742    //
743    // The instrumentation libraries should be stored under any of the following
744    // directories: HAL_LIBRARY_PATH_SYSTEM, HAL_LIBRARY_PATH_VENDOR and
745    // HAL_LIBRARY_PATH_ODM. The name of instrumentation libraries should
746    // follow pattern: ^profilerPrefix(.*).profiler.so$
747    //
748    // Each instrumentation library is expected to implement the instrumentation
749    // function called HIDL_INSTRUMENTATION_FUNCTION.
750    //
751    // A no-op for user build.
752    void registerInstrumentationCallbacks(
753            const std::string &profilerPrefix,
754            std::vector<InstrumentationCallback> *instrumentationCallbacks);
755
756    // Utility function to determine whether a give file is a instrumentation
757    // library (i.e. the file name follow the expected pattern).
758    bool isInstrumentationLib(
759            const std::string &profilerPrefix,
760            const dirent *file);
761    // A list of registered instrumentation callbacks.
762    std::vector<InstrumentationCallback> mInstrumentationCallbacks;
763    // Flag whether to enable instrumentation.
764    bool mEnableInstrumentation;
765};
766
767}  // namespace hardware
768}  // namespace android
769
770
771#endif  // ANDROID_HIDL_SUPPORT_H
772
773