[DO NOT MERGE] cs40l26: Fix the temporary no function symptom am: 97a989bfba

Original change: https://googleplex-android-review.googlesource.com/c/device/google/felix/+/20768377

Change-Id: I23de2ad2f77b58adea3db39bb285cdb1dc819818
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Chase Wu 2022-12-20 12:32:54 +00:00 committed by Automerger Merge Worker
commit ddebaac2a0
3 changed files with 56 additions and 45 deletions

View file

@ -220,7 +220,6 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
} }
bool eraseOwtEffect(int fd, int8_t effectIndex, std::vector<ff_effect> *effect) override { bool eraseOwtEffect(int fd, int8_t effectIndex, std::vector<ff_effect> *effect) override {
uint32_t effectCountBefore, effectCountAfter, i, successFlush = 0; uint32_t effectCountBefore, effectCountAfter, i, successFlush = 0;
static constexpr uint32_t MIN_ON_OFF_INTERVAL_US = 8500; // SVC initialization time
if (effectIndex < WAVEFORM_MAX_PHYSICAL_INDEX) { if (effectIndex < WAVEFORM_MAX_PHYSICAL_INDEX) {
ALOGE("Invalid waveform index for OWT erase: %d", effectIndex); ALOGE("Invalid waveform index for OWT erase: %d", effectIndex);
@ -258,7 +257,7 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
} }
} }
// Turn on the waiting time for SVC init phase to complete // Turn on the waiting time for SVC init phase to complete
setMinOnOffInterval(MIN_ON_OFF_INTERVAL_US); setMinOnOffInterval(Vibrator::MIN_ON_OFF_INTERVAL_US);
return true; return true;
} }

View file

