Merge "Refactor MockVehicleHardware into separate files."
diff --git a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
index d763f03..d3186fd 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
@@ -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 @@
 // 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);
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp
index ca366cd..5e3e03c 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp
@@ -31,16 +31,6 @@
 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{
             .payloads = results.payloads,
@@ -65,8 +55,12 @@
     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 @@
     return pop(mSetValueResults);
 }
 
+std::optional<VehiclePropValues> MockVehicleCallback::nextOnPropertyEventResults() {
+    std::scoped_lock<std::mutex> lockGuard(mLock);
+    return pop(mOnPropertyEventResults);
+}
+
 }  // namespace vehicle
 }  // namespace automotive
 }  // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h
index 916575a..c83164f 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h
+++ b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h
@@ -31,6 +31,16 @@
 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 @@
     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 @@
             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
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.cpp b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.cpp
new file mode 100644
index 0000000..7d992af
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.cpp
@@ -0,0 +1,207 @@
+/*
+ * 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
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.h b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.h
new file mode 100644
index 0000000..283d1f9
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.h
@@ -0,0 +1,114 @@
+/*
+ * 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_