diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-01-11 20:52:08 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-01-11 20:52:08 +0000 |
commit | 1317641317eebee91988e5e338277a31c835eee2 (patch) | |
tree | 444326570a6d35e0615a527102cc48624aa3a4a9 | |
parent | 85f48d068c065085ed2103d8ec2365be19ce47b4 (diff) | |
parent | 5d44008b8ae7354c905c7f5b5a8a9c77c889825d (diff) | |
download | pixel-android13-qpr2-s2-release.tar.gz |
Merge cherrypicks of ['ag/20865905'] into tm-qpr2-release.android-13.0.0_r37android-13.0.0_r36android-13.0.0_r35android-13.0.0_r34android-13.0.0_r33android-13.0.0_r32android13-qpr2-s6-releaseandroid13-qpr2-s5-releaseandroid13-qpr2-s3-releaseandroid13-qpr2-s2-releaseandroid13-qpr2-s1-release
Change-Id: I4a8ed9cbbb7a878d05d0ce1a98ca138bccb7fc63
-rw-r--r-- | vibrator/cs40l25/Android.bp | 2 | ||||
-rw-r--r-- | vibrator/cs40l25/Hardware.h | 4 | ||||
-rw-r--r-- | vibrator/cs40l25/Vibrator.cpp | 54 | ||||
-rw-r--r-- | vibrator/cs40l25/Vibrator.h | 6 | ||||
-rw-r--r-- | vibrator/cs40l25/android.hardware.vibrator-service.cs40l25.rc | 1 | ||||
-rw-r--r-- | vibrator/cs40l25/tests/mocks.h | 2 | ||||
-rw-r--r-- | vibrator/cs40l25/tests/test-vibrator.cpp | 46 |
7 files changed, 90 insertions, 25 deletions
diff --git a/vibrator/cs40l25/Android.bp b/vibrator/cs40l25/Android.bp index 13d59adb..d968eda6 100644 --- a/vibrator/cs40l25/Android.bp +++ b/vibrator/cs40l25/Android.bp @@ -110,7 +110,7 @@ cc_binary { srcs: ["service.cpp"], shared_libs: ["android.hardware.vibrator-impl.cs40l25"], cflags: [ - "-DLOG_TAG=\"android.hardware.vibrator-cs40l25\"", + "-DLOG_TAG=\"Vibrator\"", ], proprietary: true, } diff --git a/vibrator/cs40l25/Hardware.h b/vibrator/cs40l25/Hardware.h index 167e382b..e2222798 100644 --- a/vibrator/cs40l25/Hardware.h +++ b/vibrator/cs40l25/Hardware.h @@ -72,7 +72,9 @@ class HwApi : public Vibrator::HwApi, private HwApiBase { bool setGpioFallScale(uint32_t value) override { return set(value, &mGpioFallScale); } bool setGpioRiseIndex(uint32_t value) override { return set(value, &mGpioRiseIndex); } bool setGpioRiseScale(uint32_t value) override { return set(value, &mGpioRiseScale); } - bool pollVibeState(bool value) override { return poll(value, &mVibeState); } + bool pollVibeState(uint32_t value, int32_t timeoutMs) override { + return poll(value, &mVibeState, timeoutMs); + } bool setClabEnable(bool value) override { return set(value, &mClabEnable); } bool getAvailablePwleSegments(uint32_t *value) override { return get(value, &mAvailablePwleSegments); diff --git a/vibrator/cs40l25/Vibrator.cpp b/vibrator/cs40l25/Vibrator.cpp index ba4efadf..b868cfd5 100644 --- a/vibrator/cs40l25/Vibrator.cpp +++ b/vibrator/cs40l25/Vibrator.cpp @@ -65,7 +65,6 @@ static constexpr uint32_t WAVEFORM_LOW_TICK_INDEX = 10; static constexpr uint32_t WAVEFORM_UNSAVED_TRIGGER_QUEUE_INDEX = 65529; static constexpr uint32_t WAVEFORM_TRIGGER_QUEUE_INDEX = 65534; - static constexpr uint32_t VOLTAGE_GLOBAL_SCALE_LEVEL = 5; static constexpr uint8_t VOLTAGE_SCALE_MAX = 100; @@ -77,6 +76,7 @@ static constexpr float AMP_ATTENUATE_STEP_SIZE = 0.125f; static constexpr float EFFECT_FREQUENCY_KHZ = 48.0f; static constexpr auto ASYNC_COMPLETION_TIMEOUT = std::chrono::milliseconds(100); +static constexpr auto POLLING_TIMEOUT = 20; static constexpr int32_t COMPOSE_DELAY_MAX_MS = 10000; static constexpr int32_t COMPOSE_SIZE_MAX = 127; @@ -306,6 +306,7 @@ ndk::ScopedAStatus Vibrator::getCapabilities(int32_t *_aidl_return) { ndk::ScopedAStatus Vibrator::off() { ATRACE_NAME("Vibrator::off"); + ALOGD("Vibrator::off"); setGlobalAmplitude(false); mHwApi->setF0Offset(0); if (!mHwApi->setActivate(0)) { @@ -319,6 +320,7 @@ ndk::ScopedAStatus Vibrator::off() { ndk::ScopedAStatus Vibrator::on(int32_t timeoutMs, const std::shared_ptr<IVibratorCallback> &callback) { ATRACE_NAME("Vibrator::on"); + ALOGD("Vibrator::on"); const uint32_t index = timeoutMs < WAVEFORM_LONG_VIBRATION_THRESHOLD_MS ? WAVEFORM_SHORT_VIBRATION_EFFECT_INDEX : WAVEFORM_LONG_VIBRATION_EFFECT_INDEX; @@ -334,6 +336,7 @@ ndk::ScopedAStatus Vibrator::perform(Effect effect, EffectStrength strength, const std::shared_ptr<IVibratorCallback> &callback, int32_t *_aidl_return) { ATRACE_NAME("Vibrator::perform"); + ALOGD("Vibrator::perform"); return performEffect(effect, strength, callback, _aidl_return); } @@ -443,6 +446,7 @@ ndk::ScopedAStatus Vibrator::getPrimitiveDuration(CompositePrimitive primitive, ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect> &composite, const std::shared_ptr<IVibratorCallback> &callback) { ATRACE_NAME("Vibrator::compose"); + ALOGD("Vibrator::compose"); std::ostringstream effectBuilder; std::string effectQueue; @@ -450,6 +454,11 @@ ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect> &composi return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } + // Reset the mTotalDuration + { + const std::scoped_lock<std::mutex> lock(mTotalDurationMutex); + mTotalDuration = 0; + } for (auto &e : composite) { if (e.scale < 0.0f || e.scale > 1.0f) { return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); @@ -460,6 +469,10 @@ ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect> &composi return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } effectBuilder << e.delayMs << ","; + { + const std::scoped_lock<std::mutex> lock(mTotalDurationMutex); + mTotalDuration += e.delayMs; + } } if (e.primitive != CompositePrimitive::NOOP) { ndk::ScopedAStatus status; @@ -471,6 +484,10 @@ ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect> &composi } effectBuilder << effectIndex << "." << intensityToVolLevel(e.scale, effectIndex) << ","; + { + const std::scoped_lock<std::mutex> lock(mTotalDurationMutex); + mTotalDuration += mEffectDurations[effectIndex]; + } } } @@ -497,9 +514,17 @@ ndk::ScopedAStatus Vibrator::on(uint32_t timeoutMs, uint32_t effectIndex, return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } + ALOGD("Vibrator::on"); mHwApi->setEffectIndex(effectIndex); mHwApi->setDuration(timeoutMs); mHwApi->setActivate(1); + // Using the mToalDuration for composed effect. + // For composed effect, we set the UINT32_MAX to the duration sysfs node, + // but it not a practical way to use it to monitor the total duration time. + if (timeoutMs != UINT32_MAX) { + const std::scoped_lock<std::mutex> lock(mTotalDurationMutex); + mTotalDuration = timeoutMs; + } mActiveId = effectIndex; @@ -897,7 +922,10 @@ ndk::ScopedAStatus Vibrator::composePwle(const std::vector<PrimitivePwle> &compo totalDuration += MAX_COLD_START_LATENCY_MS; mHwApi->setDuration(totalDuration); - + { + const std::scoped_lock<std::mutex> lock(mTotalDurationMutex); + mTotalDuration = totalDuration; + } mHwApi->setActivate(1); mAsyncHandle = std::async(&Vibrator::waitForComplete, this, callback); @@ -993,6 +1021,10 @@ ndk::ScopedAStatus Vibrator::getSimpleDetails(Effect effect, EffectStrength stre volLevel = intensityToVolLevel(intensity, effectIndex); timeMs = mEffectDurations[effectIndex] + MAX_COLD_START_LATENCY_MS; + { + const std::scoped_lock<std::mutex> lock(mTotalDurationMutex); + mTotalDuration = timeMs; + } *outEffectIndex = effectIndex; *outTimeMs = timeMs; @@ -1037,6 +1069,10 @@ ndk::ScopedAStatus Vibrator::getCompoundDetails(Effect effect, EffectStrength st } effectBuilder << thisEffectIndex << "." << thisVolLevel; timeMs += thisTimeMs; + { + const std::scoped_lock<std::mutex> lock(mTotalDurationMutex); + mTotalDuration = timeMs; + } break; default: @@ -1155,7 +1191,19 @@ ndk::ScopedAStatus Vibrator::performEffect(uint32_t effectIndex, uint32_t volLev } void Vibrator::waitForComplete(std::shared_ptr<IVibratorCallback> &&callback) { - mHwApi->pollVibeState(false); + ALOGD("Vibrator::waitForComplete"); + uint32_t duration; + { + const std::scoped_lock<std::mutex> lock(mTotalDurationMutex); + duration = ((mTotalDuration + POLLING_TIMEOUT) < UINT32_MAX) + ? mTotalDuration + POLLING_TIMEOUT + : UINT32_MAX; + } + if (!mHwApi->pollVibeState(false, duration)) { + ALOGE("Timeout(%u)! Fail to poll STOP state", duration); + } else { + ALOGD("Vibrator::waitForComplete: Get STOP! Set active to 0."); + } mHwApi->setActivate(false); if (callback) { diff --git a/vibrator/cs40l25/Vibrator.h b/vibrator/cs40l25/Vibrator.h index 70543e30..7b6bf2c6 100644 --- a/vibrator/cs40l25/Vibrator.h +++ b/vibrator/cs40l25/Vibrator.h @@ -89,9 +89,9 @@ class Vibrator : public BnVibrator { // Indicates the number of 0.125-dB steps of attenuation to apply to // waveforms triggered in response to a GPIO1 rising edge. virtual bool setGpioRiseScale(uint32_t value) = 0; - // Blocks until vibrator reaches desired state + // Blocks until timeout or vibrator reaches desired state // (true = enabled, false = disabled). - virtual bool pollVibeState(bool value) = 0; + virtual bool pollVibeState(uint32_t value, int32_t timeoutMs = -1) = 0; // Enables/disables closed-loop active braking. virtual bool setClabEnable(bool value) = 0; // Reports the number of available PWLE segments. @@ -232,6 +232,8 @@ class Vibrator : public BnVibrator { bool mIsChirpEnabled; std::vector<float> mBandwidthAmplitudeMap; bool mGenerateBandwidthAmplitudeMapDone; + uint32_t mTotalDuration{0}; + std::mutex mTotalDurationMutex; }; } // namespace vibrator diff --git a/vibrator/cs40l25/android.hardware.vibrator-service.cs40l25.rc b/vibrator/cs40l25/android.hardware.vibrator-service.cs40l25.rc index f373d31f..1025de91 100644 --- a/vibrator/cs40l25/android.hardware.vibrator-service.cs40l25.rc +++ b/vibrator/cs40l25/android.hardware.vibrator-service.cs40l25.rc @@ -71,6 +71,7 @@ service vendor.vibrator.cs40l25 /vendor/bin/hw/android.hardware.vibrator-service device/pwle_ramp_down device/q_stored device/redc_stored + device/vibe_state state " diff --git a/vibrator/cs40l25/tests/mocks.h b/vibrator/cs40l25/tests/mocks.h index efcef527..edd65caa 100644 --- a/vibrator/cs40l25/tests/mocks.h +++ b/vibrator/cs40l25/tests/mocks.h @@ -44,7 +44,7 @@ class MockApi : public ::aidl::android::hardware::vibrator::Vibrator::HwApi { MOCK_METHOD1(setGpioFallScale, bool(uint32_t value)); MOCK_METHOD1(setGpioRiseIndex, bool(uint32_t value)); MOCK_METHOD1(setGpioRiseScale, bool(uint32_t value)); - MOCK_METHOD1(pollVibeState, bool(bool value)); + MOCK_METHOD2(pollVibeState, bool(uint32_t value, int32_t timeoutMs)); MOCK_METHOD1(setClabEnable, bool(bool value)); MOCK_METHOD1(getAvailablePwleSegments, bool(uint32_t *value)); MOCK_METHOD0(hasPwle, bool()); diff --git a/vibrator/cs40l25/tests/test-vibrator.cpp b/vibrator/cs40l25/tests/test-vibrator.cpp index 348322e7..49d12c41 100644 --- a/vibrator/cs40l25/tests/test-vibrator.cpp +++ b/vibrator/cs40l25/tests/test-vibrator.cpp @@ -68,8 +68,8 @@ static EffectScale Scale(float intensity); static constexpr uint32_t CAL_VERSION = 1; static constexpr std::array<EffectLevel, 6> V_LEVELS{40, 50, 60, 70, 80, 90}; -static constexpr std::array<EffectDuration, 10> EFFECT_DURATIONS{0, 0, 15, 0, 50, - 100, 150, 200, 250, 8}; +static constexpr std::array<EffectDuration, 10> EFFECT_DURATIONS{0, 0, 11, 0, 300, + 132, 150, 500, 101, 5}; // Constants With Prescribed Values @@ -84,6 +84,10 @@ static constexpr EffectIndex QUEUE_INDEX{65534}; static const EffectScale ON_GLOBAL_SCALE{levelToScale(V_LEVELS[5])}; static const EffectIndex ON_EFFECT_INDEX{0}; +static constexpr uint32_t WAVEFORM_DOUBLE_CLICK_SILENCE_MS = 100; +static constexpr int8_t MAX_COLD_START_LATENCY_MS = 6; // I2C Transaction + DSP Return-From-Standby +static constexpr int8_t MAX_PAUSE_TIMING_ERROR_MS = 1; // ALERT Irq Handling +static constexpr auto POLLING_TIMEOUT = 20; static const std::map<EffectTuple, EffectScale> EFFECT_SCALE{ {{Effect::CLICK, EffectStrength::LIGHT}, Scale(0.7f * 0.5f)}, @@ -102,13 +106,16 @@ static const std::map<EffectTuple, EffectScale> EFFECT_SCALE{ static const std::map<EffectTuple, EffectQueue> EFFECT_QUEUE{ {{Effect::DOUBLE_CLICK, EffectStrength::LIGHT}, - Queue(QueueEffect{EFFECT_INDEX.at(Effect::CLICK), Level(0.7f * 0.5f)}, 100, + Queue(QueueEffect{EFFECT_INDEX.at(Effect::CLICK), Level(0.7f * 0.5f)}, + WAVEFORM_DOUBLE_CLICK_SILENCE_MS, QueueEffect{EFFECT_INDEX.at(Effect::CLICK), Level(1.0f * 0.5f)})}, {{Effect::DOUBLE_CLICK, EffectStrength::MEDIUM}, - Queue(QueueEffect{EFFECT_INDEX.at(Effect::CLICK), Level(0.7f * 0.7f)}, 100, + Queue(QueueEffect{EFFECT_INDEX.at(Effect::CLICK), Level(0.7f * 0.7f)}, + WAVEFORM_DOUBLE_CLICK_SILENCE_MS, QueueEffect{EFFECT_INDEX.at(Effect::CLICK), Level(1.0f * 0.7f)})}, {{Effect::DOUBLE_CLICK, EffectStrength::STRONG}, - Queue(QueueEffect{EFFECT_INDEX.at(Effect::CLICK), Level(0.7f * 1.0f)}, 100, + Queue(QueueEffect{EFFECT_INDEX.at(Effect::CLICK), Level(0.7f * 1.0f)}, + WAVEFORM_DOUBLE_CLICK_SILENCE_MS, QueueEffect{EFFECT_INDEX.at(Effect::CLICK), Level(1.0f * 1.0f)})}, }; @@ -468,16 +475,17 @@ TEST_P(EffectsTest, perform) { }; ExpectationSet eSetup; - Expectation eActivate, ePoll; + Expectation eActivate, ePollStop; if (scale != EFFECT_SCALE.end()) { EffectIndex index = EFFECT_INDEX.at(effect); - duration = EFFECT_DURATIONS[index]; + duration = EFFECT_DURATIONS[index] + MAX_COLD_START_LATENCY_MS; eSetup += EXPECT_CALL(*mMockApi, setEffectIndex(index)).WillOnce(DoDefault()); eSetup += EXPECT_CALL(*mMockApi, setEffectScale(scale->second)).WillOnce(Return(true)); } else if (queue != EFFECT_QUEUE.end()) { - duration = std::get<1>(queue->second); + duration = std::get<1>(queue->second) + MAX_COLD_START_LATENCY_MS * 2 + + MAX_PAUSE_TIMING_ERROR_MS; eSetup += EXPECT_CALL(*mMockApi, setEffectIndex(QUEUE_INDEX)).WillOnce(DoDefault()); eSetup += EXPECT_CALL(*mMockApi, setEffectQueue(std::get<0>(queue->second))) @@ -490,11 +498,12 @@ TEST_P(EffectsTest, perform) { if (duration) { eSetup += EXPECT_CALL(*mMockApi, setDuration(Ge(duration))).WillOnce(Return(true)); eActivate = EXPECT_CALL(*mMockApi, setActivate(true)).After(eSetup).WillOnce(Return(true)); - ePoll = EXPECT_CALL(*mMockApi, pollVibeState(false)) - .After(eActivate) - .WillOnce(Return(true)); - EXPECT_CALL(*mMockApi, setActivate(false)).After(ePoll).WillOnce(Return(true)); - EXPECT_CALL(*callback, onComplete()).After(ePoll).WillOnce(complete); + ePollStop = EXPECT_CALL(*mMockApi, pollVibeState(false, duration + POLLING_TIMEOUT)) + .After(eActivate) + .WillOnce(DoDefault()); + + EXPECT_CALL(*mMockApi, setActivate(false)).After(ePollStop).WillOnce(Return(true)); + EXPECT_CALL(*callback, onComplete()).After(ePollStop).WillOnce(complete); } int32_t lengthMs; @@ -589,8 +598,9 @@ TEST_P(ComposeTest, compose) { auto param = GetParam(); auto composite = param.composite; auto queue = std::get<0>(param.queue); + auto duration = std::get<1>(param.queue); ExpectationSet eSetup; - Expectation eActivate, ePoll; + Expectation eActivate, ePollStop; auto callback = ndk::SharedRefBase::make<MockVibratorCallback>(); std::promise<void> promise; std::future<void> future{promise.get_future()}; @@ -604,9 +614,11 @@ TEST_P(ComposeTest, compose) { eSetup += EXPECT_CALL(*mMockApi, setEffectScale(0)).WillOnce(Return(true)); eSetup += EXPECT_CALL(*mMockApi, setDuration(UINT32_MAX)).WillOnce(Return(true)); eActivate = EXPECT_CALL(*mMockApi, setActivate(true)).After(eSetup).WillOnce(Return(true)); - ePoll = EXPECT_CALL(*mMockApi, pollVibeState(false)).After(eActivate).WillOnce(Return(true)); - EXPECT_CALL(*mMockApi, setActivate(false)).After(ePoll).WillOnce(Return(true)); - EXPECT_CALL(*callback, onComplete()).After(ePoll).WillOnce(complete); + ePollStop = EXPECT_CALL(*mMockApi, pollVibeState(false, duration + POLLING_TIMEOUT)) + .After(eActivate) + .WillOnce(Return(true)); + EXPECT_CALL(*mMockApi, setActivate(false)).After(ePollStop).WillOnce(Return(true)); + EXPECT_CALL(*callback, onComplete()).After(ePollStop).WillOnce(complete); EXPECT_EQ(EX_NONE, mVibrator->compose(composite, callback).getExceptionCode()); |