@ -53,7 +53,6 @@ static constexpr uint32_t WAVEFORM_LONG_VIBRATION_THRESHOLD_MS = 50;
static constexpr uint8_t VOLTAGE_SCALE_MAX = 100; static constexpr uint8_t VOLTAGE_SCALE_MAX = 100;
static constexpr int8_t MAX_COLD_START_LATENCY_MS = 6; // I2C Transaction + DSP Return-From-Standby static constexpr int8_t MAX_COLD_START_LATENCY_MS = 6; // I2C Transaction + DSP Return-From-Standby
static constexpr uint32_t MIN_ON_OFF_INTERVAL_US = 8500; // SVC initialization time
static constexpr int8_t MAX_PAUSE_TIMING_ERROR_MS = 1; // ALERT Irq Handling static constexpr int8_t MAX_PAUSE_TIMING_ERROR_MS = 1; // ALERT Irq Handling
static constexpr uint32_t MAX_TIME_MS = UINT16_MAX; static constexpr uint32_t MAX_TIME_MS = UINT16_MAX;
static constexpr float SETTING_TIME_OVERHEAD = 26; // This time was combined by static constexpr float SETTING_TIME_OVERHEAD = 26; // This time was combined by
@ -570,24 +569,23 @@ ndk::ScopedAStatus Vibrator::off() {
ALOGE("Off: Failed to stop effect %d (%d): %s", mActiveId, errno, strerror(errno)); ALOGE("Off: Failed to stop effect %d (%d): %s", mActiveId, errno, strerror(errno));
ret = false; ret = false;
} }
if (mIsDual && (!mHwApiDual->setFFPlay(mInputFdDual, mActiveId, false))) {
ALOGE("Off: Failed to stop flip's effect %d (%d): %s", mActiveId, errno,
strerror(errno));
ret = false;
}
/* Do erase process */
if ((mActiveId >= WAVEFORM_MAX_PHYSICAL_INDEX) && if ((mActiveId >= WAVEFORM_MAX_PHYSICAL_INDEX) &&
(!mHwApiDef->eraseOwtEffect(mInputFd, mActiveId, &mFfEffects))) { (!mHwApiDef->eraseOwtEffect(mInputFd, mActiveId, &mFfEffects))) {
ALOGE("Off: Failed to clean up the composed effect %d", mActiveId); ALOGE("Off: Failed to clean up the composed effect %d", mActiveId);
ret = false; ret = false;
} }
if (mIsDual) { if (mIsDual && (mActiveId >= WAVEFORM_MAX_PHYSICAL_INDEX) &&
if (!mHwApiDual->setFFPlay(mInputFdDual, mActiveId, false)) {
ALOGE("Off: Failed to stop flip's effect %d (%d): %s", mActiveId, errno,
strerror(errno));
ret = false;
}
if ((mActiveId >= WAVEFORM_MAX_PHYSICAL_INDEX) &&
(!mHwApiDual->eraseOwtEffect(mInputFdDual, mActiveId, &mFfEffectsDual))) { (!mHwApiDual->eraseOwtEffect(mInputFdDual, mActiveId, &mFfEffectsDual))) {
ALOGE("Off: Failed to clean up flip's the composed effect %d", mActiveId); ALOGE("Off: Failed to clean up flip's the composed effect %d", mActiveId);
ret = false; ret = false;
} }
}
if (!mHwGPIO->setGPIOOutput(false)) { if (!mHwGPIO->setGPIOOutput(false)) {
ALOGE("Off: Failed to reset GPIO(%d): %s", errno, strerror(errno)); ALOGE("Off: Failed to reset GPIO(%d): %s", errno, strerror(errno));
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
@ -596,7 +594,6 @@ ndk::ScopedAStatus Vibrator::off() {
ALOGD("Off: Vibrator is already off"); ALOGD("Off: Vibrator is already off");
} }
mActiveId = -1;
setGlobalAmplitude(false); setGlobalAmplitude(false);
if (mF0Offset) { if (mF0Offset) {
mHwApiDef->setF0Offset(0); mHwApiDef->setF0Offset(0);
@ -607,6 +604,7 @@ ndk::ScopedAStatus Vibrator::off() {
if (ret) { if (ret) {
ALOGD("Off: Done."); ALOGD("Off: Done.");
mActiveId = -1;
return ndk::ScopedAStatus::ok(); return ndk::ScopedAStatus::ok();
} else { } else {
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
@ -725,6 +723,7 @@ ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect> &composi
ALOGD("Vibrator::compose"); ALOGD("Vibrator::compose");
uint16_t size; uint16_t size;
uint16_t nextEffectDelay; uint16_t nextEffectDelay;
uint16_t totalDuration = 0;
auto ch = dspmem_chunk_create(new uint8_t[FF_CUSTOM_DATA_LEN_MAX_COMP]{0x00}, auto ch = dspmem_chunk_create(new uint8_t[FF_CUSTOM_DATA_LEN_MAX_COMP]{0x00},
FF_CUSTOM_DATA_LEN_MAX_COMP); FF_CUSTOM_DATA_LEN_MAX_COMP);
@ -735,6 +734,7 @@ ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect> &composi
/* Check if there is a wait before the first effect. */ /* Check if there is a wait before the first effect. */
nextEffectDelay = composite.front().delayMs; nextEffectDelay = composite.front().delayMs;
totalDuration += nextEffectDelay;
if (nextEffectDelay > COMPOSE_DELAY_MAX_MS || nextEffectDelay < 0) { if (nextEffectDelay > COMPOSE_DELAY_MAX_MS || nextEffectDelay < 0) {
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
} else if (nextEffectDelay > 0) { } else if (nextEffectDelay > 0) {
@ -769,6 +769,7 @@ ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect> &composi
return status; return status;
} }
effectVolLevel = intensityToVolLevel(e_curr.scale, effectIndex); effectVolLevel = intensityToVolLevel(e_curr.scale, effectIndex);
totalDuration += mEffectDurations[effectIndex];
} }
/* Fetch the next composite effect delay and fill into the current section */ /* Fetch the next composite effect delay and fill into the current section */
@ -781,6 +782,7 @@ ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect> &composi
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
} }
nextEffectDelay = delay; nextEffectDelay = delay;
totalDuration += delay;
} }
if (effectIndex == 0 && nextEffectDelay == 0) { if (effectIndex == 0 && nextEffectDelay == 0) {
@ -797,6 +799,10 @@ ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect> &composi
if (header_count == dspmem_chunk_bytes(ch)) { if (header_count == dspmem_chunk_bytes(ch)) {
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
} else { } else {
mFfEffects[WAVEFORM_COMPOSE].replay.length = totalDuration;
if (mIsDual) {
mFfEffectsDual[WAVEFORM_COMPOSE].replay.length = totalDuration;
}
return performEffect(WAVEFORM_MAX_INDEX /*ignored*/, VOLTAGE_SCALE_MAX /*ignored*/, ch, return performEffect(WAVEFORM_MAX_INDEX /*ignored*/, VOLTAGE_SCALE_MAX /*ignored*/, ch,
callback); callback);
} }
@ -1325,7 +1331,7 @@ binder_status_t Vibrator::dump(int fd, const char **args, uint32_t numArgs) {
} }
dprintf(fd, "Base: OWT waveform:\n"); dprintf(fd, "Base: OWT waveform:\n");
dprintf(fd, "\tId\tBytes\tData\ttrigger button\n"); dprintf(fd, "\tId\tBytes\tData\tt\ttrigger button\n");
for (effectId = WAVEFORM_MAX_PHYSICAL_INDEX; effectId < WAVEFORM_MAX_INDEX; effectId++) { for (effectId = WAVEFORM_MAX_PHYSICAL_INDEX; effectId < WAVEFORM_MAX_INDEX; effectId++) {
uint32_t numBytes = mFfEffects[effectId].u.periodic.custom_len * 2; uint32_t numBytes = mFfEffects[effectId].u.periodic.custom_len * 2;
std::stringstream ss; std::stringstream ss;
@ -1337,12 +1343,12 @@ binder_status_t Vibrator::dump(int fd, const char **args, uint32_t numArgs) {
i)) i))
<< " "; << " ";
} }
dprintf(fd, "\t%d\t%d\t{%s}\t%X\n", mFfEffects[effectId].id, numBytes, ss.str().c_str(), dprintf(fd, "\t%d\t%d\t{%s}\t%u\t%X\n", mFfEffects[effectId].id, numBytes, ss.str().c_str(),
mFfEffects[effectId].trigger.button); mFfEffectsDual[effectId].replay.length, mFfEffects[effectId].trigger.button);
} }
if (mIsDual) { if (mIsDual) {
dprintf(fd, "Flip: OWT waveform:\n"); dprintf(fd, "Flip: OWT waveform:\n");
dprintf(fd, "\tId\tBytes\tData\ttrigger button\n"); dprintf(fd, "\tId\tBytes\tData\tt\ttrigger button\n");
for (effectId = WAVEFORM_MAX_PHYSICAL_INDEX; effectId < WAVEFORM_MAX_INDEX; effectId++) { for (effectId = WAVEFORM_MAX_PHYSICAL_INDEX; effectId < WAVEFORM_MAX_INDEX; effectId++) {
uint32_t numBytes = mFfEffectsDual[effectId].u.periodic.custom_len * 2; uint32_t numBytes = mFfEffectsDual[effectId].u.periodic.custom_len * 2;
std::stringstream ss; std::stringstream ss;
@ -1354,8 +1360,9 @@ binder_status_t Vibrator::dump(int fd, const char **args, uint32_t numArgs) {
i)) i))
<< " "; << " ";
} }
dprintf(fd, "\t%d\t%d\t{%s}\t%X\n", mFfEffectsDual[effectId].id, numBytes, dprintf(fd, "\t%d\t%d\t{%s}\t%u\t%X\n", mFfEffectsDual[effectId].id, numBytes,
ss.str().c_str(), mFfEffectsDual[effectId].trigger.button); ss.str().c_str(), mFfEffectsDual[effectId].replay.length,
mFfEffectsDual[effectId].trigger.button);
} }
} }
dprintf(fd, "\n"); dprintf(fd, "\n");
@ -1606,37 +1613,40 @@ void Vibrator::waitForComplete(std::shared_ptr<IVibratorCallback> &&callback) {
ALOGD("waitForComplete: get STOP"); ALOGD("waitForComplete: get STOP");
{ {
const std::scoped_lock<std::mutex> lock(mActiveId_mutex); const std::scoped_lock<std::mutex> lock(mActiveId_mutex);
uint32_t effectCount; if (mActiveId >= WAVEFORM_MAX_PHYSICAL_INDEX) {
mHwApiDef->getEffectCount(&effectCount); if (!mHwApiDef->eraseOwtEffect(mInputFd, mActiveId, &mFfEffects)) {
if (mActiveId >= 0) {
if ((mActiveId >= WAVEFORM_MAX_PHYSICAL_INDEX) &&
(!mHwApiDef->eraseOwtEffect(mInputFd, mActiveId, &mFfEffects))) {
ALOGE("Failed to clean up the composed effect %d", mActiveId); ALOGE("Failed to clean up the composed effect %d", mActiveId);
} }
if (mIsDual && (mActiveId >= WAVEFORM_MAX_PHYSICAL_INDEX) && if (mIsDual &&
(!mHwApiDual->eraseOwtEffect(mInputFdDual, mActiveId, &mFfEffectsDual))) { (!mHwApiDual->eraseOwtEffect(mInputFdDual, mActiveId, &mFfEffectsDual))) {
ALOGE("Failed to clean up flip's composed effect %d", mActiveId); ALOGE("Failed to clean up flip's composed effect %d", mActiveId);
} }
} else {
ALOGD("waitForComplete: Vibrator is already off");
}
mActiveId = -1;
if (mGPIOStatus && !mHwGPIO->setGPIOOutput(false)) { if (mGPIOStatus && !mHwGPIO->setGPIOOutput(false)) {
ALOGE("waitForComplete: Failed to reset GPIO(%d): %s", errno, strerror(errno)); ALOGE("waitForComplete: Failed to reset GPIO(%d): %s", errno, strerror(errno));
} }
// Do waveform number checking
mActiveId = -1; uint32_t effectCount = WAVEFORM_MAX_PHYSICAL_INDEX;
} else if (effectCount > WAVEFORM_MAX_PHYSICAL_INDEX) { mHwApiDef->getEffectCount(&effectCount);
if (!mHwApiDef->eraseOwtEffect(mInputFd, effectCount - 1, &mFfEffects)) { if (effectCount > WAVEFORM_MAX_PHYSICAL_INDEX) {
ALOGE("Failed to clean up the composed effect %d", effectCount - 1); // Forcibly clean all OWT waveforms
if (!mHwApiDef->eraseOwtEffect(mInputFd, WAVEFORM_MAX_INDEX, &mFfEffects)) {
ALOGE("Failed to clean up all base's composed effect");
} }
}
if (mIsDual) { if (mIsDual) {
// Forcibly clean all OWT waveforms
effectCount = WAVEFORM_MAX_PHYSICAL_INDEX;
mHwApiDual->getEffectCount(&effectCount); mHwApiDual->getEffectCount(&effectCount);
if ((effectCount > WAVEFORM_MAX_PHYSICAL_INDEX) && if ((effectCount > WAVEFORM_MAX_PHYSICAL_INDEX) &&
(!mHwApiDual->eraseOwtEffect(mInputFdDual, effectCount - 1, &mFfEffectsDual))) { (!mHwApiDual->eraseOwtEffect(mInputFdDual, WAVEFORM_MAX_INDEX, &mFfEffectsDual))) {
ALOGE("Failed to clean up flip's composed effect %d", effectCount - 1); ALOGE("Failed to clean up all flip's composed effect");
} }
} }
} else {
ALOGD("waitForComplete: Vibrator is already off");
}
} }
if (callback) { if (callback) {

View file

@ -175,6 +175,8 @@ class Vibrator : public BnVibrator {
// BnCInterface APIs // BnCInterface APIs
binder_status_t dump(int fd, const char **args, uint32_t numArgs) override; binder_status_t dump(int fd, const char **args, uint32_t numArgs) override;
static constexpr uint32_t MIN_ON_OFF_INTERVAL_US = 8500; // SVC initialization time
private: private:
ndk::ScopedAStatus on(uint32_t timeoutMs, uint32_t effectIndex, struct dspmem_chunk *ch, ndk::ScopedAStatus on(uint32_t timeoutMs, uint32_t effectIndex, struct dspmem_chunk *ch,
const std::shared_ptr<IVibratorCallback> &callback); const std::shared_ptr<IVibratorCallback> &callback);