Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c5a9283c authored by Yu Shan's avatar Yu Shan
Browse files

Refactor MockVehicleHardware into separate files.

Test: presubmit.
Bug: 200737967
Change-Id: Id28357f8ccd692de1daa47a1bfa539e90826b02a
parent e032b158
Loading
Loading
Loading
Loading
+1 −188
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include "ConnectedClient.h"
#include "DefaultVehicleHal.h"
#include "MockVehicleCallback.h"
#include "MockVehicleHardware.h"

#include <IVehicleHardware.h>
#include <LargeParcelableBase.h>
@@ -76,199 +77,11 @@ constexpr int32_t INVALID_PROP_ID = 0;
// VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
constexpr int32_t INT32_WINDOW_PROP = 10001 + 0x10000000 + 0x03000000 + 0x00400000;

template <class T>
std::optional<T> pop(std::list<T>& items) {
    if (items.size() > 0) {
        auto item = std::move(items.front());
        items.pop_front();
        return item;
    }
    return std::nullopt;
}

int32_t testInt32VecProp(size_t i) {
    // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
    return static_cast<int32_t>(i) + 0x10000000 + 0x01000000 + 0x00410000;
}

class MockVehicleHardware final : public IVehicleHardware {
  public:
    ~MockVehicleHardware() {
        std::scoped_lock<std::mutex> lockGuard(mLock);
        for (auto& thread : mThreads) {
            thread.join();
        }
    }

    std::vector<VehiclePropConfig> getAllPropertyConfigs() const override {
        std::scoped_lock<std::mutex> lockGuard(mLock);
        return mPropertyConfigs;
    }

    StatusCode setValues(std::shared_ptr<const SetValuesCallback> callback,
                         const std::vector<SetValueRequest>& requests) override {
        std::scoped_lock<std::mutex> lockGuard(mLock);
        return handleRequests(__func__, callback, requests, &mSetValueRequests,
                              &mSetValueResponses);
    }

    StatusCode getValues(std::shared_ptr<const GetValuesCallback> callback,
                         const std::vector<GetValueRequest>& requests) const override {
        std::scoped_lock<std::mutex> lockGuard(mLock);
        return handleRequests(__func__, callback, requests, &mGetValueRequests,
                              &mGetValueResponses);
    }

    DumpResult dump(const std::vector<std::string>&) override {
        // TODO(b/200737967): mock this.
        return DumpResult{};
    }

    StatusCode checkHealth() override {
        // TODO(b/200737967): mock this.
        return StatusCode::OK;
    }

    void registerOnPropertyChangeEvent(std::unique_ptr<const PropertyChangeCallback>) override {
        // TODO(b/200737967): mock this.
    }

    void registerOnPropertySetErrorEvent(std::unique_ptr<const PropertySetErrorCallback>) override {
        // TODO(b/200737967): mock this.
    }

    // Test functions.
    void setPropertyConfigs(const std::vector<VehiclePropConfig>& configs) {
        std::scoped_lock<std::mutex> lockGuard(mLock);
        mPropertyConfigs = configs;
    }

    void addGetValueResponses(const std::vector<GetValueResult>& responses) {
        std::scoped_lock<std::mutex> lockGuard(mLock);
        mGetValueResponses.push_back(responses);
    }

    void addSetValueResponses(const std::vector<SetValueResult>& responses) {
        std::scoped_lock<std::mutex> lockGuard(mLock);
        mSetValueResponses.push_back(responses);
    }

    std::vector<GetValueRequest> nextGetValueRequests() {
        std::scoped_lock<std::mutex> lockGuard(mLock);
        std::optional<std::vector<GetValueRequest>> request = pop(mGetValueRequests);
        if (!request.has_value()) {
            return std::vector<GetValueRequest>();
        }
        return std::move(request.value());
    }

    std::vector<SetValueRequest> nextSetValueRequests() {
        std::scoped_lock<std::mutex> lockGuard(mLock);
        std::optional<std::vector<SetValueRequest>> request = pop(mSetValueRequests);
        if (!request.has_value()) {
            return std::vector<SetValueRequest>();
        }
        return std::move(request.value());
    }

