• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 "VibratorControllerTest"
18 
19 #include <aidl/android/hardware/vibrator/IVibrator.h>
20 
21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
23 
24 #include <utils/Log.h>
25 #include <thread>
26 
27 #include <vibratorservice/VibratorController.h>
28 
29 #include "test_mocks.h"
30 #include "test_utils.h"
31 
32 using ::aidl::android::hardware::vibrator::Effect;
33 using ::aidl::android::hardware::vibrator::EffectStrength;
34 using ::aidl::android::hardware::vibrator::IVibrator;
35 
36 using namespace android;
37 using namespace testing;
38 
__anonc94ddda40102() 39 const auto kReturnOk = []() { return ndk::ScopedAStatus::ok(); };
__anonc94ddda40202() 40 const auto kReturnUnsupported = []() {
41     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
42 };
__anonc94ddda40302() 43 const auto kReturnTransactionFailed = []() {
44     return ndk::ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
45 };
__anonc94ddda40402() 46 const auto kReturnUnknownTransaction = []() {
47     return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_TRANSACTION);
48 };
__anonc94ddda40502() 49 const auto kReturnIllegalArgument = []() {
50     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
51 };
52 
53 // -------------------------------------------------------------------------------------------------
54 
55 /* Provides mock IVibrator instance for testing. */
56 class FakeVibratorProvider : public vibrator::VibratorProvider {
57 public:
FakeVibratorProvider()58     FakeVibratorProvider()
59           : mIsDeclared(true),
60             mMockVibrator(ndk::SharedRefBase::make<StrictMock<vibrator::MockIVibrator>>()),
61             mConnectCount(0),
62             mReconnectCount(0) {}
63     virtual ~FakeVibratorProvider() = default;
64 
isDeclared()65     bool isDeclared() override { return mIsDeclared; }
66 
waitForVibrator()67     std::shared_ptr<IVibrator> waitForVibrator() override {
68         mConnectCount++;
69         return mIsDeclared ? mMockVibrator : nullptr;
70     }
71 
checkForVibrator()72     std::shared_ptr<IVibrator> checkForVibrator() override {
73         mReconnectCount++;
74         return mIsDeclared ? mMockVibrator : nullptr;
75     }
76 
setDeclared(bool isDeclared)77     void setDeclared(bool isDeclared) { mIsDeclared = isDeclared; }
78 
getConnectCount()79     int32_t getConnectCount() { return mConnectCount; }
80 
getReconnectCount()81     int32_t getReconnectCount() { return mReconnectCount; }
82 
getMockVibrator()83     std::shared_ptr<StrictMock<vibrator::MockIVibrator>> getMockVibrator() { return mMockVibrator; }
84 
85 private:
86     bool mIsDeclared;
87     std::shared_ptr<StrictMock<vibrator::MockIVibrator>> mMockVibrator;
88     int32_t mConnectCount;
89     int32_t mReconnectCount;
90 };
91 
92 // -------------------------------------------------------------------------------------------------
93 
94 class VibratorControllerTest : public Test {
95 public:
SetUp()96     void SetUp() override {
97         mProvider = std::make_shared<FakeVibratorProvider>();
98         mController = std::make_unique<vibrator::VibratorController>(mProvider);
99         ASSERT_NE(mController, nullptr);
100     }
101 
102 protected:
103     std::shared_ptr<FakeVibratorProvider> mProvider = nullptr;
104     std::unique_ptr<vibrator::VibratorController> mController = nullptr;
105 };
106 
107 // -------------------------------------------------------------------------------------------------
108 
TEST_F(VibratorControllerTest,TestInitServiceDeclared)109 TEST_F(VibratorControllerTest, TestInitServiceDeclared) {
110     ASSERT_TRUE(mController->init());
111     ASSERT_EQ(1, mProvider->getConnectCount());
112     ASSERT_EQ(0, mProvider->getReconnectCount());
113 
114     // Noop when wrapper was already initialized.
115     ASSERT_TRUE(mController->init());
116     ASSERT_EQ(1, mProvider->getConnectCount());
117     ASSERT_EQ(0, mProvider->getReconnectCount());
118 }
119 
TEST_F(VibratorControllerTest,TestInitServiceNotDeclared)120 TEST_F(VibratorControllerTest, TestInitServiceNotDeclared) {
121     mProvider->setDeclared(false);
122 
123     ASSERT_FALSE(mController->init());
124     ASSERT_EQ(0, mProvider->getConnectCount());
125     ASSERT_EQ(0, mProvider->getReconnectCount());
126 
127     ASSERT_FALSE(mController->init());
128     ASSERT_EQ(0, mProvider->getConnectCount());
129     ASSERT_EQ(0, mProvider->getReconnectCount());
130 }
131 
TEST_F(VibratorControllerTest,TestFirstCallTriggersInit)132 TEST_F(VibratorControllerTest, TestFirstCallTriggersInit) {
133     EXPECT_CALL(*mProvider->getMockVibrator().get(), off())
134             .Times(Exactly(1))
135             .WillRepeatedly(kReturnOk);
136 
137     auto status = mController->off();
138     ASSERT_TRUE(status.isOk());
139     ASSERT_EQ(1, mProvider->getConnectCount());
140 }
141 
TEST_F(VibratorControllerTest,TestSuccessfulResultDoesNotRetry)142 TEST_F(VibratorControllerTest, TestSuccessfulResultDoesNotRetry) {
143     EXPECT_CALL(*mProvider->getMockVibrator().get(), off())
144             .Times(Exactly(1))
145             .WillRepeatedly(kReturnOk);
146 
147     auto status = mController->off();
148     ASSERT_TRUE(status.isOk());
149     ASSERT_EQ(0, mProvider->getReconnectCount());
150 }
151 
TEST_F(VibratorControllerTest,TestUnsupportedOperationResultDoesNotRetry)152 TEST_F(VibratorControllerTest, TestUnsupportedOperationResultDoesNotRetry) {
153     EXPECT_CALL(*mProvider->getMockVibrator().get(), off())
154             .Times(Exactly(1))
155             .WillRepeatedly(kReturnUnsupported);
156 
157     auto status = mController->off();
158     ASSERT_FALSE(status.isOk());
159     ASSERT_EQ(0, mProvider->getReconnectCount());
160 }
161 
TEST_F(VibratorControllerTest,TestUnknownTransactionResultDoesNotRetry)162 TEST_F(VibratorControllerTest, TestUnknownTransactionResultDoesNotRetry) {
163     EXPECT_CALL(*mProvider->getMockVibrator().get(), off())
164             .Times(Exactly(1))
165             .WillRepeatedly(kReturnUnknownTransaction);
166 
167     auto status = mController->off();
168     ASSERT_FALSE(status.isOk());
169     ASSERT_EQ(0, mProvider->getReconnectCount());
170 }
171 
TEST_F(VibratorControllerTest,TestOperationFailedDoesNotRetry)172 TEST_F(VibratorControllerTest, TestOperationFailedDoesNotRetry) {
173     EXPECT_CALL(*mProvider->getMockVibrator().get(), off())
174             .Times(Exactly(1))
175             .WillRepeatedly(kReturnIllegalArgument);
176 
177     auto status = mController->off();
178     ASSERT_FALSE(status.isOk());
179     ASSERT_EQ(0, mProvider->getReconnectCount());
180 }
181 
TEST_F(VibratorControllerTest,TestTransactionFailedRetriesOnlyOnce)182 TEST_F(VibratorControllerTest, TestTransactionFailedRetriesOnlyOnce) {
183     EXPECT_CALL(*mProvider->getMockVibrator().get(), off())
184             .Times(Exactly(2))
185             .WillRepeatedly(kReturnTransactionFailed);
186 
187     auto status = mController->off();
188     ASSERT_FALSE(status.isOk());
189     ASSERT_EQ(1, mProvider->getReconnectCount());
190 }
191 
TEST_F(VibratorControllerTest,TestTransactionFailedThenSucceedsReturnsSuccessAfterRetries)192 TEST_F(VibratorControllerTest, TestTransactionFailedThenSucceedsReturnsSuccessAfterRetries) {
193     EXPECT_CALL(*mProvider->getMockVibrator().get(), off())
194             .Times(Exactly(2))
195             .WillOnce(kReturnTransactionFailed)
196             .WillRepeatedly(kReturnOk);
197 
198     auto status = mController->off();
199     ASSERT_TRUE(status.isOk());
200     ASSERT_EQ(1, mProvider->getReconnectCount());
201 }
202 
TEST_F(VibratorControllerTest,TestOff)203 TEST_F(VibratorControllerTest, TestOff) {
204     EXPECT_CALL(*mProvider->getMockVibrator().get(), off())
205             .Times(Exactly(1))
206             .WillRepeatedly(kReturnOk);
207 
208     auto status = mController->off();
209     ASSERT_TRUE(status.isOk());
210 }
211 
TEST_F(VibratorControllerTest,TestSetAmplitude)212 TEST_F(VibratorControllerTest, TestSetAmplitude) {
213     EXPECT_CALL(*mProvider->getMockVibrator().get(), setAmplitude(Eq(0.1f)))
214             .Times(Exactly(1))
215             .WillRepeatedly(kReturnOk);
216     EXPECT_CALL(*mProvider->getMockVibrator().get(), setAmplitude(Eq(0.2f)))
217             .Times(Exactly(1))
218             .WillRepeatedly(kReturnIllegalArgument);
219 
220     ASSERT_TRUE(mController->setAmplitude(0.1f).isOk());
221     ASSERT_FALSE(mController->setAmplitude(0.2f).isOk());
222 }
223 
TEST_F(VibratorControllerTest,TestSetExternalControl)224 TEST_F(VibratorControllerTest, TestSetExternalControl) {
225     EXPECT_CALL(*mProvider->getMockVibrator().get(), setExternalControl(Eq(false)))
226             .Times(Exactly(1))
227             .WillRepeatedly(kReturnOk);
228     EXPECT_CALL(*mProvider->getMockVibrator().get(), setExternalControl(Eq(true)))
229             .Times(Exactly(1))
230             .WillRepeatedly(kReturnIllegalArgument);
231 
232     ASSERT_TRUE(mController->setExternalControl(false).isOk());
233     ASSERT_FALSE(mController->setExternalControl(true).isOk());
234 }
235 
TEST_F(VibratorControllerTest,TestAlwaysOnEnable)236 TEST_F(VibratorControllerTest, TestAlwaysOnEnable) {
237     EXPECT_CALL(*mProvider->getMockVibrator().get(),
238                 alwaysOnEnable(Eq(1), Eq(Effect::CLICK), Eq(EffectStrength::LIGHT)))
239             .Times(Exactly(1))
240             .WillRepeatedly(kReturnOk);
241     EXPECT_CALL(*mProvider->getMockVibrator().get(),
242                 alwaysOnEnable(Eq(2), Eq(Effect::TICK), Eq(EffectStrength::MEDIUM)))
243             .Times(Exactly(1))
244             .WillRepeatedly(kReturnIllegalArgument);
245 
246     ASSERT_TRUE(mController->alwaysOnEnable(1, Effect::CLICK, EffectStrength::LIGHT).isOk());
247     ASSERT_FALSE(mController->alwaysOnEnable(2, Effect::TICK, EffectStrength::MEDIUM).isOk());
248 }
249