Merge cherrypicks of ['googleplex-android-review.googlesource.com/26642020'] into 24Q2-release.
Change-Id: I221080236fa33a7200587cf74f130d2711dc45a5
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 @@
.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 @@
}
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 @@
(*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 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 @@
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<uint32_t>(mEffectCustomData[effectIndex].size()),
};
// Bypass the waveform update due to different input name
if ((strstr(inputEventName, "cs40l26") != nullptr) ||
@@ -518,12 +521,16 @@
}
} else {
/* Initiate placeholders for OWT effects. */
+ numBytes = effectIndex == WAVEFORM_COMPOSE ? FF_CUSTOM_DATA_LEN_MAX_COMP
+ : FF_CUSTOM_DATA_LEN_MAX_PWLE;
+ std::vector<int16_t> 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 @@
// ====================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<uint32_t>(mEffectCustomDataDual[effectIndex].size()),
};
// Bypass the waveform update due to different input name
if ((strstr(inputEventName, "cs40l26") != nullptr) ||
@@ -563,12 +573,16 @@
}
} else {
/* Initiate placeholders for OWT effects. */
+ numBytes = effectIndex == WAVEFORM_COMPOSE ? FF_CUSTOM_DATA_LEN_MAX_COMP
+ : FF_CUSTOM_DATA_LEN_MAX_PWLE;
+ std::vector<int16_t> 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 @@
std::vector<ff_effect> mFfEffects;
std::vector<ff_effect> mFfEffectsDual;
std::vector<uint32_t> mEffectDurations;
+ std::vector<std::vector<int16_t>> mEffectCustomData;
+ std::vector<std::vector<int16_t>> mEffectCustomDataDual;
std::future<void> mAsyncHandle;
::android::base::unique_fd mInputFd;
::android::base::unique_fd mInputFdDual;