    void setStatus(const char* functionName, StatusCode status) {
        std::scoped_lock<std::mutex> lockGuard(mLock);
        mStatusByFunctions[functionName] = status;
    }

    void setSleepTime(int64_t timeInNano) {
        std::scoped_lock<std::mutex> lockGuard(mLock);
        mSleepTime = timeInNano;
    }

  private:
    mutable std::mutex mLock;
    std::vector<VehiclePropConfig> mPropertyConfigs GUARDED_BY(mLock);
    mutable std::list<std::vector<GetValueRequest>> mGetValueRequests GUARDED_BY(mLock);
    mutable std::list<std::vector<GetValueResult>> mGetValueResponses GUARDED_BY(mLock);
    mutable std::list<std::vector<SetValueRequest>> mSetValueRequests GUARDED_BY(mLock);
    mutable std::list<std::vector<SetValueResult>> mSetValueResponses GUARDED_BY(mLock);
    std::unordered_map<const char*, StatusCode> mStatusByFunctions GUARDED_BY(mLock);
    int64_t mSleepTime GUARDED_BY(mLock) = 0;
    mutable std::vector<std::thread> mThreads GUARDED_BY(mLock);

    template <class ResultType>
    StatusCode returnResponse(
            std::shared_ptr<const std::function<void(std::vector<ResultType>)>> callback,
            std::list<std::vector<ResultType>>* storedResponses) const;

    template <class RequestType, class ResultType>
    StatusCode handleRequests(
            const char* functionName,
            std::shared_ptr<const std::function<void(std::vector<ResultType>)>> callback,
            const std::vector<RequestType>& requests,
            std::list<std::vector<RequestType>>* storedRequests,
            std::list<std::vector<ResultType>>* storedResponses) const REQUIRES(mLock);
};

template <class ResultType>
StatusCode MockVehicleHardware::returnResponse(
        std::shared_ptr<const std::function<void(std::vector<ResultType>)>> callback,
        std::list<std::vector<ResultType>>* storedResponses) const {
    if (storedResponses->size() > 0) {
        (*callback)(std::move(storedResponses->front()));
        storedResponses->pop_front();
        return StatusCode::OK;
    } else {
        ALOGE("no more response");
        return StatusCode::INTERNAL_ERROR;
    }
}

template StatusCode MockVehicleHardware::returnResponse<GetValueResult>(
        std::shared_ptr<const std::function<void(std::vector<GetValueResult>)>> callback,
        std::list<std::vector<GetValueResult>>* storedResponses) const;

template StatusCode MockVehicleHardware::returnResponse<SetValueResult>(
        std::shared_ptr<const std::function<void(std::vector<SetValueResult>)>> callback,
        std::list<std::vector<SetValueResult>>* storedResponses) const;

template <class RequestType, class ResultType>
StatusCode MockVehicleHardware::handleRequests(
        const char* functionName,
        std::shared_ptr<const std::function<void(std::vector<ResultType>)>> callback,
        const std::vector<RequestType>& requests,
        std::list<std::vector<RequestType>>* storedRequests,
        std::list<std::vector<ResultType>>* storedResponses) const {
    storedRequests->push_back(requests);
    if (auto it = mStatusByFunctions.find(functionName); it != mStatusByFunctions.end()) {
        if (StatusCode status = it->second; status != StatusCode::OK) {
            return status;
        }
    }

    if (mSleepTime != 0) {
        int64_t sleepTime = mSleepTime;
        mThreads.emplace_back([this, callback, sleepTime, storedResponses]() {
            std::this_thread::sleep_for(std::chrono::nanoseconds(sleepTime));
            returnResponse(callback, storedResponses);
        });
        return StatusCode::OK;

    } else {
        return returnResponse(callback, storedResponses);
    }
}

template StatusCode MockVehicleHardware::handleRequests<GetValueRequest, GetValueResult>(
        const char* functionName,
        std::shared_ptr<const std::function<void(std::vector<GetValueResult>)>> callback,
        const std::vector<GetValueRequest>& requests,
        std::list<std::vector<GetValueRequest>>* storedRequests,
        std::list<std::vector<GetValueResult>>* storedResponses) const;

