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