/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_HIDL_SUPPORT_H
#define ANDROID_HIDL_SUPPORT_H

#include <algorithm>
#include <dirent.h>
#include <dlfcn.h>
#include <cutils/properties.h>
#include <functional>
#include <hidl/Status.h>
#include <hwbinder/IBinder.h>
#include <hwbinder/Parcel.h>
#include <map>
#include <tuple>
#include <utils/Errors.h>
#include <utils/RefBase.h>
#include <utils/StrongPointer.h>

namespace android {
namespace hardware {

struct hidl_string {
    hidl_string();
    ~hidl_string();

    // copy constructor.
    hidl_string(const hidl_string &);
    // copy from a C-style string.
    hidl_string(const char *);
    // copy from an std::string.
    hidl_string(const std::string &);

    // move constructor.
    hidl_string(hidl_string &&);

    const char *c_str() const;
    size_t size() const;
    bool empty() const;

    // copy assignment operator.
    hidl_string &operator=(const hidl_string &);
    // copy from a C-style string.
    hidl_string &operator=(const char *s);
    // copy from an std::string.
    hidl_string &operator=(const std::string &);
    // move assignment operator.
    hidl_string &operator=(hidl_string &&other);
    // cast to std::string.
    operator std::string() const;
    // cast to C-style string. Caller is responsible
    // to maintain this hidl_string alive.
    operator const char *() const;

    void clear();

    // Reference an external char array. Ownership is _not_ transferred.
    // Caller is responsible for ensuring that underlying memory is valid
    // for the lifetime of this hidl_string.
    void setToExternal(const char *data, size_t size);

    // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
    static const size_t kOffsetOfBuffer;

private:
    const char *mBuffer;
    size_t mSize;  // NOT including the terminating '\0'.
    bool mOwnsBuffer; // if true then mBuffer is a mutable char *

    // copy from data with size. Assume that my memory is freed
    // (through clear(), for example)
    void copyFrom(const char *data, size_t size);
    // move from another hidl_string
    void moveFrom(hidl_string &&);
};

status_t readEmbeddedFromParcel(hidl_string *string,
        const Parcel &parcel, size_t parentHandle, size_t parentOffset);

status_t writeEmbeddedToParcel(const hidl_string &string,
        Parcel *parcel, size_t parentHandle, size_t parentOffset);

inline bool operator==(const hidl_string &hs, const char *s) {
    return strcmp(hs.c_str(), s) == 0;
}

inline bool operator!=(const hidl_string &hs, const char *s) {
    return !(hs == s);
}

inline bool operator==(const char *s, const hidl_string &hs) {
    return strcmp(hs.c_str(), s) == 0;
}

inline bool operator!=(const char *s, const hidl_string &hs) {
    return !(s == hs);
}

////////////////////////////////////////////////////////////////////////////////

template<typename T>
struct hidl_vec {
    hidl_vec()
        : mBuffer(NULL),
          mSize(0),
          mOwnsBuffer(true) {
    }

    hidl_vec(const hidl_vec<T> &other) : hidl_vec() {
        *this = other;
    }

    hidl_vec(hidl_vec<T> &&other)
	: mOwnsBuffer(false) {
        *this = std::move(other);
    }

    hidl_vec(const std::vector<T> &other) : hidl_vec() {
        *this = other;
    }

    ~hidl_vec() {
        if (mOwnsBuffer) {
            delete[] mBuffer;
        }
        mBuffer = NULL;
    }

    // Reference an existing array, optionally taking ownership. It is the
    // caller's responsibility to ensure that the underlying memory stays
    // valid for the lifetime of this hidl_vec.
    void setToExternal(T *data, size_t size, bool shouldOwn = false) {
        if (mOwnsBuffer) {
            delete [] mBuffer;
        }
        mBuffer = data;
        mSize = size;
        mOwnsBuffer = shouldOwn;
    }

    T *data() {
        return mBuffer;
    }

    const T *data() const {
        return mBuffer;
    }

    T *releaseData() {
        if (!mOwnsBuffer && mSize > 0) {
            resize(mSize);
        }
        mOwnsBuffer = false;
        return mBuffer;
    }

