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