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