    hidl_vec &operator=(hidl_vec &&other) {
        if (mOwnsBuffer) {
            delete[] mBuffer;
        }
        mBuffer = other.mBuffer;
        mSize = other.mSize;
        mOwnsBuffer = other.mOwnsBuffer;
        other.mOwnsBuffer = false;
        return *this;
    }

    hidl_vec &operator=(const hidl_vec &other) {
        if (this != &other) {
            if (mOwnsBuffer) {
                delete[] mBuffer;
            }
            copyFrom(other, other.mSize);
        }

        return *this;
    }

    // copy from an std::vector.
    hidl_vec &operator=(const std::vector<T> &other) {
        if (mOwnsBuffer) {
            delete[] mBuffer;
        }
        copyFrom(other, other.size());
        return *this;
    }

    // cast to an std::vector.
    operator std::vector<T>() const {
        std::vector<T> v(mSize);
        for (size_t i = 0; i < mSize; ++i) {
            v[i] = mBuffer[i];
        }
        return v;
    }

    size_t size() const {
        return mSize;
    }

    T &operator[](size_t index) {
        return mBuffer[index];
    }

    const T &operator[](size_t index) const {
        return mBuffer[index];
    }

    void resize(size_t size) {
        T *newBuffer = new T[size];

        for (size_t i = 0; i < std::min(size, mSize); ++i) {
            newBuffer[i] = mBuffer[i];
        }

        if (mOwnsBuffer) {
            delete[] mBuffer;
        }
        mBuffer = newBuffer;

        mSize = size;
        mOwnsBuffer = true;
    }

    status_t findInParcel(const Parcel &parcel, size_t *handle) const {
        return parcel.quickFindBuffer(mBuffer, handle);
    }

    // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
    static const size_t kOffsetOfBuffer;
private:
    T *mBuffer;
    size_t mSize;
    bool mOwnsBuffer;

    // copy from an array-like object, assuming my resources are freed.
    template <typename Array>
    void copyFrom(const Array &data, size_t size) {
        mSize = size;
        mOwnsBuffer = true;
        if (mSize > 0) {
            mBuffer = new T[size];
            for (size_t i = 0; i < size; ++i) {
                mBuffer[i] = data[i];
            }
        } else {
            mBuffer = NULL;
        }
    }
};

template <typename T>
const size_t hidl_vec<T>::kOffsetOfBuffer = offsetof(hidl_vec<T>, mBuffer);

template<typename T>
status_t readEmbeddedFromParcel(
        hidl_vec<T> * /*vec*/,
        const Parcel &parcel,
        size_t parentHandle,
        size_t parentOffset,
        size_t *handle) {
    const void *ptr = parcel.readEmbeddedBuffer(
            handle,
            parentHandle,
            parentOffset + hidl_vec<T>::kOffsetOfBuffer);

    return ptr != NULL ? OK : UNKNOWN_ERROR;
}

template<typename T>
status_t writeEmbeddedToParcel(
        const hidl_vec<T> &vec,
        Parcel *parcel,
        size_t parentHandle,
        size_t parentOffset,
        size_t *handle) {
    return parcel->writeEmbeddedBuffer(
            vec.data(),
            sizeof(T) * vec.size(),
            handle,
            parentHandle,
            parentOffset + hidl_vec<T>::kOffsetOfBuffer);
}

////////////////////////////////////////////////////////////////////////////////

namespace details {

    template<size_t SIZE1, size_t... SIZES>
    struct product {
        static constexpr size_t value = SIZE1 * product<SIZES...>::value;
    };

    template<size_t SIZE1>
    struct product<SIZE1> {
        static constexpr size_t value = SIZE1;
    };

    template<typename T, size_t SIZE1, size_t... SIZES>
    struct accessor {
        explicit accessor(T *base)
            : mBase(base) {
        }

        accessor<T, SIZES...> operator[](size_t index) {
            return accessor<T, SIZES...>(
                    &mBase[index * product<SIZES...>::value]);
        }

    private:
        T *mBase;
    };

    template<typename T, size_t SIZE1>
    struct accessor<T, SIZE1> {
        explicit accessor(T *base)
            : mBase(base) {
        }

        T &operator[](size_t index) {
            return mBase[index];
        }

    private:
        T *mBase;
    };

