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