xref: /aosp_15_r20/frameworks/native/services/vibratorservice/test/VibratorManagerHalControllerTest.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
2  * Copyright (C) 2020 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 #define LOG_TAG "VibratorManagerHalControllerTest"
18 
19 #include <cutils/atomic.h>
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22 
23 #include <utils/Log.h>
24 
25 #include <vibratorservice/VibratorManagerHalController.h>
26 
27 #include "test_mocks.h"
28 #include "test_utils.h"
29 
30 using aidl::android::hardware::vibrator::IVibrationSession;
31 using aidl::android::hardware::vibrator::VibrationSessionConfig;
32 using android::vibrator::HalController;
33 
34 using namespace android;
35 using namespace testing;
36 
37 static constexpr int MAX_ATTEMPTS = 2;
38 static const std::vector<int32_t> VIBRATOR_IDS = {1, 2};
39 static const VibrationSessionConfig SESSION_CONFIG;
40 static constexpr int VIBRATOR_ID = 1;
41 
42 // -------------------------------------------------------------------------------------------------
43 
44 class MockManagerHalWrapper : public vibrator::ManagerHalWrapper {
45 public:
46     MOCK_METHOD(void, tryReconnect, (), (override));
47     MOCK_METHOD(vibrator::HalResult<void>, ping, (), (override));
48     MOCK_METHOD(vibrator::HalResult<vibrator::ManagerCapabilities>, getCapabilities, (),
49                 (override));
50     MOCK_METHOD(vibrator::HalResult<std::vector<int32_t>>, getVibratorIds, (), (override));
51     MOCK_METHOD(vibrator::HalResult<std::shared_ptr<HalController>>, getVibrator, (int32_t id),
52                 (override));
53     MOCK_METHOD(vibrator::HalResult<void>, prepareSynced, (const std::vector<int32_t>& ids),
54                 (override));
55     MOCK_METHOD(vibrator::HalResult<void>, triggerSynced,
56                 (const std::function<void()>& completionCallback), (override));
57     MOCK_METHOD(vibrator::HalResult<void>, cancelSynced, (), (override));
58     MOCK_METHOD(vibrator::HalResult<std::shared_ptr<IVibrationSession>>, startSession,
59                 (const std::vector<int32_t>& ids, const VibrationSessionConfig& s,
60                  const std::function<void()>& completionCallback),
61                 (override));
62     MOCK_METHOD(vibrator::HalResult<void>, clearSessions, (), (override));
63 };
64 
65 // -------------------------------------------------------------------------------------------------
66 
67 class VibratorManagerHalControllerTest : public Test {
68 public:
SetUp()69     void SetUp() override {
70         mConnectCounter = 0;
71         auto callbackScheduler = std::make_shared<vibrator::CallbackScheduler>();
72         mMockHal = std::make_shared<StrictMock<MockManagerHalWrapper>>();
73         auto connector = [this](std::shared_ptr<vibrator::CallbackScheduler>) {
74             android_atomic_inc(&mConnectCounter);
75             return mMockHal;
76         };
77         mController = std::make_unique<vibrator::ManagerHalController>(std::move(callbackScheduler),
78                                                                        connector);
79         ASSERT_NE(mController, nullptr);
80     }
81 
82 protected:
83     int32_t mConnectCounter;
84     std::shared_ptr<MockManagerHalWrapper> mMockHal;
85     std::unique_ptr<vibrator::ManagerHalController> mController;
86 
setHalExpectations(int32_t cardinality,vibrator::HalResult<void> voidResult,vibrator::HalResult<vibrator::ManagerCapabilities> capabilitiesResult,vibrator::HalResult<std::vector<int32_t>> idsResult,vibrator::HalResult<std::shared_ptr<HalController>> vibratorResult,vibrator::HalResult<std::shared_ptr<IVibrationSession>> sessionResult)87     void setHalExpectations(int32_t cardinality, vibrator::HalResult<void> voidResult,
88                             vibrator::HalResult<vibrator::ManagerCapabilities> capabilitiesResult,
89                             vibrator::HalResult<std::vector<int32_t>> idsResult,
90                             vibrator::HalResult<std::shared_ptr<HalController>> vibratorResult,
91                             vibrator::HalResult<std::shared_ptr<IVibrationSession>> sessionResult) {
92         EXPECT_CALL(*mMockHal.get(), ping())
93                 .Times(Exactly(cardinality))
94                 .WillRepeatedly(Return(voidResult));
95         EXPECT_CALL(*mMockHal.get(), getCapabilities())
96                 .Times(Exactly(cardinality))
97                 .WillRepeatedly(Return(capabilitiesResult));
98         EXPECT_CALL(*mMockHal.get(), getVibratorIds())
99                 .Times(Exactly(cardinality))
100                 .WillRepeatedly(Return(idsResult));
101         EXPECT_CALL(*mMockHal.get(), getVibrator(_))
102                 .Times(Exactly(cardinality))
103                 .WillRepeatedly(Return(vibratorResult));
104         EXPECT_CALL(*mMockHal.get(), prepareSynced(_))
105                 .Times(Exactly(cardinality))
106                 .WillRepeatedly(Return(voidResult));
107         EXPECT_CALL(*mMockHal.get(), triggerSynced(_))
108                 .Times(Exactly(cardinality))
109                 .WillRepeatedly(Return(voidResult));
110         EXPECT_CALL(*mMockHal.get(), cancelSynced())
111                 .Times(Exactly(cardinality))
112                 .WillRepeatedly(Return(voidResult));
113         EXPECT_CALL(*mMockHal.get(), startSession(_, _, _))
114                 .Times(Exactly(cardinality))
115                 .WillRepeatedly(Return(sessionResult));
116         EXPECT_CALL(*mMockHal.get(), clearSessions())
117                 .Times(Exactly(cardinality))
118                 .WillRepeatedly(Return(voidResult));
119 
120         if (cardinality > 1) {
121             // One reconnection for each retry.
122             EXPECT_CALL(*mMockHal.get(), tryReconnect()).Times(Exactly(9 * (cardinality - 1)));
123         } else {
124             EXPECT_CALL(*mMockHal.get(), tryReconnect()).Times(Exactly(0));
125         }
126     }
127 };
128 
129 // -------------------------------------------------------------------------------------------------
130 
TEST_F(VibratorManagerHalControllerTest,TestInit)131 TEST_F(VibratorManagerHalControllerTest, TestInit) {
132     mController->init();
133     ASSERT_EQ(1, mConnectCounter);
134 
135     // Noop when wrapper was already initialized.
136     mController->init();
137     ASSERT_EQ(1, mConnectCounter);
138 }
139 
TEST_F(VibratorManagerHalControllerTest,TestApiCallsAreForwardedToHal)140 TEST_F(VibratorManagerHalControllerTest, TestApiCallsAreForwardedToHal) {
141     setHalExpectations(/* cardinality= */ 1, vibrator::HalResult<void>::ok(),
142                        vibrator::HalResult<vibrator::ManagerCapabilities>::ok(
143                                vibrator::ManagerCapabilities::SYNC),
144                        vibrator::HalResult<std::vector<int32_t>>::ok(VIBRATOR_IDS),
145                        vibrator::HalResult<std::shared_ptr<HalController>>::ok(nullptr),
146                        vibrator::HalResult<std::shared_ptr<IVibrationSession>>::ok(nullptr));
147 
148     ASSERT_TRUE(mController->ping().isOk());
149 
150     auto getCapabilitiesResult = mController->getCapabilities();
151     ASSERT_TRUE(getCapabilitiesResult.isOk());
152     ASSERT_EQ(vibrator::ManagerCapabilities::SYNC, getCapabilitiesResult.value());
153 
154     auto getVibratorIdsResult = mController->getVibratorIds();
155     ASSERT_TRUE(getVibratorIdsResult.isOk());
156     ASSERT_EQ(VIBRATOR_IDS, getVibratorIdsResult.value());
157 
158     auto getVibratorResult = mController->getVibrator(VIBRATOR_ID);
159     ASSERT_TRUE(getVibratorResult.isOk());
160     ASSERT_EQ(nullptr, getVibratorResult.value());
161 
162     ASSERT_TRUE(mController->prepareSynced(VIBRATOR_IDS).isOk());
163     ASSERT_TRUE(mController->triggerSynced([]() {}).isOk());
164     ASSERT_TRUE(mController->cancelSynced().isOk());
165     ASSERT_TRUE(mController->startSession(VIBRATOR_IDS, SESSION_CONFIG, []() {}).isOk());
166     ASSERT_TRUE(mController->clearSessions().isOk());
167 
168     ASSERT_EQ(1, mConnectCounter);
169 }
170 
TEST_F(VibratorManagerHalControllerTest,TestUnsupportedApiResultDoesNotResetHalConnection)171 TEST_F(VibratorManagerHalControllerTest, TestUnsupportedApiResultDoesNotResetHalConnection) {
172     setHalExpectations(/* cardinality= */ 1, vibrator::HalResult<void>::unsupported(),
173                        vibrator::HalResult<vibrator::ManagerCapabilities>::unsupported(),
174                        vibrator::HalResult<std::vector<int32_t>>::unsupported(),
175                        vibrator::HalResult<std::shared_ptr<HalController>>::unsupported(),
176                        vibrator::HalResult<std::shared_ptr<IVibrationSession>>::unsupported());
177 
178     ASSERT_TRUE(mController->ping().isUnsupported());
179     ASSERT_TRUE(mController->getCapabilities().isUnsupported());
180     ASSERT_TRUE(mController->getVibratorIds().isUnsupported());
181     ASSERT_TRUE(mController->getVibrator(VIBRATOR_ID).isUnsupported());
182     ASSERT_TRUE(mController->prepareSynced(VIBRATOR_IDS).isUnsupported());
183     ASSERT_TRUE(mController->triggerSynced([]() {}).isUnsupported());
184     ASSERT_TRUE(mController->cancelSynced().isUnsupported());
185     ASSERT_TRUE(mController->startSession(VIBRATOR_IDS, SESSION_CONFIG, []() {}).isUnsupported());
186     ASSERT_TRUE(mController->clearSessions().isUnsupported());
187 
188     ASSERT_EQ(1, mConnectCounter);
189 }
190 
TEST_F(VibratorManagerHalControllerTest,TestOperationFailedApiResultDoesNotResetHalConnection)191 TEST_F(VibratorManagerHalControllerTest, TestOperationFailedApiResultDoesNotResetHalConnection) {
192     setHalExpectations(/* cardinality= */ 1, vibrator::HalResult<void>::failed("msg"),
193                        vibrator::HalResult<vibrator::ManagerCapabilities>::failed("msg"),
194                        vibrator::HalResult<std::vector<int32_t>>::failed("msg"),
195                        vibrator::HalResult<std::shared_ptr<HalController>>::failed("msg"),
196                        vibrator::HalResult<std::shared_ptr<IVibrationSession>>::failed("msg"));
197 
198     ASSERT_TRUE(mController->ping().isFailed());
199     ASSERT_TRUE(mController->getCapabilities().isFailed());
200     ASSERT_TRUE(mController->getVibratorIds().isFailed());
201     ASSERT_TRUE(mController->getVibrator(VIBRATOR_ID).isFailed());
202     ASSERT_TRUE(mController->prepareSynced(VIBRATOR_IDS).isFailed());
203     ASSERT_TRUE(mController->triggerSynced([]() {}).isFailed());
204     ASSERT_TRUE(mController->cancelSynced().isFailed());
205     ASSERT_TRUE(mController->startSession(VIBRATOR_IDS, SESSION_CONFIG, []() {}).isFailed());
206     ASSERT_TRUE(mController->clearSessions().isFailed());
207 
208     ASSERT_EQ(1, mConnectCounter);
209 }
210 
TEST_F(VibratorManagerHalControllerTest,TestTransactionFailedApiResultResetsHalConnection)211 TEST_F(VibratorManagerHalControllerTest, TestTransactionFailedApiResultResetsHalConnection) {
212     setHalExpectations(MAX_ATTEMPTS, vibrator::HalResult<void>::transactionFailed("m"),
213                        vibrator::HalResult<vibrator::ManagerCapabilities>::transactionFailed("m"),
214                        vibrator::HalResult<std::vector<int32_t>>::transactionFailed("m"),
215                        vibrator::HalResult<std::shared_ptr<HalController>>::transactionFailed("m"),
216                        vibrator::HalResult<std::shared_ptr<IVibrationSession>>::transactionFailed(
217                                "m"));
218 
219     ASSERT_TRUE(mController->ping().isFailed());
220     ASSERT_TRUE(mController->getCapabilities().isFailed());
221     ASSERT_TRUE(mController->getVibratorIds().isFailed());
222     ASSERT_TRUE(mController->getVibrator(VIBRATOR_ID).isFailed());
223     ASSERT_TRUE(mController->prepareSynced(VIBRATOR_IDS).isFailed());
224     ASSERT_TRUE(mController->triggerSynced([]() {}).isFailed());
225     ASSERT_TRUE(mController->cancelSynced().isFailed());
226     ASSERT_TRUE(mController->startSession(VIBRATOR_IDS, SESSION_CONFIG, []() {}).isFailed());
227     ASSERT_TRUE(mController->clearSessions().isFailed());
228 
229     ASSERT_EQ(1, mConnectCounter);
230 }
231 
TEST_F(VibratorManagerHalControllerTest,TestFailedApiResultReturnsSuccessAfterRetries)232 TEST_F(VibratorManagerHalControllerTest, TestFailedApiResultReturnsSuccessAfterRetries) {
233     {
234         InSequence seq;
235         EXPECT_CALL(*mMockHal.get(), ping())
236                 .Times(Exactly(1))
237                 .WillRepeatedly(Return(vibrator::HalResult<void>::transactionFailed("message")));
238         EXPECT_CALL(*mMockHal.get(), tryReconnect()).Times(Exactly(1));
239         EXPECT_CALL(*mMockHal.get(), ping())
240                 .Times(Exactly(1))
241                 .WillRepeatedly(Return(vibrator::HalResult<void>::ok()));
242     }
243 
244     ASSERT_TRUE(mController->ping().isOk());
245     ASSERT_EQ(1, mConnectCounter);
246 }
247 
TEST_F(VibratorManagerHalControllerTest,TestMultiThreadConnectsOnlyOnce)248 TEST_F(VibratorManagerHalControllerTest, TestMultiThreadConnectsOnlyOnce) {
249     ASSERT_EQ(0, mConnectCounter);
250 
251     EXPECT_CALL(*mMockHal.get(), ping())
252             .Times(Exactly(10))
253             .WillRepeatedly(Return(vibrator::HalResult<void>::ok()));
254 
255     std::vector<std::thread> threads;
256     for (int i = 0; i < 10; i++) {
257         threads.push_back(std::thread([&]() { ASSERT_TRUE(mController->ping().isOk()); }));
258     }
259     std::for_each(threads.begin(), threads.end(), [](std::thread& t) { t.join(); });
260 
261     // Connector was called only by the first thread to use the api.
262     ASSERT_EQ(1, mConnectCounter);
263 }
264