    template<typename T, size_t SIZE1, size_t... SIZES>
    struct const_accessor {
        explicit const_accessor(const T *base)
            : mBase(base) {
        }

        const_accessor<T, SIZES...> operator[](size_t index) {
            return const_accessor<T, SIZES...>(
                    &mBase[index * product<SIZES...>::value]);
        }

    private:
        const T *mBase;
    };

    template<typename T, size_t SIZE1>
    struct const_accessor<T, SIZE1> {
        explicit const_accessor(const T *base)
            : mBase(base) {
        }

        const T &operator[](size_t index) const {
            return mBase[index];
        }

    private:
        const T *mBase;
    };

}  // namespace details

////////////////////////////////////////////////////////////////////////////////

template<typename T, size_t SIZE1, size_t... SIZES>
struct hidl_array {
    hidl_array() = default;

    T *data() { return mBuffer; }
    const T *data() const { return mBuffer; }

    details::accessor<T, SIZES...> operator[](size_t index) {
        return details::accessor<T, SIZES...>(
                &mBuffer[index * details::product<SIZES...>::value]);
    }

    details::const_accessor<T, SIZES...> operator[](size_t index) const {
        return details::const_accessor<T, SIZES...>(
                &mBuffer[index * details::product<SIZES...>::value]);
    }

    using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;

    static constexpr size_tuple_type size() {
        return std::make_tuple(SIZE1, SIZES...);
    }

private:
    T mBuffer[details::product<SIZE1, SIZES...>::value];
};

template<typename T, size_t SIZE1>
struct hidl_array<T, SIZE1> {
    hidl_array() = default;

    T *data() { return mBuffer; }
    const T *data() const { return mBuffer; }

    T &operator[](size_t index) {
        return mBuffer[index];
    }

    const T &operator[](size_t index) const {
        return mBuffer[index];
    }

    static constexpr size_t size() { return SIZE1; }

private:
    T mBuffer[SIZE1];
};

///////////////////////////// pointers for HIDL

template <typename T>
static status_t readEmbeddedReferenceFromParcel(
        T const* * /* bufptr */,
        const Parcel & parcel,
        size_t parentHandle,
        size_t parentOffset,
        size_t *handle,
        bool *shouldResolveRefInBuffer
    ) {
    // *bufptr is ignored because, if I am embedded in some
    // other buffer, the kernel should have fixed me up already.
    bool isPreviouslyWritten;
    status_t result = parcel.readEmbeddedReference(
        nullptr, // ignored, not written to bufptr.
        handle,
        parentHandle,
        parentOffset,
        &isPreviouslyWritten);
    // tell caller to run T::readEmbeddedToParcel and
    // T::readEmbeddedReferenceToParcel if necessary.
    // It is not called here because we don't know if these two are valid methods.
    *shouldResolveRefInBuffer = !isPreviouslyWritten;
    return result;
}

template <typename T>
static status_t writeEmbeddedReferenceToParcel(
        T const* buf,
        Parcel *parcel, size_t parentHandle, size_t parentOffset,
        size_t *handle,
        bool *shouldResolveRefInBuffer
        ) {

    if(buf == nullptr) {
        *shouldResolveRefInBuffer = false;
        return parcel->writeEmbeddedNullReference(handle, parentHandle, parentOffset);
    }

    // find whether the buffer exists
    size_t childHandle, childOffset;
    status_t result;
    bool found;

    result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);

    // tell caller to run T::writeEmbeddedToParcel and
    // T::writeEmbeddedReferenceToParcel if necessary.
    // It is not called here because we don't know if these two are valid methods.
    *shouldResolveRefInBuffer = !found;

