summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-01-11 20:52:08 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-01-11 20:52:08 +0000
commit1317641317eebee91988e5e338277a31c835eee2 (patch)
tree444326570a6d35e0615a527102cc48624aa3a4a9
parent85f48d068c065085ed2103d8ec2365be19ce47b4 (diff)
parent5d44008b8ae7354c905c7f5b5a8a9c77c889825d (diff)
downloadpixel-android13-qpr2-s2-release.tar.gz
Change-Id: I4a8ed9cbbb7a878d05d0ce1a98ca138bccb7fc63
-rw-r--r--vibrator/cs40l25/Android.bp2
-rw-r--r--vibrator/cs40l25/Hardware.h4
-rw-r--r--vibrator/cs40l25/Vibrator.cpp54
-rw-r--r--vibrator/cs40l25/Vibrator.h6
-rw-r--r--vibrator/cs40l25/android.hardware.vibrator-service.cs40l25.rc1
-rw-r--r--vibrator/cs40l25/tests/mocks.h2
-rw-r--r--vibrator/cs40l25/tests/test-vibrator.cpp46
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());