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 "VibratorManagerHalWrapperAidlTest"
18
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21
22 #include <utils/Log.h>
23
24 #include <vibratorservice/VibratorManagerHalWrapper.h>
25
26 #include "test_mocks.h"
27 #include "test_utils.h"
28
29 using aidl::android::hardware::vibrator::Braking;
30 using aidl::android::hardware::vibrator::CompositeEffect;
31 using aidl::android::hardware::vibrator::CompositePrimitive;
32 using aidl::android::hardware::vibrator::Effect;
33 using aidl::android::hardware::vibrator::EffectStrength;
34 using aidl::android::hardware::vibrator::IVibrationSession;
35 using aidl::android::hardware::vibrator::IVibrator;
36 using aidl::android::hardware::vibrator::IVibratorCallback;
37 using aidl::android::hardware::vibrator::IVibratorManager;
38 using aidl::android::hardware::vibrator::PrimitivePwle;
39 using aidl::android::hardware::vibrator::VibrationSessionConfig;
40
41 using namespace android;
42 using namespace testing;
43
__anon103fc7eb0102(vibrator::HalWrapper* hal) 44 static const auto OFF_FN = [](vibrator::HalWrapper* hal) { return hal->off(); };
45
46 // -------------------------------------------------------------------------------------------------
47
48 class MockIVibratorManager : public IVibratorManager {
49 public:
50 MockIVibratorManager() = default;
51
52 MOCK_METHOD(ndk::ScopedAStatus, getCapabilities, (int32_t * ret), (override));
53 MOCK_METHOD(ndk::ScopedAStatus, getVibratorIds, (std::vector<int32_t> * ret), (override));
54 MOCK_METHOD(ndk::ScopedAStatus, getVibrator, (int32_t id, std::shared_ptr<IVibrator>* ret),
55 (override));
56 MOCK_METHOD(ndk::ScopedAStatus, prepareSynced, (const std::vector<int32_t>& ids), (override));
57 MOCK_METHOD(ndk::ScopedAStatus, triggerSynced, (const std::shared_ptr<IVibratorCallback>& cb),
58 (override));
59 MOCK_METHOD(ndk::ScopedAStatus, cancelSynced, (), (override));
60 MOCK_METHOD(ndk::ScopedAStatus, startSession,
61 (const std::vector<int32_t>& ids, const VibrationSessionConfig& s,
62 const std::shared_ptr<IVibratorCallback>& cb,
63 std::shared_ptr<IVibrationSession>* ret),
64 (override));
65 MOCK_METHOD(ndk::ScopedAStatus, clearSessions, (), (override));
66 MOCK_METHOD(ndk::ScopedAStatus, getInterfaceVersion, (int32_t*), (override));
67 MOCK_METHOD(ndk::ScopedAStatus, getInterfaceHash, (std::string*), (override));
68 MOCK_METHOD(ndk::SpAIBinder, asBinder, (), (override));
69 MOCK_METHOD(bool, isRemote, (), (override));
70 };
71
72 class MockIVibrationSession : public IVibrationSession {
73 public:
74 MockIVibrationSession() = default;
75
76 MOCK_METHOD(ndk::ScopedAStatus, close, (), (override));
77 MOCK_METHOD(ndk::ScopedAStatus, abort, (), (override));
78 MOCK_METHOD(ndk::ScopedAStatus, getInterfaceVersion, (int32_t*), (override));
79 MOCK_METHOD(ndk::ScopedAStatus, getInterfaceHash, (std::string*), (override));
80 MOCK_METHOD(ndk::SpAIBinder, asBinder, (), (override));
81 MOCK_METHOD(bool, isRemote, (), (override));
82 };
83
84 // -------------------------------------------------------------------------------------------------
85
86 class VibratorManagerHalWrapperAidlTest : public Test {
87 public:
SetUp()88 void SetUp() override {
89 mMockVibrator = ndk::SharedRefBase::make<StrictMock<vibrator::MockIVibrator>>();
90 mMockSession = ndk::SharedRefBase::make<StrictMock<MockIVibrationSession>>();
91 mMockHal = ndk::SharedRefBase::make<StrictMock<MockIVibratorManager>>();
92 mMockScheduler = std::make_shared<StrictMock<vibrator::MockCallbackScheduler>>();
93 mWrapper = std::make_unique<vibrator::AidlManagerHalWrapper>(mMockScheduler, mMockHal);
94 ASSERT_NE(mWrapper, nullptr);
95 }
96
97 protected:
98 std::shared_ptr<StrictMock<vibrator::MockCallbackScheduler>> mMockScheduler = nullptr;
99 std::unique_ptr<vibrator::ManagerHalWrapper> mWrapper = nullptr;
100 std::shared_ptr<StrictMock<MockIVibratorManager>> mMockHal = nullptr;
101 std::shared_ptr<StrictMock<vibrator::MockIVibrator>> mMockVibrator = nullptr;
102 std::shared_ptr<StrictMock<MockIVibrationSession>> mMockSession = nullptr;
103 };
104
105 // -------------------------------------------------------------------------------------------------
106
107 static const std::vector<int32_t> kVibratorIds = {1, 2};
108 static const VibrationSessionConfig kSessionConfig;
109 static constexpr int kVibratorId = 1;
110
TEST_F(VibratorManagerHalWrapperAidlTest,TestGetCapabilitiesDoesNotCacheFailedResult)111 TEST_F(VibratorManagerHalWrapperAidlTest, TestGetCapabilitiesDoesNotCacheFailedResult) {
112 EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
113 .Times(Exactly(3))
114 .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION)))
115 .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
116 .WillOnce(DoAll(SetArgPointee<0>(IVibratorManager::CAP_SYNC),
117 Return(ndk::ScopedAStatus::ok())));
118
119 ASSERT_TRUE(mWrapper->getCapabilities().isUnsupported());
120 ASSERT_TRUE(mWrapper->getCapabilities().isFailed());
121
122 auto result = mWrapper->getCapabilities();
123 ASSERT_TRUE(result.isOk());
124 ASSERT_EQ(vibrator::ManagerCapabilities::SYNC, result.value());
125 }
126
TEST_F(VibratorManagerHalWrapperAidlTest,TestGetCapabilitiesCachesResult)127 TEST_F(VibratorManagerHalWrapperAidlTest, TestGetCapabilitiesCachesResult) {
128 EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
129 .Times(Exactly(1))
130 .WillOnce(DoAll(SetArgPointee<0>(IVibratorManager::CAP_SYNC),
131 Return(ndk::ScopedAStatus::ok())));
132
133 std::vector<std::thread> threads;
134 for (int i = 0; i < 10; i++) {
135 threads.push_back(std::thread([&]() {
136 auto result = mWrapper->getCapabilities();
137 ASSERT_TRUE(result.isOk());
138 ASSERT_EQ(vibrator::ManagerCapabilities::SYNC, result.value());
139 }));
140 }
141 std::for_each(threads.begin(), threads.end(), [](std::thread& t) { t.join(); });
142
143 auto result = mWrapper->getCapabilities();
144 ASSERT_TRUE(result.isOk());
145 ASSERT_EQ(vibrator::ManagerCapabilities::SYNC, result.value());
146 }
147
TEST_F(VibratorManagerHalWrapperAidlTest,TestGetVibratorIdsDoesNotCacheFailedResult)148 TEST_F(VibratorManagerHalWrapperAidlTest, TestGetVibratorIdsDoesNotCacheFailedResult) {
149 EXPECT_CALL(*mMockHal.get(), getVibratorIds(_))
150 .Times(Exactly(3))
151 .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION)))
152 .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
153 .WillOnce(DoAll(SetArgPointee<0>(kVibratorIds), Return(ndk::ScopedAStatus::ok())));
154
155 ASSERT_TRUE(mWrapper->getVibratorIds().isUnsupported());
156 ASSERT_TRUE(mWrapper->getVibratorIds().isFailed());
157
158 auto result = mWrapper->getVibratorIds();
159 ASSERT_TRUE(result.isOk());
160 ASSERT_EQ(kVibratorIds, result.value());
161 }
162
TEST_F(VibratorManagerHalWrapperAidlTest,TestGetVibratorIdsCachesResult)163 TEST_F(VibratorManagerHalWrapperAidlTest, TestGetVibratorIdsCachesResult) {
164 EXPECT_CALL(*mMockHal.get(), getVibratorIds(_))
165 .Times(Exactly(1))
166 .WillOnce(DoAll(SetArgPointee<0>(kVibratorIds), Return(ndk::ScopedAStatus::ok())));
167
168 std::vector<std::thread> threads;
169 for (int i = 0; i < 10; i++) {
170 threads.push_back(std::thread([&]() {
171 auto result = mWrapper->getVibratorIds();
172 ASSERT_TRUE(result.isOk());
173 ASSERT_EQ(kVibratorIds, result.value());
174 }));
175 }
176 std::for_each(threads.begin(), threads.end(), [](std::thread& t) { t.join(); });
177
178 auto result = mWrapper->getVibratorIds();
179 ASSERT_TRUE(result.isOk());
180 ASSERT_EQ(kVibratorIds, result.value());
181 }
182
TEST_F(VibratorManagerHalWrapperAidlTest,TestGetVibratorWithValidIdReturnsController)183 TEST_F(VibratorManagerHalWrapperAidlTest, TestGetVibratorWithValidIdReturnsController) {
184 {
185 InSequence seq;
186 EXPECT_CALL(*mMockHal.get(), getVibratorIds(_))
187 .Times(Exactly(1))
188 .WillOnce(DoAll(SetArgPointee<0>(kVibratorIds), Return(ndk::ScopedAStatus::ok())));
189
190 EXPECT_CALL(*mMockHal.get(), getVibrator(Eq(kVibratorId), _))
191 .Times(Exactly(1))
192 .WillOnce(DoAll(SetArgPointee<1>(mMockVibrator), Return(ndk::ScopedAStatus::ok())));
193 }
194
195 auto result = mWrapper->getVibrator(kVibratorId);
196 ASSERT_TRUE(result.isOk());
197 ASSERT_NE(nullptr, result.value().get());
198 ASSERT_TRUE(result.value().get()->init());
199 }
200
TEST_F(VibratorManagerHalWrapperAidlTest,TestGetVibratorWithInvalidIdFails)201 TEST_F(VibratorManagerHalWrapperAidlTest, TestGetVibratorWithInvalidIdFails) {
202 EXPECT_CALL(*mMockHal.get(), getVibratorIds(_))
203 .Times(Exactly(1))
204 .WillOnce(DoAll(SetArgPointee<0>(kVibratorIds), Return(ndk::ScopedAStatus::ok())));
205
206 ASSERT_TRUE(mWrapper->getVibrator(0).isFailed());
207 }
208
TEST_F(VibratorManagerHalWrapperAidlTest,TestGetVibratorRecoversVibratorPointer)209 TEST_F(VibratorManagerHalWrapperAidlTest, TestGetVibratorRecoversVibratorPointer) {
210 EXPECT_CALL(*mMockHal.get(), getVibratorIds(_))
211 .Times(Exactly(1))
212 .WillOnce(DoAll(SetArgPointee<0>(kVibratorIds), Return(ndk::ScopedAStatus::ok())));
213
214 EXPECT_CALL(*mMockHal.get(), getVibrator(Eq(kVibratorId), _))
215 .Times(Exactly(3))
216 .WillOnce(DoAll(SetArgPointee<1>(nullptr),
217 Return(ndk::ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED))))
218 // ndk::ScopedAStatus::ok() cannot be copy-constructed so can't use WillRepeatedly
219 .WillOnce(DoAll(SetArgPointee<1>(mMockVibrator), Return(ndk::ScopedAStatus::ok())))
220 .WillOnce(DoAll(SetArgPointee<1>(mMockVibrator), Return(ndk::ScopedAStatus::ok())));
221
222 EXPECT_CALL(*mMockVibrator.get(), off())
223 .Times(Exactly(3))
224 .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED)))
225 .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED)))
226 .WillOnce(Return(ndk::ScopedAStatus::ok()));
227
228 // Get vibrator controller is successful even if first getVibrator.
229 auto result = mWrapper->getVibrator(kVibratorId);
230 ASSERT_TRUE(result.isOk());
231 ASSERT_NE(nullptr, result.value().get());
232
233 auto vibrator = result.value();
234 // First getVibrator call fails.
235 ASSERT_FALSE(vibrator->init());
236 // First and second off() calls fail, reload IVibrator with getVibrator.
237 ASSERT_TRUE(vibrator->doWithRetry<void>(OFF_FN, "off").isFailed());
238 // Third call to off() worked after IVibrator reloaded.
239 ASSERT_TRUE(vibrator->doWithRetry<void>(OFF_FN, "off").isOk());
240 }
241
TEST_F(VibratorManagerHalWrapperAidlTest,TestPrepareSynced)242 TEST_F(VibratorManagerHalWrapperAidlTest, TestPrepareSynced) {
243 EXPECT_CALL(*mMockHal.get(), getVibratorIds(_))
244 .Times(Exactly(1))
245 .WillOnce(DoAll(SetArgPointee<0>(kVibratorIds), Return(ndk::ScopedAStatus::ok())));
246
247 EXPECT_CALL(*mMockHal.get(), getVibrator(_, _))
248 .Times(Exactly(2))
249 // ndk::ScopedAStatus::ok() cannot be copy-constructed so can't use WillRepeatedly
250 .WillOnce(DoAll(SetArgPointee<1>(mMockVibrator), Return(ndk::ScopedAStatus::ok())))
251 .WillOnce(DoAll(SetArgPointee<1>(mMockVibrator), Return(ndk::ScopedAStatus::ok())));
252
253 EXPECT_CALL(*mMockHal.get(), prepareSynced(Eq(kVibratorIds)))
254 .Times(Exactly(3))
255 .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION)))
256 .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
257 .WillOnce(Return(ndk::ScopedAStatus::ok()));
258
259 ASSERT_TRUE(mWrapper->getVibratorIds().isOk());
260 ASSERT_TRUE(mWrapper->prepareSynced(kVibratorIds).isUnsupported());
261 ASSERT_TRUE(mWrapper->prepareSynced(kVibratorIds).isFailed());
262 ASSERT_TRUE(mWrapper->prepareSynced(kVibratorIds).isOk());
263 }
264
TEST_F(VibratorManagerHalWrapperAidlTest,TestTriggerSyncedWithCallbackSupport)265 TEST_F(VibratorManagerHalWrapperAidlTest, TestTriggerSyncedWithCallbackSupport) {
266 {
267 InSequence seq;
268 EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
269 .Times(Exactly(1))
270 .WillOnce(DoAll(SetArgPointee<0>(IVibratorManager::CAP_TRIGGER_CALLBACK),
271 Return(ndk::ScopedAStatus::ok())));
272 EXPECT_CALL(*mMockHal.get(), triggerSynced(_))
273 .Times(Exactly(3))
274 .WillOnce(Return(ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_TRANSACTION)))
275 .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
276 .WillOnce(DoAll(vibrator::TriggerCallback(), Return(ndk::ScopedAStatus::ok())));
277 }
278
279 std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
280 auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
281
282 ASSERT_TRUE(mWrapper->triggerSynced(callback).isUnsupported());
283 ASSERT_TRUE(mWrapper->triggerSynced(callback).isFailed());
284 ASSERT_TRUE(mWrapper->triggerSynced(callback).isOk());
285 ASSERT_EQ(1, *callbackCounter.get());
286 }
287
TEST_F(VibratorManagerHalWrapperAidlTest,TestTriggerSyncedWithoutCallbackSupport)288 TEST_F(VibratorManagerHalWrapperAidlTest, TestTriggerSyncedWithoutCallbackSupport) {
289 {
290 InSequence seq;
291 EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
292 .Times(Exactly(1))
293 .WillOnce(DoAll(SetArgPointee<0>(IVibratorManager::CAP_SYNC),
294 Return(ndk::ScopedAStatus::ok())));
295 EXPECT_CALL(*mMockHal.get(), triggerSynced(Eq(nullptr)))
296 .Times(Exactly(1))
297 .WillOnce(Return(ndk::ScopedAStatus::ok()));
298 }
299
300 std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
301 auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
302
303 ASSERT_TRUE(mWrapper->triggerSynced(callback).isOk());
304 ASSERT_EQ(0, *callbackCounter.get());
305 }
306
TEST_F(VibratorManagerHalWrapperAidlTest,TestCancelSynced)307 TEST_F(VibratorManagerHalWrapperAidlTest, TestCancelSynced) {
308 EXPECT_CALL(*mMockHal.get(), cancelSynced())
309 .Times(Exactly(3))
310 .WillOnce(Return(ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_TRANSACTION)))
311 .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
312 .WillOnce(Return(ndk::ScopedAStatus::ok()));
313
314 ASSERT_TRUE(mWrapper->cancelSynced().isUnsupported());
315 ASSERT_TRUE(mWrapper->cancelSynced().isFailed());
316 ASSERT_TRUE(mWrapper->cancelSynced().isOk());
317 }
318
TEST_F(VibratorManagerHalWrapperAidlTest,TestCancelSyncedReloadsAllControllers)319 TEST_F(VibratorManagerHalWrapperAidlTest, TestCancelSyncedReloadsAllControllers) {
320 EXPECT_CALL(*mMockHal.get(), getVibratorIds(_))
321 .Times(Exactly(1))
322 .WillOnce(DoAll(SetArgPointee<0>(kVibratorIds), Return(ndk::ScopedAStatus::ok())));
323
324 EXPECT_CALL(*mMockHal.get(), getVibrator(_, _))
325 .Times(Exactly(2))
326 // ndk::ScopedAStatus::ok() cannot be copy-constructed so can't use WillRepeatedly
327 .WillOnce(DoAll(SetArgPointee<1>(mMockVibrator), Return(ndk::ScopedAStatus::ok())))
328 .WillOnce(DoAll(SetArgPointee<1>(mMockVibrator), Return(ndk::ScopedAStatus::ok())));
329
330 EXPECT_CALL(*mMockHal.get(), cancelSynced())
331 .Times(Exactly(1))
332 .WillOnce(Return(ndk::ScopedAStatus::ok()));
333
334 ASSERT_TRUE(mWrapper->getVibratorIds().isOk());
335 ASSERT_TRUE(mWrapper->cancelSynced().isOk());
336 }
337
TEST_F(VibratorManagerHalWrapperAidlTest,TestStartSession)338 TEST_F(VibratorManagerHalWrapperAidlTest, TestStartSession) {
339 EXPECT_CALL(*mMockHal.get(), startSession(_, _, _, _))
340 .Times(Exactly(3))
341 .WillOnce(Return(ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_TRANSACTION)))
342 .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
343 .WillOnce(
344 DoAll(DoAll(SetArgPointee<3>(mMockSession), Return(ndk::ScopedAStatus::ok()))));
345
346 std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
347 auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
348
349 ASSERT_TRUE(mWrapper->startSession(kVibratorIds, kSessionConfig, callback).isUnsupported());
350 ASSERT_TRUE(mWrapper->startSession(kVibratorIds, kSessionConfig, callback).isFailed());
351
352 auto result = mWrapper->startSession(kVibratorIds, kSessionConfig, callback);
353 ASSERT_TRUE(result.isOk());
354 ASSERT_NE(nullptr, result.value().get());
355 ASSERT_EQ(0, *callbackCounter.get());
356 }
357
TEST_F(VibratorManagerHalWrapperAidlTest,TestClearSessions)358 TEST_F(VibratorManagerHalWrapperAidlTest, TestClearSessions) {
359 EXPECT_CALL(*mMockHal.get(), clearSessions())
360 .Times(Exactly(3))
361 .WillOnce(Return(ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_TRANSACTION)))
362 .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
363 .WillOnce(Return(ndk::ScopedAStatus::ok()));
364
365 ASSERT_TRUE(mWrapper->clearSessions().isUnsupported());
366 ASSERT_TRUE(mWrapper->clearSessions().isFailed());
367 ASSERT_TRUE(mWrapper->clearSessions().isOk());
368 }
369