    if(result != OK) {
        return result; // bad pointers and length given
    }
    if(!found) { // did not find it.
        return parcel->writeEmbeddedBuffer(buf, sizeof(T), handle,
                parentHandle, parentOffset);
    }
    // found the buffer. easy case.
    return parcel->writeEmbeddedReference(
            handle,
            childHandle,
            childOffset,
            parentHandle,
            parentOffset);
}

template <typename T>
static status_t readReferenceFromParcel(
        T const* *bufptr,
        const Parcel & parcel,
        size_t *handle,
        bool *shouldResolveRefInBuffer
    ) {
    bool isPreviouslyWritten;
    status_t result = parcel.readReference(reinterpret_cast<void const* *>(bufptr),
            handle, &isPreviouslyWritten);
    // tell caller to run T::readEmbeddedToParcel and
    // T::readEmbeddedReferenceToParcel if necessary.
    // It is not called here because we don't know if these two are valid methods.
    *shouldResolveRefInBuffer = !isPreviouslyWritten;
    return result;
}

template <typename T>
static status_t writeReferenceToParcel(
        T const *buf,
        Parcel * parcel,
        size_t *handle,
        bool *shouldResolveRefInBuffer
    ) {

    if(buf == nullptr) {
        *shouldResolveRefInBuffer = false;
        return parcel->writeNullReference(handle);
    }

    // find whether the buffer exists
    size_t childHandle, childOffset;
    status_t result;
    bool found;

    result = parcel->findBuffer(buf, sizeof(T), &found, &childHandle, &childOffset);

    // tell caller to run T::writeEmbeddedToParcel and
    // T::writeEmbeddedReferenceToParcel if necessary.
    // It is not called here because we don't know if these two are valid methods.
    *shouldResolveRefInBuffer = !found;

    if(result != OK) {
        return result; // bad pointers and length given
    }
    if(!found) { // did not find it.
        return parcel->writeBuffer(buf, sizeof(T), handle);
    }
    // found the buffer. easy case.
    return parcel->writeReference(handle,
        childHandle, childOffset);
}

// ----------------------------------------------------------------------
// Version functions
struct hidl_version {
public:
    constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {}

    bool operator==(const hidl_version& other) const {
        return (mMajor == other.get_major() && mMinor == other.get_minor());
    }

    constexpr uint16_t get_major() const { return mMajor; }
    constexpr uint16_t get_minor() const { return mMinor; }

    android::status_t writeToParcel(android::hardware::Parcel& parcel) const {
        return parcel.writeUint32(static_cast<uint32_t>(mMajor) << 16 | mMinor);
    }

    static hidl_version* readFromParcel(const android::hardware::Parcel& parcel) {
        uint32_t version;
        android::status_t status = parcel.readUint32(&version);
        if (status != OK) {
            return nullptr;
        } else {
            return new hidl_version(version >> 16, version & 0xFFFF);
        }
    }

private:
    uint16_t mMajor;
    uint16_t mMinor;
};

inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
    return hidl_version(major,minor);
}

struct IBase : virtual public RefBase {
    virtual bool isRemote() const = 0;
    // HIDL reserved methods follow.
    virtual ::android::hardware::Return<void> interfaceChain(
            std::function<void(const hidl_vec<hidl_string>&)> _hidl_cb) = 0;
    // descriptor for HIDL reserved methods.
    static const char* descriptor;
};

extern std::map<std::string, std::function<sp<IBinder>(void*)>> gBnConstructorMap;

// Construct a smallest possible binder from the given interface.
// If it is remote, then its remote() will be retrieved.
// Otherwise, the smallest possible BnChild is found where IChild is a subclass of IType
// and iface is of class IChild. BnChild will be used to wrapped the given iface.
// Return nullptr if iface is null or any failure.
template <typename IType, typename IHwType>
sp<IBinder> toBinder(sp<IType> iface) {
    IType *ifacePtr = iface.get();
    if (ifacePtr == nullptr) {
        return nullptr;
    }
    if (ifacePtr->isRemote()) {
        return ::android::hardware::IInterface::asBinder(static_cast<IHwType *>(ifacePtr));
    } else {
        std::string myDescriptor{};
        ifacePtr->interfaceChain([&](const hidl_vec<hidl_string> &types) {
            if (types.size() > 0) {
                myDescriptor = types[0].c_str();
            }
        });
        if (myDescriptor.empty()) {
            // interfaceChain fails || types.size() == 0
            return nullptr;
        }
        auto iter = gBnConstructorMap.find(myDescriptor);
        if (iter == gBnConstructorMap.end()) {
            return nullptr;
        }
        return sp<IBinder>((iter->second)(reinterpret_cast<void *>(ifacePtr)));
    }
}

