diff --git a/vibrator/cs40l26/Hardware.h b/vibrator/cs40l26/Hardware.h index af8d120..69cf9ae 100644 --- a/vibrator/cs40l26/Hardware.h +++ b/vibrator/cs40l26/Hardware.h @@ -104,18 +104,25 @@ class HwApi : public Vibrator::HwApi, private HwApiBase { .code = FF_GAIN, .value = value, }; + if (value > 100) { + ALOGE("Invalid gain"); + return false; + } if (write(fd, (const void *)&gain, sizeof(gain)) != sizeof(gain)) { return false; } return true; } bool setFFEffect(int fd, struct ff_effect *effect, uint16_t timeoutMs) override { + if (effect == nullptr) { + ALOGE("Invalid ff_effect"); + return false; + } if (ioctl(fd, EVIOCSFF, effect) < 0) { ALOGE("setFFEffect fail"); return false; - } else { - return true; } + return true; } bool setFFPlay(int fd, int8_t index, bool value) override { struct input_event play = { @@ -186,14 +193,17 @@ class HwApi : public Vibrator::HwApi, private HwApiBase { } bool uploadOwtEffect(int fd, const uint8_t *owtData, const uint32_t numBytes, struct ff_effect *effect, uint32_t *outEffectIndex, int *status) override { - (*effect).u.periodic.custom_len = numBytes / sizeof(uint16_t); - delete[] ((*effect).u.periodic.custom_data); - (*effect).u.periodic.custom_data = new int16_t[(*effect).u.periodic.custom_len]{0x0000}; - if ((*effect).u.periodic.custom_data == nullptr) { - ALOGE("Failed to allocate memory for custom data\n"); + if (owtData == nullptr || effect == nullptr || outEffectIndex == nullptr) { + ALOGE("Invalid argument owtData, ff_effect or outEffectIndex"); *status = EX_NULL_POINTER; return false; } + if (status == nullptr) { + ALOGE("Invalid argument status"); + return false; + } + + (*effect).u.periodic.custom_len = numBytes / sizeof(uint16_t); memcpy((*effect).u.periodic.custom_data, owtData, numBytes); if ((*effect).id != -1) { @@ -204,7 +214,6 @@ class HwApi : public Vibrator::HwApi, private HwApiBase { (*effect).id = -1; if (ioctl(fd, EVIOCSFF, effect) < 0) { ALOGE("Failed to upload effect %d (%d): %s", *outEffectIndex, errno, strerror(errno)); - delete[] ((*effect).u.periodic.custom_data); *status = EX_ILLEGAL_STATE; return false; } diff --git a/vibrator/cs40l26/Vibrator.cpp b/vibrator/cs40l26/Vibrator.cpp index 2abe72e..b3ce88e 100644 --- a/vibrator/cs40l26/Vibrator.cpp +++ b/vibrator/cs40l26/Vibrator.cpp @@ -44,7 +44,6 @@ namespace aidl { namespace android { namespace hardware { namespace vibrator { -static constexpr uint8_t FF_CUSTOM_DATA_LEN = 2; static constexpr uint16_t FF_CUSTOM_DATA_LEN_MAX_COMP = 2044; // (COMPOSE_SIZE_MAX + 1) * 8 + 4 static constexpr uint16_t FF_CUSTOM_DATA_LEN_MAX_PWLE = 2302; @@ -488,19 +487,23 @@ Vibrator::Vibrator(std::unique_ptr hwApiDefault, std::unique_ptr h mEffectDurations = { 1000, 100, 12, 1000, 300, 130, 150, 500, 100, 5, 12, 1000, 1000, 1000, }; /* 11+3 waveforms. The duration must < UINT16_MAX */ + mEffectCustomData.reserve(WAVEFORM_MAX_INDEX); uint8_t effectIndex; + uint16_t numBytes = 0; for (effectIndex = 0; effectIndex < WAVEFORM_MAX_INDEX; effectIndex++) { if (effectIndex < WAVEFORM_MAX_PHYSICAL_INDEX) { /* Initialize physical waveforms. */ + mEffectCustomData.push_back({RAM_WVFRM_BANK, effectIndex}); mFfEffects[effectIndex] = { .type = FF_PERIODIC, .id = -1, // Length == 0 to allow firmware control of the duration .replay.length = 0, .u.periodic.waveform = FF_CUSTOM, - .u.periodic.custom_data = new int16_t[2]{RAM_WVFRM_BANK, effectIndex}, - .u.periodic.custom_len = FF_CUSTOM_DATA_LEN, + .u.periodic.custom_data = mEffectCustomData[effectIndex].data(), + .u.periodic.custom_len = + static_cast(mEffectCustomData[effectIndex].size()), }; // Bypass the waveform update due to different input name if ((strstr(inputEventName, "cs40l26") != nullptr) || @@ -518,12 +521,16 @@ Vibrator::Vibrator(std::unique_ptr hwApiDefault, std::unique_ptr h } } else { /* Initiate placeholders for OWT effects. */ + numBytes = effectIndex == WAVEFORM_COMPOSE ? FF_CUSTOM_DATA_LEN_MAX_COMP + : FF_CUSTOM_DATA_LEN_MAX_PWLE; + std::vector tempVec(numBytes, 0); + mEffectCustomData.push_back(std::move(tempVec)); mFfEffects[effectIndex] = { .type = FF_PERIODIC, .id = -1, .replay.length = 0, .u.periodic.waveform = FF_CUSTOM, - .u.periodic.custom_data = nullptr, + .u.periodic.custom_data = mEffectCustomData[effectIndex].data(), .u.periodic.custom_len = 0, }; } @@ -532,18 +539,21 @@ Vibrator::Vibrator(std::unique_ptr hwApiDefault, std::unique_ptr h // ====================HAL internal effect table== Flip ================================== if (mIsDual) { mFfEffectsDual.resize(WAVEFORM_MAX_INDEX); + mEffectCustomDataDual.reserve(WAVEFORM_MAX_INDEX); for (effectIndex = 0; effectIndex < WAVEFORM_MAX_INDEX; effectIndex++) { if (effectIndex < WAVEFORM_MAX_PHYSICAL_INDEX) { /* Initialize physical waveforms. */ + mEffectCustomDataDual.push_back({RAM_WVFRM_BANK, effectIndex}); mFfEffectsDual[effectIndex] = { .type = FF_PERIODIC, .id = -1, // Length == 0 to allow firmware control of the duration .replay.length = 0, .u.periodic.waveform = FF_CUSTOM, - .u.periodic.custom_data = new int16_t[2]{RAM_WVFRM_BANK, effectIndex}, - .u.periodic.custom_len = FF_CUSTOM_DATA_LEN, + .u.periodic.custom_data = mEffectCustomDataDual[effectIndex].data(), + .u.periodic.custom_len = + static_cast(mEffectCustomDataDual[effectIndex].size()), }; // Bypass the waveform update due to different input name if ((strstr(inputEventName, "cs40l26") != nullptr) || @@ -563,12 +573,16 @@ Vibrator::Vibrator(std::unique_ptr hwApiDefault, std::unique_ptr h } } else { /* Initiate placeholders for OWT effects. */ + numBytes = effectIndex == WAVEFORM_COMPOSE ? FF_CUSTOM_DATA_LEN_MAX_COMP + : FF_CUSTOM_DATA_LEN_MAX_PWLE; + std::vector tempVec(numBytes, 0); + mEffectCustomDataDual.push_back(std::move(tempVec)); mFfEffectsDual[effectIndex] = { .type = FF_PERIODIC, .id = -1, .replay.length = 0, .u.periodic.waveform = FF_CUSTOM, - .u.periodic.custom_data = nullptr, + .u.periodic.custom_data = mEffectCustomDataDual[effectIndex].data(), .u.periodic.custom_len = 0, }; } diff --git a/vibrator/cs40l26/Vibrator.h b/vibrator/cs40l26/Vibrator.h index 06bd6e5..8f89713 100644 --- a/vibrator/cs40l26/Vibrator.h +++ b/vibrator/cs40l26/Vibrator.h @@ -218,6 +218,8 @@ class Vibrator : public BnVibrator { std::vector mFfEffects; std::vector mFfEffectsDual; std::vector mEffectDurations; + std::vector> mEffectCustomData; + std::vector> mEffectCustomDataDual; std::future mAsyncHandle; ::android::base::unique_fd mInputFd; ::android::base::unique_fd mInputFdDual;