Support latency in MockVehicleHardware.

Allow MockVehicleHardware to sleep for some time before returning
results to VHAL, so that we could test timeout behavior.

Test: atest DefaultVehicleHalTest
Bug: 200737967
Change-Id: I1198b80f1c08f664bc2fcdb6b590f6d84bc75384
diff --git a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
index 26380b3..6c99ceb 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
@@ -31,6 +31,7 @@
 #include <memory>
 #include <mutex>
 #include <optional>
+#include <thread>
 #include <unordered_map>
 #include <vector>
 
@@ -48,6 +49,7 @@
 using ::aidl::android::hardware::automotive::vehicle::IVehicle;
 using ::aidl::android::hardware::automotive::vehicle::IVehicleCallback;
 using ::aidl::android::hardware::automotive::vehicle::SetValueRequest;
+using ::aidl::android::hardware::automotive::vehicle::SetValueRequests;
 using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
 using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
 using ::aidl::android::hardware::automotive::vehicle::StatusCode;
@@ -83,16 +85,25 @@
         return mPropertyConfigs;
     }
 
+    ~MockVehicleHardware() {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        for (auto& thread : mThreads) {
+            thread.join();
+        }
+    }
+
     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);
+        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);
+        return handleRequests(__func__, callback, requests, &mGetValueRequests,
+                              &mGetValueResponses);
     }
 
     DumpResult dump(const std::vector<std::string>&) override {
@@ -124,6 +135,11 @@
         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);
@@ -147,6 +163,11 @@
         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);
@@ -155,28 +176,30 @@
     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;
+            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);
+            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();
+        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");
@@ -186,42 +209,52 @@
 
 template StatusCode MockVehicleHardware::returnResponse<GetValueResult>(
         std::shared_ptr<const std::function<void(std::vector<GetValueResult>)>> callback,
-        std::list<std::vector<GetValueResult>>& storedResponses) const;
+        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;
+        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);
+        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;
         }
     }
 
-    return returnResponse(callback, storedResponses);
+    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;
+        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;
+        std::list<std::vector<SetValueRequest>>* storedRequests,
+        std::list<std::vector<SetValueResult>>* storedResponses) const;
 
 struct PropConfigCmp {
     bool operator()(const VehiclePropConfig& a, const VehiclePropConfig& b) const {