// cast the interface IParent to IChild.
// Return nullptr if parent is null or any failure.
template<typename IChild, typename IParent, typename BpChild, typename IHwParent>
sp<IChild> castInterface(sp<IParent> parent, const char *childIndicator) {
    if (parent.get() == nullptr) {
        // casts always succeed with nullptrs.
        return nullptr;
    }
    bool canCast = false;
    parent->interfaceChain([&](const hidl_vec<hidl_string> &allowedCastTypes) {
        for (size_t i = 0; i < allowedCastTypes.size(); i++) {
            if (allowedCastTypes[i] == childIndicator) {
                canCast = true;
                break;
            }
        }
    });

    if (!canCast) {
        return sp<IChild>(nullptr); // cast failed.
    }
    if (parent->isRemote()) {
        // binderized mode. Got BpChild. grab the remote and wrap it.
        return sp<IChild>(new BpChild(toBinder<IParent, IHwParent>(parent)));
    }
    // Passthrough mode. Got BnChild and BsChild.
    return sp<IChild>(static_cast<IChild *>(parent.get()));
}

#if defined(__LP64__)
#define HAL_LIBRARY_PATH_SYSTEM "/system/lib64/hw/"
#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib64/hw/"
#define HAL_LIBRARY_PATH_ODM "/odm/lib64/hw/"
#else
#define HAL_LIBRARY_PATH_SYSTEM "/system/lib/hw/"
#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib/hw/"
#define HAL_LIBRARY_PATH_ODM "/odm/lib/hw/"
#endif

#define DECLARE_SERVICE_MANAGER_INTERACTIONS(INTERFACE)                                  \
    static ::android::sp<I##INTERFACE> getService(                                       \
            const std::string &serviceName, bool getStub=false);                         \
    ::android::status_t registerAsService(const std::string &serviceName);               \
    static bool registerForNotifications(                                                \
        const std::string &serviceName,                                                  \
        const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification>        \
                  &notification);                                                        \

#define IMPLEMENT_SERVICE_MANAGER_INTERACTIONS(INTERFACE, PACKAGE)                       \
    ::android::sp<I##INTERFACE> I##INTERFACE::getService(                                \
            const std::string &serviceName, bool getStub)                                \
    {                                                                                    \
        using ::android::sp;                                                             \
        using ::android::hardware::defaultServiceManager;                                \
        using ::android::hardware::IBinder;                                              \
        using ::android::hidl::manager::V1_0::IServiceManager;                           \
        sp<I##INTERFACE> iface;                                                          \
        const sp<IServiceManager> sm = defaultServiceManager();                          \
        if (sm != nullptr && !getStub) {                                                 \
            sp<IBinder> binderIface;                                                     \
            ::android::hardware::Return<void> ret =                                      \
                sm->get(PACKAGE "::I" #INTERFACE, serviceName.c_str(),                   \
                    [&binderIface](sp<IBinder> iface) {                                  \
                        binderIface = iface;                                             \
                    });                                                                  \
            if (ret.getStatus().isOk()) {                                                \
                iface = IHw##INTERFACE::asInterface(binderIface);                        \
                if (iface != nullptr) {                                                  \
                    return iface;                                                        \
                }                                                                        \
            }                                                                            \
        }                                                                                \
        int dlMode = RTLD_LAZY;                                                          \
        void *handle = dlopen(HAL_LIBRARY_PATH_ODM PACKAGE "-impl.so", dlMode);          \
        if (handle == nullptr) {                                                         \
            handle = dlopen(HAL_LIBRARY_PATH_VENDOR PACKAGE "-impl.so", dlMode);         \
        }                                                                                \
        if (handle == nullptr) {                                                         \
            handle = dlopen(HAL_LIBRARY_PATH_SYSTEM PACKAGE "-impl.so", dlMode);         \
        }                                                                                \
        if (handle == nullptr) {                                                         \
            return iface;                                                                \
        }                                                                                \
        I##INTERFACE* (*generator)(const char* name);                                    \
        *(void **)(&generator) = dlsym(handle, "HIDL_FETCH_I"#INTERFACE);                \
        if (generator) {                                                                 \
            iface = (*generator)(serviceName.c_str());                                   \
            if (iface != nullptr) {                                                      \
                iface = new Bs##INTERFACE(iface);                                        \
            }                                                                            \
        }                                                                                \
        return iface;                                                                    \
    }                                                                                    \
    ::android::status_t I##INTERFACE::registerAsService(                                 \
            const std::string &serviceName)                                              \
    {                                                                                    \
        using ::android::sp;                                                             \
        using ::android::hardware::defaultServiceManager;                                \
        using ::android::hidl::manager::V1_0::IServiceManager;                           \
        sp<Bn##INTERFACE> binderIface = new Bn##INTERFACE(this);                         \
        const sp<IServiceManager> sm = defaultServiceManager();                          \
        bool success = false;                                                            \
        ::android::hardware::Return<void> ret =                                          \
            this->interfaceChain(                                                        \
                [&success, &sm, &serviceName, &binderIface](const auto &chain) {         \
                    success = sm->add(chain, serviceName.c_str(), binderIface);          \
                });                                                                      \
        success = success && ret.getStatus().isOk();                                     \
        return success ? ::android::OK : ::android::UNKNOWN_ERROR;                       \
    }                                                                                    \
    bool I##INTERFACE::registerForNotifications(                                         \
            const std::string &serviceName,                                              \
            const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification>    \
                      &notification)                                                     \
    {                                                                                    \
        using ::android::sp;                                                             \
        using ::android::hardware::defaultServiceManager;                                \
        using ::android::hidl::manager::V1_0::IServiceManager;                           \
        const sp<IServiceManager> sm = defaultServiceManager();                          \
        if (sm == nullptr) {                                                             \
            return false;                                                                \
        }                                                                                \
        return sm->registerForNotifications(PACKAGE "::I" #INTERFACE,                    \
                                            serviceName,                                 \
                                            notification);                               \
    }

