1 /*
2  * Copyright (C) 2021 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 #include "MockVehicleCallback.h"
18 
19 #include <android-base/thread_annotations.h>
20 #include <chrono>
21 
22 namespace android {
23 namespace hardware {
24 namespace automotive {
25 namespace vehicle {
26 
27 namespace {
28 
29 using ::aidl::android::hardware::automotive::vehicle::GetValueResults;
30 using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
31 using ::aidl::android::hardware::automotive::vehicle::VehiclePropErrors;
32 using ::aidl::android::hardware::automotive::vehicle::VehiclePropValues;
33 using ::android::base::ScopedLockAssertion;
34 using ::ndk::ScopedAStatus;
35 using ::ndk::ScopedFileDescriptor;
36 
37 template <class T>
storeResults(const T & results,std::list<T> * storedResults)38 static ScopedAStatus storeResults(const T& results, std::list<T>* storedResults) {
39     T resultsCopy{
40             .payloads = results.payloads,
41     };
42     int fd = results.sharedMemoryFd.get();
43     if (fd != -1) {
44         resultsCopy.sharedMemoryFd = ScopedFileDescriptor(dup(fd));
45     }
46     storedResults->push_back(std::move(resultsCopy));
47     return ScopedAStatus::ok();
48 }
49 
50 }  // namespace
51 
onGetValues(const GetValueResults & results)52 ScopedAStatus MockVehicleCallback::onGetValues(const GetValueResults& results) {
53     ScopedAStatus result;
54     {
55         std::scoped_lock<std::mutex> lockGuard(mLock);
56         result = storeResults(results, &mGetValueResults);
57     }
58     mCond.notify_all();
59     return result;
60 }
61 
onSetValues(const SetValueResults & results)62 ScopedAStatus MockVehicleCallback::onSetValues(const SetValueResults& results) {
63     ScopedAStatus result;
64     {
65         std::scoped_lock<std::mutex> lockGuard(mLock);
66         result = storeResults(results, &mSetValueResults);
67     }
68     mCond.notify_all();
69     return result;
70 }
71 
onPropertyEvent(const VehiclePropValues & results,int32_t sharedMemoryFileCount)72 ScopedAStatus MockVehicleCallback::onPropertyEvent(const VehiclePropValues& results,
73                                                    int32_t sharedMemoryFileCount) {
74     ScopedAStatus result;
75     {
76         std::scoped_lock<std::mutex> lockGuard(mLock);
77         mSharedMemoryFileCount = sharedMemoryFileCount;
78         result = storeResults(results, &mOnPropertyEventResults);
79     }
80     mCond.notify_all();
81     return result;
82 }
83 
onPropertySetError(const VehiclePropErrors & results)84 ScopedAStatus MockVehicleCallback::onPropertySetError(const VehiclePropErrors& results) {
85     ScopedAStatus result;
86     {
87         std::scoped_lock<std::mutex> lockGuard(mLock);
88         result = storeResults(results, &mOnPropertySetErrorResults);
89     }
90     mCond.notify_all();
91     return result;
92 }
93 
nextGetValueResults()94 std::optional<GetValueResults> MockVehicleCallback::nextGetValueResults() {
95     std::scoped_lock<std::mutex> lockGuard(mLock);
96     return pop(mGetValueResults);
97 }
98 
nextSetValueResults()99 std::optional<SetValueResults> MockVehicleCallback::nextSetValueResults() {
100     std::scoped_lock<std::mutex> lockGuard(mLock);
101     return pop(mSetValueResults);
102 }
103 
nextOnPropertyEventResults()104 std::optional<VehiclePropValues> MockVehicleCallback::nextOnPropertyEventResults() {
105     std::scoped_lock<std::mutex> lockGuard(mLock);
106     return pop(mOnPropertyEventResults);
107 }
108 
countOnPropertyEventResults()109 size_t MockVehicleCallback::countOnPropertyEventResults() {
110     std::scoped_lock<std::mutex> lockGuard(mLock);
111     return mOnPropertyEventResults.size();
112 }
113 
nextOnPropertySetErrorResults()114 std::optional<VehiclePropErrors> MockVehicleCallback::nextOnPropertySetErrorResults() {
115     std::scoped_lock<std::mutex> lockGuard(mLock);
116     return pop(mOnPropertySetErrorResults);
117 }
118 
countOnPropertySetErrorResults()119 size_t MockVehicleCallback::countOnPropertySetErrorResults() {
120     std::scoped_lock<std::mutex> lockGuard(mLock);
121     return mOnPropertySetErrorResults.size();
122 }
123 
waitForSetValueResults(size_t size,size_t timeoutInNano)124 bool MockVehicleCallback::waitForSetValueResults(size_t size, size_t timeoutInNano) {
125     std::unique_lock lk(mLock);
126     return mCond.wait_for(lk, std::chrono::nanoseconds(timeoutInNano), [this, size] {
127         ScopedLockAssertion lockAssertion(mLock);
128         return mSetValueResults.size() >= size;
129     });
130 }
131 
waitForGetValueResults(size_t size,size_t timeoutInNano)132 bool MockVehicleCallback::waitForGetValueResults(size_t size, size_t timeoutInNano) {
133     std::unique_lock lk(mLock);
134     return mCond.wait_for(lk, std::chrono::nanoseconds(timeoutInNano), [this, size] {
135         ScopedLockAssertion lockAssertion(mLock);
136         return mGetValueResults.size() >= size;
137     });
138 }
139 
waitForOnPropertyEventResults(size_t size,size_t timeoutInNano)140 bool MockVehicleCallback::waitForOnPropertyEventResults(size_t size, size_t timeoutInNano) {
141     std::unique_lock lk(mLock);
142     return mCond.wait_for(lk, std::chrono::nanoseconds(timeoutInNano), [this, size] {
143         ScopedLockAssertion lockAssertion(mLock);
144         return mOnPropertyEventResults.size() >= size;
145     });
146 }
147 
148 }  // namespace vehicle
149 }  // namespace automotive
150 }  // namespace hardware
151 }  // namespace android
152