template StatusCode MockVehicleHardware::handleRequests<SetValueRequest, SetValueResult>(
        const char* functionName,
        std::shared_ptr<const std::function<void(std::vector<SetValueResult>)>> callback,
        const std::vector<SetValueRequest>& requests,
        std::list<std::vector<SetValueRequest>>* storedRequests,
        std::list<std::vector<SetValueResult>>* storedResponses) const;

struct PropConfigCmp {
    bool operator()(const VehiclePropConfig& a, const VehiclePropConfig& b) const {
        return (a.prop < b.prop);
+11 −12
Original line number Diff line number Diff line
@@ -30,16 +30,6 @@ using ::aidl::android::hardware::automotive::vehicle::VehiclePropValues;
using ::ndk::ScopedAStatus;
using ::ndk::ScopedFileDescriptor;

template <class T>
std::optional<T> pop(std::list<T>& items) {
    if (items.size() > 0) {
        auto item = std::move(items.front());
        items.pop_front();
        return item;
    }
    return std::nullopt;
}

template <class T>
static ScopedAStatus storeResults(const T& results, std::list<T>* storedResults) {
    T resultsCopy{
@@ -65,8 +55,12 @@ ScopedAStatus MockVehicleCallback::onSetValues(const SetValueResults& results) {
    return storeResults(results, &mSetValueResults);
}

ScopedAStatus MockVehicleCallback::onPropertyEvent(const VehiclePropValues&, int32_t) {
    return ScopedAStatus::ok();
ScopedAStatus MockVehicleCallback::onPropertyEvent(const VehiclePropValues& results,
                                                   int32_t sharedMemoryFileCount) {
    std::scoped_lock<std::mutex> lockGuard(mLock);

    mSharedMemoryFileCount = sharedMemoryFileCount;
    return storeResults(results, &mOnPropertyEventResults);
}

ScopedAStatus MockVehicleCallback::onPropertySetError(const VehiclePropErrors&) {
@@ -83,6 +77,11 @@ std::optional<SetValueResults> MockVehicleCallback::nextSetValueResults() {
    return pop(mSetValueResults);
}

std::optional<VehiclePropValues> MockVehicleCallback::nextOnPropertyEventResults() {
    std::scoped_lock<std::mutex> lockGuard(mLock);
    return pop(mOnPropertyEventResults);
}

}  // namespace vehicle
}  // namespace automotive
}  // namespace hardware
+15 −0
Original line number Diff line number Diff line
@@ -31,6 +31,16 @@ namespace hardware {
namespace automotive {
namespace vehicle {

template <class T>
std::optional<T> pop(std::list<T>& items) {
    if (items.size() > 0) {
        auto item = std::move(items.front());
        items.pop_front();
        return item;
    }
    return std::nullopt;
}

// MockVehicleCallback is a mock VehicleCallback implementation that simply stores the results.
class MockVehicleCallback final
    : public ::aidl::android::hardware::automotive::vehicle::BnVehicleCallback {
@@ -52,6 +62,8 @@ class MockVehicleCallback final
    nextGetValueResults();
    std::optional<::aidl::android::hardware::automotive::vehicle::SetValueResults>
    nextSetValueResults();
    std::optional<::aidl::android::hardware::automotive::vehicle::VehiclePropValues>
    nextOnPropertyEventResults();

  private:
    std::mutex mLock;
@@ -59,6 +71,9 @@ class MockVehicleCallback final
            GUARDED_BY(mLock);
    std::list<::aidl::android::hardware::automotive::vehicle::SetValueResults> mSetValueResults
            GUARDED_BY(mLock);
    std::list<::aidl::android::hardware::automotive::vehicle::VehiclePropValues>
            mOnPropertyEventResults GUARDED_BY(mLock);
    int32_t mSharedMemoryFileCount GUARDED_BY(mLock);
};

}  // namespace vehicle
+207 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.
 */

#include "MockVehicleHardware.h"
#include "MockVehicleCallback.h"

#include <utils/Log.h>

namespace android {
namespace hardware {
namespace automotive {
namespace vehicle {

using ::aidl::android::hardware::automotive::vehicle::GetValueRequest;
using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
using ::aidl::android::hardware::automotive::vehicle::SetValueRequest;
using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
using ::aidl::android::hardware::automotive::vehicle::StatusCode;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;

MockVehicleHardware::~MockVehicleHardware() {
    std::unique_lock<std::mutex> lk(mLock);
    mCv.wait(lk, [this] { return mThreadCount == 0; });
}

std::vector<VehiclePropConfig> MockVehicleHardware::getAllPropertyConfigs() const {
    std::scoped_lock<std::mutex> lockGuard(mLock);
    return mPropertyConfigs;
}

StatusCode MockVehicleHardware::setValues(std::shared_ptr<const SetValuesCallback> callback,
                                          const std::vector<SetValueRequest>& requests) {
    std::scoped_lock<std::mutex> lockGuard(mLock);
    if (StatusCode status = handleRequestsLocked(__func__, callback, requests, &mSetValueRequests,
                                                 &mSetValueResponses);
        status != StatusCode::OK) {
        return status;
    }
    if (mPropertyChangeCallback == nullptr) {
        return StatusCode::OK;
    }
    std::vector<VehiclePropValue> values;
    for (auto& request : requests) {
        values.push_back(request.value);
    }
    (*mPropertyChangeCallback)(values);
    return StatusCode::OK;
}

StatusCode MockVehicleHardware::getValues(std::shared_ptr<const GetValuesCallback> callback,
                                          const std::vector<GetValueRequest>& requests) const {
    std::scoped_lock<std::mutex> lockGuard(mLock);
    return handleRequestsLocked(__func__, callback, requests, &mGetValueRequests,
                                &mGetValueResponses);
}

DumpResult MockVehicleHardware::dump(const std::vector<std::string>&) {
    // TODO(b/200737967): mock this.
    return DumpResult{};
}

StatusCode MockVehicleHardware::checkHealth() {
    // TODO(b/200737967): mock this.
    return StatusCode::OK;
}

void MockVehicleHardware::registerOnPropertyChangeEvent(
        std::unique_ptr<const PropertyChangeCallback> callback) {
    std::scoped_lock<std::mutex> lockGuard(mLock);
    mPropertyChangeCallback = std::move(callback);
}

void MockVehicleHardware::registerOnPropertySetErrorEvent(
        std::unique_ptr<const PropertySetErrorCallback>) {
    // TODO(b/200737967): mock this.
}

void MockVehicleHardware::setPropertyConfigs(const std::vector<VehiclePropConfig>& configs) {
    std::scoped_lock<std::mutex> lockGuard(mLock);
    mPropertyConfigs = configs;
}

void MockVehicleHardware::addGetValueResponses(const std::vector<GetValueResult>& responses) {
    std::scoped_lock<std::mutex> lockGuard(mLock);
    mGetValueResponses.push_back(responses);
}

void MockVehicleHardware::addSetValueResponses(const std::vector<SetValueResult>& responses) {
    std::scoped_lock<std::mutex> lockGuard(mLock);
    mSetValueResponses.push_back(responses);
}

std::vector<GetValueRequest> MockVehicleHardware::nextGetValueRequests() {
    std::scoped_lock<std::mutex> lockGuard(mLock);
    std::optional<std::vector<GetValueRequest>> request = pop(mGetValueRequests);
    if (!request.has_value()) {
        return std::vector<GetValueRequest>();
    }
    return std::move(request.value());
}

std::vector<SetValueRequest> MockVehicleHardware::nextSetValueRequests() {
    std::scoped_lock<std::mutex> lockGuard(mLock);
    std::optional<std::vector<SetValueRequest>> request = pop(mSetValueRequests);
    if (!request.has_value()) {
        return std::vector<SetValueRequest>();
    }
    return std::move(request.value());
}

void MockVehicleHardware::setStatus(const char* functionName, StatusCode status) {
    std::scoped_lock<std::mutex> lockGuard(mLock);
    mStatusByFunctions[functionName] = status;
}

void MockVehicleHardware::setSleepTime(int64_t timeInNano) {
    std::scoped_lock<std::mutex> lockGuard(mLock);
    mSleepTime = timeInNano;
}

template <class ResultType>
StatusCode MockVehicleHardware::returnResponse(
        std::shared_ptr<const std::function<void(std::vector<ResultType>)>> callback,
        std::list<std::vector<ResultType>>* storedResponses) const {
    if (storedResponses->size() > 0) {
        (*callback)(std::move(storedResponses->front()));
        storedResponses->pop_front();
        return StatusCode::OK;
    } else {
        ALOGE("no more response");
        return StatusCode::INTERNAL_ERROR;
    }
}

template StatusCode MockVehicleHardware::returnResponse<GetValueResult>(
        std::shared_ptr<const std::function<void(std::vector<GetValueResult>)>> callback,
        std::list<std::vector<GetValueResult>>* storedResponses) const;

template StatusCode MockVehicleHardware::returnResponse<SetValueResult>(
        std::shared_ptr<const std::function<void(std::vector<SetValueResult>)>> callback,
        std::list<std::vector<SetValueResult>>* storedResponses) const;

template <class RequestType, class ResultType>
StatusCode MockVehicleHardware::handleRequestsLocked(
        const char* functionName,
        std::shared_ptr<const std::function<void(std::vector<ResultType>)>> callback,
        const std::vector<RequestType>& requests,
        std::list<std::vector<RequestType>>* storedRequests,
        std::list<std::vector<ResultType>>* storedResponses) const {
    storedRequests->push_back(requests);
    if (auto it = mStatusByFunctions.find(functionName); it != mStatusByFunctions.end()) {
        if (StatusCode status = it->second; status != StatusCode::OK) {
            return status;
        }
    }

    if (mSleepTime != 0) {
        int64_t sleepTime = mSleepTime;
        mThreadCount++;
        std::thread t([this, callback, sleepTime, storedResponses]() {
            std::this_thread::sleep_for(std::chrono::nanoseconds(sleepTime));
            returnResponse(callback, storedResponses);
            mThreadCount--;
            mCv.notify_one();
        });
        // Detach the thread here so we do not have to maintain the thread object. mThreadCount
        // and mCv make sure we wait for all threads to end before we exit.
        t.detach();
        return StatusCode::OK;

    } else {
        return returnResponse(callback, storedResponses);
    }
}

template StatusCode MockVehicleHardware::handleRequestsLocked<GetValueRequest, GetValueResult>(
        const char* functionName,
        std::shared_ptr<const std::function<void(std::vector<GetValueResult>)>> callback,
        const std::vector<GetValueRequest>& requests,
        std::list<std::vector<GetValueRequest>>* storedRequests,
        std::list<std::vector<GetValueResult>>* storedResponses) const;

template StatusCode MockVehicleHardware::handleRequestsLocked<SetValueRequest, SetValueResult>(
        const char* functionName,
        std::shared_ptr<const std::function<void(std::vector<SetValueResult>)>> callback,
        const std::vector<SetValueRequest>& requests,
        std::list<std::vector<SetValueRequest>>* storedRequests,
        std::list<std::vector<SetValueResult>>* storedResponses) const;

}  // namespace vehicle
}  // namespace automotive
}  // namespace hardware
}  // namespace android
+114 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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_hardware_automotive_vehicle_aidl_impl_vhal_test_MockVehicleHardware_H_
#define android_hardware_automotive_vehicle_aidl_impl_vhal_test_MockVehicleHardware_H_

#include <IVehicleHardware.h>
#include <VehicleHalTypes.h>

#include <android-base/thread_annotations.h>

#include <atomic>
#include <condition_variable>
#include <list>
#include <memory>
#include <mutex>
#include <thread>
#include <unordered_map>
#include <vector>

namespace android {
namespace hardware {
namespace automotive {
namespace vehicle {

class MockVehicleHardware final : public IVehicleHardware {
  public:
    ~MockVehicleHardware();

    std::vector<::aidl::android::hardware::automotive::vehicle::VehiclePropConfig>
    getAllPropertyConfigs() const override;
    ::aidl::android::hardware::automotive::vehicle::StatusCode setValues(
            std::shared_ptr<const SetValuesCallback> callback,
            const std::vector<::aidl::android::hardware::automotive::vehicle::SetValueRequest>&
                    requests) override;
    ::aidl::android::hardware::automotive::vehicle::StatusCode getValues(
            std::shared_ptr<const GetValuesCallback> callback,
            const std::vector<::aidl::android::hardware::automotive::vehicle::GetValueRequest>&
                    requests) const override;
    DumpResult dump(const std::vector<std::string>&) override;
    ::aidl::android::hardware::automotive::vehicle::StatusCode checkHealth() override;
    void registerOnPropertyChangeEvent(
            std::unique_ptr<const PropertyChangeCallback> callback) override;
    void registerOnPropertySetErrorEvent(std::unique_ptr<const PropertySetErrorCallback>) override;

    // Test functions.
    void setPropertyConfigs(
            const std::vector<::aidl::android::hardware::automotive::vehicle::VehiclePropConfig>&
                    configs);
    void addGetValueResponses(
            const std::vector<::aidl::android::hardware::automotive::vehicle::GetValueResult>&
                    responses);
    void addSetValueResponses(
            const std::vector<::aidl::android::hardware::automotive::vehicle::SetValueResult>&
                    responses);
    std::vector<::aidl::android::hardware::automotive::vehicle::GetValueRequest>
    nextGetValueRequests();
    std::vector<::aidl::android::hardware::automotive::vehicle::SetValueRequest>
    nextSetValueRequests();
    void setStatus(const char* functionName,
                   ::aidl::android::hardware::automotive::vehicle::StatusCode status);
    void setSleepTime(int64_t timeInNano);

  private:
    mutable std::mutex mLock;
    mutable std::condition_variable mCv;
    mutable std::atomic<int> mThreadCount;
    std::vector<::aidl::android::hardware::automotive::vehicle::VehiclePropConfig> mPropertyConfigs
            GUARDED_BY(mLock);
    mutable std::list<std::vector<::aidl::android::hardware::automotive::vehicle::GetValueRequest>>
            mGetValueRequests GUARDED_BY(mLock);
    mutable std::list<std::vector<::aidl::android::hardware::automotive::vehicle::GetValueResult>>
            mGetValueResponses GUARDED_BY(mLock);
    mutable std::list<std::vector<::aidl::android::hardware::automotive::vehicle::SetValueRequest>>
            mSetValueRequests GUARDED_BY(mLock);
    mutable std::list<std::vector<::aidl::android::hardware::automotive::vehicle::SetValueResult>>
            mSetValueResponses GUARDED_BY(mLock);
    std::unordered_map<const char*, ::aidl::android::hardware::automotive::vehicle::StatusCode>
            mStatusByFunctions GUARDED_BY(mLock);
    int64_t mSleepTime GUARDED_BY(mLock) = 0;
    std::unique_ptr<const PropertyChangeCallback> mPropertyChangeCallback GUARDED_BY(mLock);

    template <class ResultType>
    ::aidl::android::hardware::automotive::vehicle::StatusCode returnResponse(
            std::shared_ptr<const std::function<void(std::vector<ResultType>)>> callback,
            std::list<std::vector<ResultType>>* storedResponses) const;
    template <class RequestType, class ResultType>
    ::aidl::android::hardware::automotive::vehicle::StatusCode handleRequestsLocked(
            const char* functionName,
            std::shared_ptr<const std::function<void(std::vector<ResultType>)>> callback,
            const std::vector<RequestType>& requests,
            std::list<std::vector<RequestType>>* storedRequests,
            std::list<std::vector<ResultType>>* storedResponses) const REQUIRES(mLock);
};

}  // namespace vehicle
}  // namespace automotive
}  // namespace hardware
}  // namespace android

#endif  // android_hardware_automotive_vehicle_aidl_impl_vhal_test_MockVehicleHardware_H_