// ----------------------------------------------------------------------
// Class that provides Hidl instrumentation utilities.
struct HidlInstrumentor {
    // Event that triggers the instrumentation. e.g. enter of an API call on
    // the server/client side, exit of an API call on the server/client side
    // etc.
    enum InstrumentationEvent {
        SERVER_API_ENTRY = 0,
        SERVER_API_EXIT,
        CLIENT_API_ENTRY,
        CLIENT_API_EXIT,
        SYNC_CALLBACK_ENTRY,
        SYNC_CALLBACK_EXIT,
        ASYNC_CALLBACK_ENTRY,
        ASYNC_CALLBACK_EXIT,
        PASSTHROUGH_ENTRY,
        PASSTHROUGH_EXIT,
    };

    // Signature of the instrumentation callback function.
    using InstrumentationCallback = std::function<void(
            const InstrumentationEvent event,
            const char *package,
            const char *version,
            const char *interface,
            const char *method,
            std::vector<void *> *args)>;

    explicit HidlInstrumentor(const std::string &prefix);
    virtual ~HidlInstrumentor();

 protected:
    // Function that lookup and dynamically loads the hidl instrumentation
    // libraries and registers the instrumentation callback functions.
    //
    // The instrumentation libraries should be stored under any of the following
    // directories: HAL_LIBRARY_PATH_SYSTEM, HAL_LIBRARY_PATH_VENDOR and
    // HAL_LIBRARY_PATH_ODM. The name of instrumentation libraries should
    // follow pattern: ^profilerPrefix(.*).profiler.so$
    //
    // Each instrumentation library is expected to implement the instrumentation
    // function called HIDL_INSTRUMENTATION_FUNCTION.
    //
    // A no-op for user build.
    void registerInstrumentationCallbacks(
            const std::string &profilerPrefix,
            std::vector<InstrumentationCallback> *instrumentationCallbacks);

    // Utility function to determine whether a give file is a instrumentation
    // library (i.e. the file name follow the expected pattern).
    bool isInstrumentationLib(
            const std::string &profilerPrefix,
            const dirent *file);
    // A list of registered instrumentation callbacks.
    std::vector<InstrumentationCallback> mInstrumentationCallbacks;
    // Flag whether to enable instrumentation.
    bool mEnableInstrumentation;
};

}  // namespace hardware
}  // namespace android


#endif  // ANDROID_HIDL_SUPPORT_H

