• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "VibratorHalWrapperAidlTest"
18 
19 #include <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/VibratorCallbackScheduler.h>
28 #include <vibratorservice/VibratorHalWrapper.h>
29 
30 #include "test_utils.h"
31 
32 using android::binder::Status;
33 
34 using android::hardware::vibrator::Braking;
35 using android::hardware::vibrator::CompositeEffect;
36 using android::hardware::vibrator::CompositePrimitive;
37 using android::hardware::vibrator::Effect;
38 using android::hardware::vibrator::EffectStrength;
39 using android::hardware::vibrator::IVibrator;
40 using android::hardware::vibrator::IVibratorCallback;
41 using android::hardware::vibrator::PrimitivePwle;
42 
43 using namespace android;
44 using namespace std::chrono_literals;
45 using namespace testing;
46 
47 // -------------------------------------------------------------------------------------------------
48 
49 class MockBinder : public BBinder {
50 public:
51     MOCK_METHOD(status_t, linkToDeath,
52                 (const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags), (override));
53     MOCK_METHOD(status_t, unlinkToDeath,
54                 (const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
55                  wp<DeathRecipient>* outRecipient),
56                 (override));
57     MOCK_METHOD(status_t, pingBinder, (), (override));
58 };
59 
60 class MockIVibrator : public IVibrator {
61 public:
62     MOCK_METHOD(Status, getCapabilities, (int32_t * ret), (override));
63     MOCK_METHOD(Status, off, (), (override));
64     MOCK_METHOD(Status, on, (int32_t timeout, const sp<IVibratorCallback>& cb), (override));
65     MOCK_METHOD(Status, perform,
66                 (Effect e, EffectStrength s, const sp<IVibratorCallback>& cb, int32_t* ret),
67                 (override));
68     MOCK_METHOD(Status, getSupportedEffects, (std::vector<Effect> * ret), (override));
69     MOCK_METHOD(Status, setAmplitude, (float amplitude), (override));
70     MOCK_METHOD(Status, setExternalControl, (bool enabled), (override));
71     MOCK_METHOD(Status, getCompositionDelayMax, (int32_t * ret), (override));
72     MOCK_METHOD(Status, getCompositionSizeMax, (int32_t * ret), (override));
73     MOCK_METHOD(Status, getSupportedPrimitives, (std::vector<CompositePrimitive> * ret),
74                 (override));
75     MOCK_METHOD(Status, getPrimitiveDuration, (CompositePrimitive p, int32_t* ret), (override));
76     MOCK_METHOD(Status, compose,
77                 (const std::vector<CompositeEffect>& e, const sp<IVibratorCallback>& cb),
78                 (override));
79     MOCK_METHOD(Status, composePwle,
80                 (const std::vector<PrimitivePwle>& e, const sp<IVibratorCallback>& cb), (override));
81     MOCK_METHOD(Status, getSupportedAlwaysOnEffects, (std::vector<Effect> * ret), (override));
82     MOCK_METHOD(Status, alwaysOnEnable, (int32_t id, Effect e, EffectStrength s), (override));
83     MOCK_METHOD(Status, alwaysOnDisable, (int32_t id), (override));
84     MOCK_METHOD(Status, getQFactor, (float * ret), (override));
85     MOCK_METHOD(Status, getResonantFrequency, (float * ret), (override));
86     MOCK_METHOD(Status, getFrequencyResolution, (float* ret), (override));
87     MOCK_METHOD(Status, getFrequencyMinimum, (float* ret), (override));
88     MOCK_METHOD(Status, getBandwidthAmplitudeMap, (std::vector<float> * ret), (override));
89     MOCK_METHOD(Status, getPwlePrimitiveDurationMax, (int32_t * ret), (override));
90     MOCK_METHOD(Status, getPwleCompositionSizeMax, (int32_t * ret), (override));
91     MOCK_METHOD(Status, getSupportedBraking, (std::vector<Braking> * ret), (override));
92     MOCK_METHOD(int32_t, getInterfaceVersion, (), (override));
93     MOCK_METHOD(std::string, getInterfaceHash, (), (override));
94     MOCK_METHOD(IBinder*, onAsBinder, (), (override));
95 };
96 
97 // -------------------------------------------------------------------------------------------------
98 
99 class VibratorHalWrapperAidlTest : public Test {
100 public:
SetUp()101     void SetUp() override {
102         mMockBinder = new StrictMock<MockBinder>();
103         mMockHal = new StrictMock<MockIVibrator>();
104         mMockScheduler = std::make_shared<StrictMock<vibrator::MockCallbackScheduler>>();
105         mWrapper = std::make_unique<vibrator::AidlHalWrapper>(mMockScheduler, mMockHal);
106         ASSERT_NE(mWrapper, nullptr);
107     }
108 
109 protected:
110     std::shared_ptr<StrictMock<vibrator::MockCallbackScheduler>> mMockScheduler = nullptr;
111     std::unique_ptr<vibrator::HalWrapper> mWrapper = nullptr;
112     sp<StrictMock<MockIVibrator>> mMockHal = nullptr;
113     sp<StrictMock<MockBinder>> mMockBinder = nullptr;
114 };
115 
116 // -------------------------------------------------------------------------------------------------
117 
ACTION(TriggerCallbackInArg1)118 ACTION(TriggerCallbackInArg1) {
119     if (arg1 != nullptr) {
120         arg1->onComplete();
121     }
122 }
123 
ACTION(TriggerCallbackInArg2)124 ACTION(TriggerCallbackInArg2) {
125     if (arg2 != nullptr) {
126         arg2->onComplete();
127     }
128 }
129 
TEST_F(VibratorHalWrapperAidlTest,TestPing)130 TEST_F(VibratorHalWrapperAidlTest, TestPing) {
131     EXPECT_CALL(*mMockHal.get(), onAsBinder())
132             .Times(Exactly(2))
133             .WillRepeatedly(Return(mMockBinder.get()));
134     EXPECT_CALL(*mMockBinder.get(), pingBinder())
135             .Times(Exactly(2))
136             .WillOnce(Return(android::OK))
137             .WillRepeatedly(Return(android::DEAD_OBJECT));
138 
139     ASSERT_TRUE(mWrapper->ping().isOk());
140     ASSERT_TRUE(mWrapper->ping().isFailed());
141 }
142 
TEST_F(VibratorHalWrapperAidlTest,TestOnWithCallbackSupport)143 TEST_F(VibratorHalWrapperAidlTest, TestOnWithCallbackSupport) {
144     {
145         InSequence seq;
146         EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
147                 .Times(Exactly(1))
148                 .WillRepeatedly(
149                         DoAll(SetArgPointee<0>(IVibrator::CAP_ON_CALLBACK), Return(Status())));
150         EXPECT_CALL(*mMockHal.get(), on(Eq(10), _))
151                 .Times(Exactly(1))
152                 .WillRepeatedly(DoAll(TriggerCallbackInArg1(), Return(Status())));
153         EXPECT_CALL(*mMockHal.get(), on(Eq(100), _))
154                 .Times(Exactly(1))
155                 .WillRepeatedly(Return(
156                         Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)));
157         EXPECT_CALL(*mMockHal.get(), on(Eq(1000), _))
158                 .Times(Exactly(1))
159                 .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
160     }
161 
162     std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
163     auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
164 
165     ASSERT_TRUE(mWrapper->on(10ms, callback).isOk());
166     ASSERT_EQ(1, *callbackCounter.get());
167 
168     ASSERT_TRUE(mWrapper->on(100ms, callback).isUnsupported());
169     // Callback not triggered for unsupported
170     ASSERT_EQ(1, *callbackCounter.get());
171 
172     ASSERT_TRUE(mWrapper->on(1000ms, callback).isFailed());
173     // Callback not triggered on failure
174     ASSERT_EQ(1, *callbackCounter.get());
175 }
176 
TEST_F(VibratorHalWrapperAidlTest,TestOnWithoutCallbackSupport)177 TEST_F(VibratorHalWrapperAidlTest, TestOnWithoutCallbackSupport) {
178     {
179         InSequence seq;
180         EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
181                 .Times(Exactly(1))
182                 .WillRepeatedly(
183                         DoAll(SetArgPointee<0>(IVibrator::CAP_COMPOSE_EFFECTS), Return(Status())));
184         EXPECT_CALL(*mMockHal.get(), on(Eq(10), _))
185                 .Times(Exactly(1))
186                 .WillRepeatedly(Return(Status()));
187         EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(10ms)))
188                 .Times(Exactly(1))
189                 .WillRepeatedly(vibrator::TriggerSchedulerCallback());
190         EXPECT_CALL(*mMockHal.get(), on(Eq(11), _))
191                 .Times(Exactly(1))
192                 .WillRepeatedly(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)));
193         EXPECT_CALL(*mMockHal.get(), on(Eq(12), _))
194                 .Times(Exactly(1))
195                 .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
196     }
197 
198     std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
199     auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
200 
201     ASSERT_TRUE(mWrapper->on(10ms, callback).isOk());
202     ASSERT_EQ(1, *callbackCounter.get());
203 
204     ASSERT_TRUE(mWrapper->on(11ms, callback).isUnsupported());
205     ASSERT_TRUE(mWrapper->on(12ms, callback).isFailed());
206 
207     // Callback not triggered for unsupported and on failure
208     ASSERT_EQ(1, *callbackCounter.get());
209 }
210 
TEST_F(VibratorHalWrapperAidlTest,TestOff)211 TEST_F(VibratorHalWrapperAidlTest, TestOff) {
212     EXPECT_CALL(*mMockHal.get(), off())
213             .Times(Exactly(3))
214             .WillOnce(Return(Status()))
215             .WillOnce(
216                     Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)))
217             .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
218 
219     ASSERT_TRUE(mWrapper->off().isOk());
220     ASSERT_TRUE(mWrapper->off().isUnsupported());
221     ASSERT_TRUE(mWrapper->off().isFailed());
222 }
223 
TEST_F(VibratorHalWrapperAidlTest,TestSetAmplitude)224 TEST_F(VibratorHalWrapperAidlTest, TestSetAmplitude) {
225     {
226         InSequence seq;
227         EXPECT_CALL(*mMockHal.get(), setAmplitude(Eq(0.1f))).Times(Exactly(1));
228         EXPECT_CALL(*mMockHal.get(), setAmplitude(Eq(0.2f)))
229                 .Times(Exactly(1))
230                 .WillRepeatedly(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)));
231         EXPECT_CALL(*mMockHal.get(), setAmplitude(Eq(0.5f)))
232                 .Times(Exactly(1))
233                 .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
234     }
235 
236     ASSERT_TRUE(mWrapper->setAmplitude(0.1f).isOk());
237     ASSERT_TRUE(mWrapper->setAmplitude(0.2f).isUnsupported());
238     ASSERT_TRUE(mWrapper->setAmplitude(0.5f).isFailed());
239 }
240 
TEST_F(VibratorHalWrapperAidlTest,TestSetExternalControl)241 TEST_F(VibratorHalWrapperAidlTest, TestSetExternalControl) {
242     {
243         InSequence seq;
244         EXPECT_CALL(*mMockHal.get(), setExternalControl(Eq(true))).Times(Exactly(1));
245         EXPECT_CALL(*mMockHal.get(), setExternalControl(Eq(false)))
246                 .Times(Exactly(2))
247                 .WillOnce(Return(
248                         Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)))
249                 .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
250     }
251 
252     ASSERT_TRUE(mWrapper->setExternalControl(true).isOk());
253     ASSERT_TRUE(mWrapper->setExternalControl(false).isUnsupported());
254     ASSERT_TRUE(mWrapper->setExternalControl(false).isFailed());
255 }
256 
TEST_F(VibratorHalWrapperAidlTest,TestAlwaysOnEnable)257 TEST_F(VibratorHalWrapperAidlTest, TestAlwaysOnEnable) {
258     {
259         InSequence seq;
260         EXPECT_CALL(*mMockHal.get(),
261                     alwaysOnEnable(Eq(1), Eq(Effect::CLICK), Eq(EffectStrength::LIGHT)))
262                 .Times(Exactly(1));
263         EXPECT_CALL(*mMockHal.get(),
264                     alwaysOnEnable(Eq(2), Eq(Effect::TICK), Eq(EffectStrength::MEDIUM)))
265                 .Times(Exactly(1))
266                 .WillRepeatedly(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)));
267         EXPECT_CALL(*mMockHal.get(),
268                     alwaysOnEnable(Eq(3), Eq(Effect::POP), Eq(EffectStrength::STRONG)))
269                 .Times(Exactly(1))
270                 .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
271     }
272 
273     auto result = mWrapper->alwaysOnEnable(1, Effect::CLICK, EffectStrength::LIGHT);
274     ASSERT_TRUE(result.isOk());
275     result = mWrapper->alwaysOnEnable(2, Effect::TICK, EffectStrength::MEDIUM);
276     ASSERT_TRUE(result.isUnsupported());
277     result = mWrapper->alwaysOnEnable(3, Effect::POP, EffectStrength::STRONG);
278     ASSERT_TRUE(result.isFailed());
279 }
280 
TEST_F(VibratorHalWrapperAidlTest,TestAlwaysOnDisable)281 TEST_F(VibratorHalWrapperAidlTest, TestAlwaysOnDisable) {
282     {
283         InSequence seq;
284         EXPECT_CALL(*mMockHal.get(), alwaysOnDisable(Eq(1))).Times(Exactly(1));
285         EXPECT_CALL(*mMockHal.get(), alwaysOnDisable(Eq(2)))
286                 .Times(Exactly(1))
287                 .WillRepeatedly(Return(
288                         Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)));
289         EXPECT_CALL(*mMockHal.get(), alwaysOnDisable(Eq(3)))
290                 .Times(Exactly(1))
291                 .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
292     }
293 
294     ASSERT_TRUE(mWrapper->alwaysOnDisable(1).isOk());
295     ASSERT_TRUE(mWrapper->alwaysOnDisable(2).isUnsupported());
296     ASSERT_TRUE(mWrapper->alwaysOnDisable(3).isFailed());
297 }
298 
TEST_F(VibratorHalWrapperAidlTest,TestGetInfoDoesNotCacheFailedResult)299 TEST_F(VibratorHalWrapperAidlTest, TestGetInfoDoesNotCacheFailedResult) {
300     constexpr float F_MIN = 100.f;
301     constexpr float F0 = 123.f;
302     constexpr float F_RESOLUTION = 0.5f;
303     constexpr float Q_FACTOR = 123.f;
304     constexpr int32_t COMPOSITION_SIZE_MAX = 10;
305     constexpr int32_t PWLE_SIZE_MAX = 20;
306     constexpr int32_t PRIMITIVE_DELAY_MAX = 100;
307     constexpr int32_t PWLE_DURATION_MAX = 200;
308     std::vector<Effect> supportedEffects = {Effect::CLICK, Effect::TICK};
309     std::vector<CompositePrimitive> supportedPrimitives = {CompositePrimitive::CLICK};
310     std::vector<Braking> supportedBraking = {Braking::CLAB};
311     std::vector<float> amplitudes = {0.f, 1.f, 0.f};
312 
313     std::vector<std::chrono::milliseconds> primitiveDurations;
314     constexpr auto primitiveRange = enum_range<CompositePrimitive>();
315     constexpr auto primitiveCount = std::distance(primitiveRange.begin(), primitiveRange.end());
316     primitiveDurations.resize(primitiveCount);
317     primitiveDurations[static_cast<size_t>(CompositePrimitive::CLICK)] = 10ms;
318 
319     EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
320             .Times(Exactly(2))
321             .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
322             .WillRepeatedly(DoAll(SetArgPointee<0>(IVibrator::CAP_ON_CALLBACK), Return(Status())));
323     EXPECT_CALL(*mMockHal.get(), getSupportedEffects(_))
324             .Times(Exactly(2))
325             .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
326             .WillRepeatedly(DoAll(SetArgPointee<0>(supportedEffects), Return(Status())));
327     EXPECT_CALL(*mMockHal.get(), getSupportedBraking(_))
328             .Times(Exactly(2))
329             .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
330             .WillRepeatedly(DoAll(SetArgPointee<0>(supportedBraking), Return(Status())));
331     EXPECT_CALL(*mMockHal.get(), getSupportedPrimitives(_))
332             .Times(Exactly(2))
333             .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
334             .WillRepeatedly(DoAll(SetArgPointee<0>(supportedPrimitives), Return(Status())));
335     EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::CLICK), _))
336             .Times(Exactly(1))
337             .WillRepeatedly(DoAll(SetArgPointee<1>(10), Return(Status())));
338     EXPECT_CALL(*mMockHal.get(), getCompositionSizeMax(_))
339             .Times(Exactly(2))
340             .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
341             .WillRepeatedly(DoAll(SetArgPointee<0>(COMPOSITION_SIZE_MAX), Return(Status())));
342     EXPECT_CALL(*mMockHal.get(), getCompositionDelayMax(_))
343             .Times(Exactly(2))
344             .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
345             .WillRepeatedly(DoAll(SetArgPointee<0>(PRIMITIVE_DELAY_MAX), Return(Status())));
346     EXPECT_CALL(*mMockHal.get(), getPwlePrimitiveDurationMax(_))
347             .Times(Exactly(2))
348             .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
349             .WillRepeatedly(DoAll(SetArgPointee<0>(PWLE_DURATION_MAX), Return(Status())));
350     EXPECT_CALL(*mMockHal.get(), getPwleCompositionSizeMax(_))
351             .Times(Exactly(2))
352             .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
353             .WillRepeatedly(DoAll(SetArgPointee<0>(PWLE_SIZE_MAX), Return(Status())));
354     EXPECT_CALL(*mMockHal.get(), getFrequencyMinimum(_))
355             .Times(Exactly(2))
356             .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
357             .WillRepeatedly(DoAll(SetArgPointee<0>(F_MIN), Return(Status())));
358     EXPECT_CALL(*mMockHal.get(), getResonantFrequency(_))
359             .Times(Exactly(2))
360             .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
361             .WillRepeatedly(DoAll(SetArgPointee<0>(F0), Return(Status())));
362     EXPECT_CALL(*mMockHal.get(), getFrequencyResolution(_))
363             .Times(Exactly(2))
364             .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
365             .WillRepeatedly(DoAll(SetArgPointee<0>(F_RESOLUTION), Return(Status())));
366     EXPECT_CALL(*mMockHal.get(), getQFactor(_))
367             .Times(Exactly(2))
368             .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
369             .WillRepeatedly(DoAll(SetArgPointee<0>(Q_FACTOR), Return(Status())));
370     EXPECT_CALL(*mMockHal.get(), getBandwidthAmplitudeMap(_))
371             .Times(Exactly(2))
372             .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
373             .WillRepeatedly(DoAll(SetArgPointee<0>(amplitudes), Return(Status())));
374 
375     vibrator::Info failed = mWrapper->getInfo();
376     ASSERT_TRUE(failed.capabilities.isFailed());
377     ASSERT_TRUE(failed.supportedEffects.isFailed());
378     ASSERT_TRUE(failed.supportedBraking.isFailed());
379     ASSERT_TRUE(failed.supportedPrimitives.isFailed());
380     ASSERT_TRUE(failed.primitiveDurations.isFailed());
381     ASSERT_TRUE(failed.primitiveDelayMax.isFailed());
382     ASSERT_TRUE(failed.pwlePrimitiveDurationMax.isFailed());
383     ASSERT_TRUE(failed.compositionSizeMax.isFailed());
384     ASSERT_TRUE(failed.pwleSizeMax.isFailed());
385     ASSERT_TRUE(failed.minFrequency.isFailed());
386     ASSERT_TRUE(failed.resonantFrequency.isFailed());
387     ASSERT_TRUE(failed.frequencyResolution.isFailed());
388     ASSERT_TRUE(failed.qFactor.isFailed());
389     ASSERT_TRUE(failed.maxAmplitudes.isFailed());
390 
391     vibrator::Info successful = mWrapper->getInfo();
392     ASSERT_EQ(vibrator::Capabilities::ON_CALLBACK, successful.capabilities.value());
393     ASSERT_EQ(supportedEffects, successful.supportedEffects.value());
394     ASSERT_EQ(supportedBraking, successful.supportedBraking.value());
395     ASSERT_EQ(supportedPrimitives, successful.supportedPrimitives.value());
396     ASSERT_EQ(primitiveDurations, successful.primitiveDurations.value());
397     ASSERT_EQ(std::chrono::milliseconds(PRIMITIVE_DELAY_MAX), successful.primitiveDelayMax.value());
398     ASSERT_EQ(std::chrono::milliseconds(PWLE_DURATION_MAX),
399               successful.pwlePrimitiveDurationMax.value());
400     ASSERT_EQ(COMPOSITION_SIZE_MAX, successful.compositionSizeMax.value());
401     ASSERT_EQ(PWLE_SIZE_MAX, successful.pwleSizeMax.value());
402     ASSERT_EQ(F_MIN, successful.minFrequency.value());
403     ASSERT_EQ(F0, successful.resonantFrequency.value());
404     ASSERT_EQ(F_RESOLUTION, successful.frequencyResolution.value());
405     ASSERT_EQ(Q_FACTOR, successful.qFactor.value());
406     ASSERT_EQ(amplitudes, successful.maxAmplitudes.value());
407 }
408 
TEST_F(VibratorHalWrapperAidlTest,TestGetInfoCachesResult)409 TEST_F(VibratorHalWrapperAidlTest, TestGetInfoCachesResult) {
410     constexpr float F_MIN = 100.f;
411     constexpr float F0 = 123.f;
412     constexpr int32_t COMPOSITION_SIZE_MAX = 10;
413     constexpr int32_t PWLE_SIZE_MAX = 20;
414     constexpr int32_t PRIMITIVE_DELAY_MAX = 100;
415     constexpr int32_t PWLE_DURATION_MAX = 200;
416     std::vector<Effect> supportedEffects = {Effect::CLICK, Effect::TICK};
417 
418     EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
419             .Times(Exactly(1))
420             .WillRepeatedly(DoAll(SetArgPointee<0>(IVibrator::CAP_ON_CALLBACK), Return(Status())));
421     EXPECT_CALL(*mMockHal.get(), getSupportedEffects(_))
422             .Times(Exactly(1))
423             .WillRepeatedly(DoAll(SetArgPointee<0>(supportedEffects), Return(Status())));
424     EXPECT_CALL(*mMockHal.get(), getQFactor(_))
425             .Times(Exactly(1))
426             .WillRepeatedly(
427                     Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)));
428     EXPECT_CALL(*mMockHal.get(), getSupportedPrimitives(_))
429             .Times(Exactly(1))
430             .WillRepeatedly(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)));
431     EXPECT_CALL(*mMockHal.get(), getCompositionSizeMax(_))
432             .Times(Exactly(1))
433             .WillRepeatedly(DoAll(SetArgPointee<0>(COMPOSITION_SIZE_MAX), Return(Status())));
434     EXPECT_CALL(*mMockHal.get(), getCompositionDelayMax(_))
435             .Times(Exactly(1))
436             .WillRepeatedly(DoAll(SetArgPointee<0>(PRIMITIVE_DELAY_MAX), Return(Status())));
437     EXPECT_CALL(*mMockHal.get(), getPwlePrimitiveDurationMax(_))
438             .Times(Exactly(1))
439             .WillRepeatedly(DoAll(SetArgPointee<0>(PWLE_DURATION_MAX), Return(Status())));
440     EXPECT_CALL(*mMockHal.get(), getPwleCompositionSizeMax(_))
441             .Times(Exactly(1))
442             .WillRepeatedly(DoAll(SetArgPointee<0>(PWLE_SIZE_MAX), Return(Status())));
443     EXPECT_CALL(*mMockHal.get(), getFrequencyMinimum(_))
444             .Times(Exactly(1))
445             .WillRepeatedly(DoAll(SetArgPointee<0>(F_MIN), Return(Status())));
446     EXPECT_CALL(*mMockHal.get(), getResonantFrequency(_))
447             .Times(Exactly(1))
448             .WillRepeatedly(DoAll(SetArgPointee<0>(F0), Return(Status())));
449     EXPECT_CALL(*mMockHal.get(), getFrequencyResolution(_))
450             .Times(Exactly(1))
451             .WillRepeatedly(
452                     Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)));
453     EXPECT_CALL(*mMockHal.get(), getBandwidthAmplitudeMap(_))
454             .Times(Exactly(1))
455             .WillRepeatedly(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)));
456     EXPECT_CALL(*mMockHal.get(), getSupportedBraking(_))
457             .Times(Exactly(1))
458             .WillRepeatedly(
459                     Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)));
460 
461     std::vector<std::thread> threads;
462     for (int i = 0; i < 10; i++) {
463         threads.push_back(
464                 std::thread([&]() { ASSERT_TRUE(mWrapper->getInfo().capabilities.isOk()); }));
465     }
466     std::for_each(threads.begin(), threads.end(), [](std::thread& t) { t.join(); });
467 
468     vibrator::Info info = mWrapper->getInfo();
469     ASSERT_EQ(vibrator::Capabilities::ON_CALLBACK, info.capabilities.value());
470     ASSERT_EQ(supportedEffects, info.supportedEffects.value());
471     ASSERT_TRUE(info.supportedBraking.isUnsupported());
472     ASSERT_TRUE(info.supportedPrimitives.isUnsupported());
473     ASSERT_TRUE(info.primitiveDurations.isUnsupported());
474     ASSERT_EQ(std::chrono::milliseconds(PRIMITIVE_DELAY_MAX), info.primitiveDelayMax.value());
475     ASSERT_EQ(std::chrono::milliseconds(PWLE_DURATION_MAX), info.pwlePrimitiveDurationMax.value());
476     ASSERT_EQ(COMPOSITION_SIZE_MAX, info.compositionSizeMax.value());
477     ASSERT_EQ(PWLE_SIZE_MAX, info.pwleSizeMax.value());
478     ASSERT_EQ(F_MIN, info.minFrequency.value());
479     ASSERT_EQ(F0, info.resonantFrequency.value());
480     ASSERT_TRUE(info.frequencyResolution.isUnsupported());
481     ASSERT_TRUE(info.qFactor.isUnsupported());
482     ASSERT_TRUE(info.maxAmplitudes.isUnsupported());
483 }
484 
TEST_F(VibratorHalWrapperAidlTest,TestPerformEffectWithCallbackSupport)485 TEST_F(VibratorHalWrapperAidlTest, TestPerformEffectWithCallbackSupport) {
486     {
487         InSequence seq;
488         EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
489                 .Times(Exactly(1))
490                 .WillRepeatedly(
491                         DoAll(SetArgPointee<0>(IVibrator::CAP_PERFORM_CALLBACK), Return(Status())));
492         EXPECT_CALL(*mMockHal.get(), perform(Eq(Effect::CLICK), Eq(EffectStrength::LIGHT), _, _))
493                 .Times(Exactly(1))
494                 .WillRepeatedly(
495                         DoAll(SetArgPointee<3>(1000), TriggerCallbackInArg2(), Return(Status())));
496         EXPECT_CALL(*mMockHal.get(), perform(Eq(Effect::POP), Eq(EffectStrength::MEDIUM), _, _))
497                 .Times(Exactly(1))
498                 .WillRepeatedly(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)));
499         EXPECT_CALL(*mMockHal.get(), perform(Eq(Effect::THUD), Eq(EffectStrength::STRONG), _, _))
500                 .Times(Exactly(1))
501                 .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
502     }
503 
504     std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
505     auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
506 
507     auto result = mWrapper->performEffect(Effect::CLICK, EffectStrength::LIGHT, callback);
508     ASSERT_TRUE(result.isOk());
509     ASSERT_EQ(1000ms, result.value());
510     ASSERT_EQ(1, *callbackCounter.get());
511 
512     result = mWrapper->performEffect(Effect::POP, EffectStrength::MEDIUM, callback);
513     ASSERT_TRUE(result.isUnsupported());
514     // Callback not triggered for unsupported
515     ASSERT_EQ(1, *callbackCounter.get());
516 
517     result = mWrapper->performEffect(Effect::THUD, EffectStrength::STRONG, callback);
518     ASSERT_TRUE(result.isFailed());
519     // Callback not triggered on failure
520     ASSERT_EQ(1, *callbackCounter.get());
521 }
522 
TEST_F(VibratorHalWrapperAidlTest,TestPerformEffectWithoutCallbackSupport)523 TEST_F(VibratorHalWrapperAidlTest, TestPerformEffectWithoutCallbackSupport) {
524     {
525         InSequence seq;
526         EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
527                 .Times(Exactly(1))
528                 .WillRepeatedly(
529                         DoAll(SetArgPointee<0>(IVibrator::CAP_ON_CALLBACK), Return(Status())));
530         EXPECT_CALL(*mMockHal.get(), perform(Eq(Effect::CLICK), Eq(EffectStrength::LIGHT), _, _))
531                 .Times(Exactly(1))
532                 .WillRepeatedly(DoAll(SetArgPointee<3>(10), Return(Status())));
533         EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(10ms)))
534                 .Times(Exactly(1))
535                 .WillRepeatedly(vibrator::TriggerSchedulerCallback());
536         EXPECT_CALL(*mMockHal.get(), perform(Eq(Effect::POP), Eq(EffectStrength::MEDIUM), _, _))
537                 .Times(Exactly(1))
538                 .WillRepeatedly(Return(
539                         Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)));
540         EXPECT_CALL(*mMockHal.get(), perform(Eq(Effect::THUD), Eq(EffectStrength::STRONG), _, _))
541                 .Times(Exactly(1))
542                 .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
543     }
544 
545     std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
546     auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
547 
548     auto result = mWrapper->performEffect(Effect::CLICK, EffectStrength::LIGHT, callback);
549     ASSERT_TRUE(result.isOk());
550     ASSERT_EQ(10ms, result.value());
551     ASSERT_EQ(1, *callbackCounter.get());
552 
553     result = mWrapper->performEffect(Effect::POP, EffectStrength::MEDIUM, callback);
554     ASSERT_TRUE(result.isUnsupported());
555 
556     result = mWrapper->performEffect(Effect::THUD, EffectStrength::STRONG, callback);
557     ASSERT_TRUE(result.isFailed());
558 
559     // Callback not triggered for unsupported and on failure
560     ASSERT_EQ(1, *callbackCounter.get());
561 }
562 
TEST_F(VibratorHalWrapperAidlTest,TestPerformComposedEffect)563 TEST_F(VibratorHalWrapperAidlTest, TestPerformComposedEffect) {
564     std::vector<CompositePrimitive> supportedPrimitives = {CompositePrimitive::CLICK,
565                                                            CompositePrimitive::SPIN,
566                                                            CompositePrimitive::THUD};
567     std::vector<CompositeEffect> emptyEffects, singleEffect, multipleEffects;
568     singleEffect.push_back(
569             vibrator::TestFactory::createCompositeEffect(CompositePrimitive::CLICK, 10ms, 0.0f));
570     multipleEffects.push_back(
571             vibrator::TestFactory::createCompositeEffect(CompositePrimitive::SPIN, 100ms, 0.5f));
572     multipleEffects.push_back(
573             vibrator::TestFactory::createCompositeEffect(CompositePrimitive::THUD, 1000ms, 1.0f));
574 
575     {
576         InSequence seq;
577         EXPECT_CALL(*mMockHal.get(), getSupportedPrimitives(_))
578                 .Times(Exactly(1))
579                 .WillRepeatedly(DoAll(SetArgPointee<0>(supportedPrimitives), Return(Status())));
580         EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::CLICK), _))
581                 .Times(Exactly(1))
582                 .WillRepeatedly(DoAll(SetArgPointee<1>(1), Return(Status())));
583         EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::SPIN), _))
584                 .Times(Exactly(1))
585                 .WillRepeatedly(DoAll(SetArgPointee<1>(2), Return(Status())));
586         EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::THUD), _))
587                 .Times(Exactly(1))
588                 .WillRepeatedly(DoAll(SetArgPointee<1>(3), Return(Status())));
589 
590         EXPECT_CALL(*mMockHal.get(), compose(Eq(emptyEffects), _))
591                 .Times(Exactly(1))
592                 .WillRepeatedly(DoAll(TriggerCallbackInArg1(), Return(Status())));
593         EXPECT_CALL(*mMockHal.get(), compose(Eq(singleEffect), _))
594                 .Times(Exactly(1))
595                 .WillRepeatedly(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)));
596         EXPECT_CALL(*mMockHal.get(), compose(Eq(multipleEffects), _))
597                 .Times(Exactly(1))
598                 .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
599     }
600 
601     std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
602     auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
603 
604     auto result = mWrapper->performComposedEffect(emptyEffects, callback);
605     ASSERT_TRUE(result.isOk());
606     ASSERT_EQ(0ms, result.value());
607     ASSERT_EQ(1, *callbackCounter.get());
608 
609     result = mWrapper->performComposedEffect(singleEffect, callback);
610     ASSERT_TRUE(result.isUnsupported());
611     // Callback not triggered for unsupported
612     ASSERT_EQ(1, *callbackCounter.get());
613 
614     result = mWrapper->performComposedEffect(multipleEffects, callback);
615     ASSERT_TRUE(result.isFailed());
616     // Callback not triggered on failure
617     ASSERT_EQ(1, *callbackCounter.get());
618 }
619 
TEST_F(VibratorHalWrapperAidlTest,TestPerformComposedCachesPrimitiveDurationsAndIgnoresFailures)620 TEST_F(VibratorHalWrapperAidlTest, TestPerformComposedCachesPrimitiveDurationsAndIgnoresFailures) {
621     std::vector<CompositePrimitive> supportedPrimitives = {CompositePrimitive::SPIN,
622                                                            CompositePrimitive::THUD};
623     std::vector<CompositeEffect> multipleEffects;
624     multipleEffects.push_back(
625             vibrator::TestFactory::createCompositeEffect(CompositePrimitive::SPIN, 10ms, 0.5f));
626     multipleEffects.push_back(
627             vibrator::TestFactory::createCompositeEffect(CompositePrimitive::THUD, 100ms, 1.0f));
628 
629     {
630         InSequence seq;
631         EXPECT_CALL(*mMockHal.get(), getSupportedPrimitives(_))
632                 .Times(Exactly(1))
633                 .WillRepeatedly(DoAll(SetArgPointee<0>(supportedPrimitives), Return(Status())));
634         EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::SPIN), _))
635                 .Times(Exactly(1))
636                 .WillRepeatedly(DoAll(SetArgPointee<1>(2), Return(Status())));
637         EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::THUD), _))
638                 .Times(Exactly(1))
639                 .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
640         EXPECT_CALL(*mMockHal.get(), compose(Eq(multipleEffects), _))
641                 .Times(Exactly(1))
642                 .WillRepeatedly(DoAll(TriggerCallbackInArg1(), Return(Status())));
643 
644         EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::SPIN), _))
645                 .Times(Exactly(1))
646                 .WillRepeatedly(DoAll(SetArgPointee<1>(2), Return(Status())));
647         EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::THUD), _))
648                 .Times(Exactly(1))
649                 .WillRepeatedly(DoAll(SetArgPointee<1>(2), Return(Status())));
650         EXPECT_CALL(*mMockHal.get(), compose(Eq(multipleEffects), _))
651                 .Times(Exactly(2))
652                 .WillRepeatedly(DoAll(TriggerCallbackInArg1(), Return(Status())));
653     }
654 
655     std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
656     auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
657 
658     auto result = mWrapper->performComposedEffect(multipleEffects, callback);
659     ASSERT_TRUE(result.isOk());
660     ASSERT_EQ(112ms, result.value()); // Failed primitive durations counted as 1.
661     ASSERT_EQ(1, *callbackCounter.get());
662 
663     result = mWrapper->performComposedEffect(multipleEffects, callback);
664     ASSERT_TRUE(result.isOk());
665     ASSERT_EQ(114ms, result.value()); // Second fetch succeeds and returns primitive duration.
666     ASSERT_EQ(2, *callbackCounter.get());
667 
668     result = mWrapper->performComposedEffect(multipleEffects, callback);
669     ASSERT_TRUE(result.isOk());
670     ASSERT_EQ(114ms, result.value()); // Cached durations not fetched again, same duration returned.
671     ASSERT_EQ(3, *callbackCounter.get());
672 }
673 
TEST_F(VibratorHalWrapperAidlTest,TestPerformPwleEffect)674 TEST_F(VibratorHalWrapperAidlTest, TestPerformPwleEffect) {
675     std::vector<PrimitivePwle> emptyPrimitives, multiplePrimitives;
676     multiplePrimitives.push_back(vibrator::TestFactory::createActivePwle(0, 1, 0, 1, 10ms));
677     multiplePrimitives.push_back(vibrator::TestFactory::createBrakingPwle(Braking::NONE, 100ms));
678 
679     {
680         InSequence seq;
681         EXPECT_CALL(*mMockHal.get(), composePwle(Eq(emptyPrimitives), _))
682                 .Times(Exactly(1))
683                 .WillRepeatedly(Return(
684                         Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)));
685         EXPECT_CALL(*mMockHal.get(), composePwle(Eq(multiplePrimitives), _))
686                 .Times(Exactly(2))
687                 .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
688                 .WillRepeatedly(DoAll(TriggerCallbackInArg1(), Return(Status())));
689     }
690 
691     std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
692     auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
693 
694     auto result = mWrapper->performPwleEffect(emptyPrimitives, callback);
695     ASSERT_TRUE(result.isUnsupported());
696     // Callback not triggered on failure
697     ASSERT_EQ(0, *callbackCounter.get());
698 
699     result = mWrapper->performPwleEffect(multiplePrimitives, callback);
700     ASSERT_TRUE(result.isFailed());
701     // Callback not triggered for unsupported
702     ASSERT_EQ(0, *callbackCounter.get());
703 
704     result = mWrapper->performPwleEffect(multiplePrimitives, callback);
705     ASSERT_TRUE(result.isOk());
706     ASSERT_EQ(1, *callbackCounter.get());
707 }
708