Merge changes from topic "AK3_porting"
* changes: vibrator: cs40l26: Sync the HAL patches delta from main to device folder vibrator: enable f0 and disable redc compensation
This commit is contained in:
commit
2c9072d3d2
11 changed files with 185 additions and 252 deletions
|
@ -206,3 +206,9 @@ PRODUCT_VENDOR_PROPERTIES += \
|
|||
# Disable camera DPM
|
||||
PRODUCT_PROPERTY_OVERRIDES += \
|
||||
vendor.camera.debug.force_dpm_on=0
|
||||
|
||||
# Vibrator HAL
|
||||
PRODUCT_VENDOR_PROPERTIES += \
|
||||
ro.vendor.vibrator.hal.supported_primitives=243 \
|
||||
ro.vendor.vibrator.hal.f0.comp.enabled=1 \
|
||||
ro.vendor.vibrator.hal.redc.comp.enabled=0 \
|
||||
|
|
|
@ -76,16 +76,3 @@ cc_binary {
|
|||
shared_libs: ["android.hardware.vibrator-impl.cs40l26-akita"],
|
||||
proprietary: true,
|
||||
}
|
||||
|
||||
cc_binary {
|
||||
name: "android.hardware.vibrator-service.cs40l26-dual-akita",
|
||||
defaults: ["VibratorHalCs40l26BinaryDefaultsAkita"],
|
||||
init_rc: ["android.hardware.vibrator-service.cs40l26-dual-akita.rc"],
|
||||
vintf_fragments: ["android.hardware.vibrator-service.cs40l26-dual-akita.xml"],
|
||||
srcs: ["service.cpp"],
|
||||
shared_libs: ["android.hardware.vibrator-impl.cs40l26-akita"],
|
||||
cflags: ["-DVIBRATOR_NAME=\"dual\""],
|
||||
proprietary: true,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
|
|||
bool setMinOnOffInterval(uint32_t value) override { return set(value, &mMinOnOffInterval); }
|
||||
// TODO(b/234338136): Need to add the force feedback HW API test cases
|
||||
bool setFFGain(int fd, uint16_t value) override {
|
||||
ATRACE_NAME(StringPrintf("%s %d%%", __func__, value).c_str());
|
||||
struct input_event gain = {
|
||||
.type = EV_FF,
|
||||
.code = FF_GAIN,
|
||||
|
@ -105,6 +106,7 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
|
|||
return true;
|
||||
}
|
||||
bool setFFEffect(int fd, struct ff_effect *effect, uint16_t timeoutMs) override {
|
||||
ATRACE_NAME(StringPrintf("%s %dms", __func__, timeoutMs).c_str());
|
||||
if (((*effect).replay.length != timeoutMs) || (ioctl(fd, EVIOCSFF, effect) < 0)) {
|
||||
ALOGE("setFFEffect fail");
|
||||
return false;
|
||||
|
@ -113,6 +115,7 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
|
|||
}
|
||||
}
|
||||
bool setFFPlay(int fd, int8_t index, bool value) override {
|
||||
ATRACE_NAME(StringPrintf("%s index:%d %s", __func__, index, value ? "on" : "off").c_str());
|
||||
struct input_event play = {
|
||||
.type = EV_FF,
|
||||
.code = static_cast<uint16_t>(index),
|
||||
|
@ -125,6 +128,7 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
|
|||
}
|
||||
}
|
||||
bool getHapticAlsaDevice(int *card, int *device) override {
|
||||
ATRACE_NAME(__func__);
|
||||
std::string line;
|
||||
std::ifstream myfile(PROC_SND_PCM);
|
||||
if (myfile.is_open()) {
|
||||
|
@ -144,6 +148,7 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
|
|||
return false;
|
||||
}
|
||||
bool setHapticPcmAmp(struct pcm **haptic_pcm, bool enable, int card, int device) override {
|
||||
ATRACE_NAME(StringPrintf("%s %s", __func__, enable ? "enable" : "disable").c_str());
|
||||
int ret = 0;
|
||||
|
||||
if (enable) {
|
||||
|
@ -181,6 +186,7 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
|
|||
}
|
||||
bool uploadOwtEffect(int fd, uint8_t *owtData, uint32_t numBytes, struct ff_effect *effect,
|
||||
uint32_t *outEffectIndex, int *status) override {
|
||||
ATRACE_NAME(__func__);
|
||||
(*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};
|
||||
|
@ -214,13 +220,17 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
|
|||
return true;
|
||||
}
|
||||
bool eraseOwtEffect(int fd, int8_t effectIndex, std::vector<ff_effect> *effect) override {
|
||||
ATRACE_NAME(__func__);
|
||||
uint32_t effectCountBefore, effectCountAfter, i, successFlush = 0;
|
||||
|
||||
if (effectIndex < WAVEFORM_MAX_PHYSICAL_INDEX) {
|
||||
ALOGE("Invalid waveform index for OWT erase: %d", effectIndex);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Turn off the waiting time for SVC init phase to complete since chip
|
||||
// should already under STOP state
|
||||
setMinOnOffInterval(0);
|
||||
// Do erase flow
|
||||
if (effectIndex < WAVEFORM_MAX_INDEX) {
|
||||
/* Normal situation. Only erase the effect which we just played. */
|
||||
if (ioctl(fd, EVIOCRMFF, effectIndex) < 0) {
|
||||
|
@ -248,6 +258,8 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
|
|||
(*effect)[i].id = -1;
|
||||
}
|
||||
}
|
||||
// Turn on the waiting time for SVC init phase to complete
|
||||
setMinOnOffInterval(Vibrator::MIN_ON_OFF_INTERVAL_US);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -335,6 +347,16 @@ class HwCal : public Vibrator::HwCal, private HwCalBase {
|
|||
bool getSupportedPrimitives(uint32_t *value) override {
|
||||
return getProperty("supported_primitives", value, (uint32_t)0);
|
||||
}
|
||||
bool isF0CompEnabled() override {
|
||||
bool value;
|
||||
getProperty("f0.comp.enabled", &value, true);
|
||||
return value;
|
||||
}
|
||||
bool isRedcCompEnabled() override {
|
||||
bool value;
|
||||
getProperty("redc.comp.enabled", &value, true);
|
||||
return value;
|
||||
}
|
||||
void debug(int fd) override { HwCalBase::debug(fd); }
|
||||
};
|
||||
|
||||
|
|
|
@ -35,10 +35,22 @@
|
|||
#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
#ifdef LOG_TAG
|
||||
#undef LOG_TAG
|
||||
#define LOG_TAG "Vibrator"
|
||||
#endif
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace vibrator {
|
||||
|
||||
#ifdef HAPTIC_TRACE
|
||||
#define HAPTICS_TRACE(...) ALOGD(__VA_ARGS__)
|
||||
#else
|
||||
#define HAPTICS_TRACE(...)
|
||||
#endif
|
||||
|
||||
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;
|
||||
|
@ -50,7 +62,6 @@ static constexpr uint32_t WAVEFORM_LONG_VIBRATION_THRESHOLD_MS = 50;
|
|||
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 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 uint32_t MAX_TIME_MS = UINT16_MAX;
|
||||
|
||||
|
@ -111,11 +122,6 @@ static uint16_t amplitudeToScale(float amplitude, float maximum) {
|
|||
return std::round(ratio);
|
||||
}
|
||||
|
||||
enum class AlwaysOnId : uint32_t {
|
||||
GPIO_RISE,
|
||||
GPIO_FALL,
|
||||
};
|
||||
|
||||
enum WaveformBankID : uint8_t {
|
||||
RAM_WVFRM_BANK,
|
||||
ROM_WVFRM_BANK,
|
||||
|
@ -144,8 +150,8 @@ enum WaveformIndex : uint16_t {
|
|||
WAVEFORM_PWLE,
|
||||
/*
|
||||
* Refer to <linux/input.h>, the WAVEFORM_MAX_INDEX must not exceed 96.
|
||||
* #define FF_GAIN 0x60 // 96 in decimal
|
||||
* #define FF_MAX_EFFECTS FF_GAIN
|
||||
* #define FF_GAIN 0x60 // 96 in decimal
|
||||
* #define FF_MAX_EFFECTS FF_GAIN
|
||||
*/
|
||||
WAVEFORM_MAX_INDEX,
|
||||
};
|
||||
|
@ -159,6 +165,8 @@ enum vibe_state {
|
|||
VIBE_STATE_ASP,
|
||||
};
|
||||
|
||||
std::mutex mActiveId_mutex; // protects mActiveId
|
||||
|
||||
static int min(int x, int y) {
|
||||
return x < y ? x : y;
|
||||
}
|
||||
|
@ -182,6 +190,7 @@ struct dspmem_chunk {
|
|||
};
|
||||
|
||||
static dspmem_chunk *dspmem_chunk_create(void *data, int size) {
|
||||
HAPTICS_TRACE(" dspmem_chunk_create(data, size:%d)", size);
|
||||
auto ch = new dspmem_chunk{
|
||||
.head = reinterpret_cast<uint8_t *>(data),
|
||||
.current = reinterpret_cast<uint8_t *>(data),
|
||||
|
@ -192,14 +201,17 @@ static dspmem_chunk *dspmem_chunk_create(void *data, int size) {
|
|||
}
|
||||
|
||||
static bool dspmem_chunk_end(struct dspmem_chunk *ch) {
|
||||
HAPTICS_TRACE(" dspmem_chunk_end(ch)");
|
||||
return ch->current == ch->max;
|
||||
}
|
||||
|
||||
static int dspmem_chunk_bytes(struct dspmem_chunk *ch) {
|
||||
HAPTICS_TRACE(" dspmem_chunk_bytes(ch)");
|
||||
return ch->bytes;
|
||||
}
|
||||
|
||||
static int dspmem_chunk_write(struct dspmem_chunk *ch, int nbits, uint32_t val) {
|
||||
HAPTICS_TRACE(" dspmem_chunk_write(ch, nbits:%d, val:%u)", nbits, val);
|
||||
int nwrite, i;
|
||||
|
||||
nwrite = min(24 - ch->cachebits, nbits);
|
||||
|
@ -227,6 +239,7 @@ static int dspmem_chunk_write(struct dspmem_chunk *ch, int nbits, uint32_t val)
|
|||
}
|
||||
|
||||
static int dspmem_chunk_flush(struct dspmem_chunk *ch) {
|
||||
HAPTICS_TRACE(" dspmem_chunk_flush(ch)");
|
||||
if (!ch->cachebits)
|
||||
return 0;
|
||||
|
||||
|
@ -306,7 +319,7 @@ Vibrator::Vibrator(std::unique_ptr<HwApi> hwapi, std::unique_ptr<HwCal> hwcal)
|
|||
mFfEffects.resize(WAVEFORM_MAX_INDEX);
|
||||
mEffectDurations.resize(WAVEFORM_MAX_INDEX);
|
||||
mEffectDurations = {
|
||||
1000, 100, 30, 1000, 300, 130, 150, 500, 100, 15, 20, 1000, 1000, 1000,
|
||||
1000, 100, 12, 1000, 300, 130, 150, 500, 100, 5, 12, 1000, 1000, 1000,
|
||||
}; /* 11+3 waveforms. The duration must < UINT16_MAX */
|
||||
|
||||
uint8_t effectIndex;
|
||||
|
@ -380,9 +393,10 @@ Vibrator::Vibrator(std::unique_ptr<HwApi> hwapi, std::unique_ptr<HwCal> hwcal)
|
|||
} else {
|
||||
ALOGD("Unsupported calibration version: %u!", calVer);
|
||||
}
|
||||
HAPTICS_TRACE("Vibrator(hwapi, hwcal:%u)", calVer);
|
||||
|
||||
mHwApi->setF0CompEnable(true);
|
||||
mHwApi->setRedcCompEnable(true);
|
||||
mHwApi->setF0CompEnable(mHwCal->isF0CompEnabled());
|
||||
mHwApi->setRedcCompEnable(mHwCal->isRedcCompEnabled());
|
||||
|
||||
mIsUnderExternalControl = false;
|
||||
|
||||
|
@ -409,11 +423,12 @@ Vibrator::Vibrator(std::unique_ptr<HwApi> hwapi, std::unique_ptr<HwCal> hwcal)
|
|||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getCapabilities(int32_t *_aidl_return) {
|
||||
HAPTICS_TRACE("getCapabilities(_aidl_return)");
|
||||
ATRACE_NAME("Vibrator::getCapabilities");
|
||||
|
||||
int32_t ret = IVibrator::CAP_ON_CALLBACK | IVibrator::CAP_PERFORM_CALLBACK |
|
||||
IVibrator::CAP_AMPLITUDE_CONTROL | IVibrator::CAP_ALWAYS_ON_CONTROL |
|
||||
IVibrator::CAP_GET_RESONANT_FREQUENCY | IVibrator::CAP_GET_Q_FACTOR;
|
||||
IVibrator::CAP_AMPLITUDE_CONTROL | IVibrator::CAP_GET_RESONANT_FREQUENCY |
|
||||
IVibrator::CAP_GET_Q_FACTOR;
|
||||
if (hasHapticAlsaDevice()) {
|
||||
ret |= IVibrator::CAP_EXTERNAL_CONTROL;
|
||||
} else {
|
||||
|
@ -430,34 +445,44 @@ ndk::ScopedAStatus Vibrator::getCapabilities(int32_t *_aidl_return) {
|
|||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::off() {
|
||||
HAPTICS_TRACE("off()");
|
||||
ATRACE_NAME("Vibrator::off");
|
||||
if (mActiveId < 0) {
|
||||
ALOGD("Vibrator is already off");
|
||||
return ndk::ScopedAStatus::ok();
|
||||
bool ret{true};
|
||||
const std::scoped_lock<std::mutex> lock(mActiveId_mutex);
|
||||
|
||||
if (mActiveId >= 0) {
|
||||
/* Stop the active effect. */
|
||||
if (!mHwApi->setFFPlay(mInputFd, mActiveId, false)) {
|
||||
ALOGE("Failed to stop effect %d (%d): %s", mActiveId, errno, strerror(errno));
|
||||
ret = false;
|
||||
}
|
||||
|
||||
if ((mActiveId >= WAVEFORM_MAX_PHYSICAL_INDEX) &&
|
||||
(!mHwApi->eraseOwtEffect(mInputFd, mActiveId, &mFfEffects))) {
|
||||
ALOGE("Failed to clean up the composed effect %d", mActiveId);
|
||||
ret = false;
|
||||
}
|
||||
} else {
|
||||
ALOGV("Vibrator is already off");
|
||||
}
|
||||
|
||||
/* Stop the active effect. */
|
||||
if (!mHwApi->setFFPlay(mInputFd, mActiveId, false)) {
|
||||
ALOGE("Failed to stop effect %d (%d): %s", mActiveId, errno, strerror(errno));
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
|
||||
}
|
||||
|
||||
if ((mActiveId >= WAVEFORM_MAX_PHYSICAL_INDEX) &&
|
||||
(!mHwApi->eraseOwtEffect(mInputFd, mActiveId, &mFfEffects))) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
|
||||
}
|
||||
mActiveId = -1;
|
||||
setGlobalAmplitude(false);
|
||||
if (mF0Offset) {
|
||||
mHwApi->setF0Offset(0);
|
||||
}
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
if (ret) {
|
||||
return ndk::ScopedAStatus::ok();
|
||||
} else {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
|
||||
}
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::on(int32_t timeoutMs,
|
||||
const std::shared_ptr<IVibratorCallback> &callback) {
|
||||
ATRACE_NAME("Vibrator::on");
|
||||
ATRACE_NAME(StringPrintf("Vibrator::on %dms", timeoutMs).c_str());
|
||||
HAPTICS_TRACE("on(timeoutMs:%u, callback)", timeoutMs);
|
||||
if (timeoutMs > MAX_TIME_MS) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
|
||||
}
|
||||
|
@ -477,17 +502,23 @@ ndk::ScopedAStatus Vibrator::on(int32_t timeoutMs,
|
|||
ndk::ScopedAStatus Vibrator::perform(Effect effect, EffectStrength strength,
|
||||
const std::shared_ptr<IVibratorCallback> &callback,
|
||||
int32_t *_aidl_return) {
|
||||
ATRACE_NAME("Vibrator::perform");
|
||||
ATRACE_NAME(StringPrintf("Vibrator::perform %s,%s", toString(effect).c_str(),
|
||||
toString(strength).c_str())
|
||||
.c_str());
|
||||
HAPTICS_TRACE("perform(effect:%s, strength:%s, callback, _aidl_return)",
|
||||
toString(effect).c_str(), toString(strength).c_str());
|
||||
return performEffect(effect, strength, callback, _aidl_return);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getSupportedEffects(std::vector<Effect> *_aidl_return) {
|
||||
HAPTICS_TRACE("getSupportedEffects(_aidl_return)");
|
||||
*_aidl_return = {Effect::TEXTURE_TICK, Effect::TICK, Effect::CLICK, Effect::HEAVY_CLICK,
|
||||
Effect::DOUBLE_CLICK};
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::setAmplitude(float amplitude) {
|
||||
HAPTICS_TRACE("setAmplitude(amplitude:%f)", amplitude);
|
||||
ATRACE_NAME("Vibrator::setAmplitude");
|
||||
if (amplitude <= 0.0f || amplitude > 1.0f) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
|
||||
|
@ -502,6 +533,7 @@ ndk::ScopedAStatus Vibrator::setAmplitude(float amplitude) {
|
|||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::setExternalControl(bool enabled) {
|
||||
HAPTICS_TRACE("setExternalControl(enabled:%u)", enabled);
|
||||
ATRACE_NAME("Vibrator::setExternalControl");
|
||||
setGlobalAmplitude(enabled);
|
||||
|
||||
|
@ -520,24 +552,28 @@ ndk::ScopedAStatus Vibrator::setExternalControl(bool enabled) {
|
|||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getCompositionDelayMax(int32_t *maxDelayMs) {
|
||||
HAPTICS_TRACE("getCompositionDelayMax(maxDelayMs)");
|
||||
ATRACE_NAME("Vibrator::getCompositionDelayMax");
|
||||
*maxDelayMs = COMPOSE_DELAY_MAX_MS;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getCompositionSizeMax(int32_t *maxSize) {
|
||||
HAPTICS_TRACE("getCompositionSizeMax(maxSize)");
|
||||
ATRACE_NAME("Vibrator::getCompositionSizeMax");
|
||||
*maxSize = COMPOSE_SIZE_MAX;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getSupportedPrimitives(std::vector<CompositePrimitive> *supported) {
|
||||
HAPTICS_TRACE("getSupportedPrimitives(supported)");
|
||||
*supported = mSupportedPrimitives;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getPrimitiveDuration(CompositePrimitive primitive,
|
||||
int32_t *durationMs) {
|
||||
HAPTICS_TRACE("getPrimitiveDuration(primitive:%s, durationMs)", toString(primitive).c_str());
|
||||
ndk::ScopedAStatus status;
|
||||
uint32_t effectIndex;
|
||||
if (primitive != CompositePrimitive::NOOP) {
|
||||
|
@ -555,7 +591,8 @@ 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");
|
||||
ATRACE_NAME(StringPrintf("Vibrator::compose size=%zu", composite.size()).c_str());
|
||||
HAPTICS_TRACE("compose(composite, callback)");
|
||||
uint16_t size;
|
||||
uint16_t nextEffectDelay;
|
||||
|
||||
|
@ -637,17 +674,16 @@ ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect> &composi
|
|||
|
||||
ndk::ScopedAStatus Vibrator::on(uint32_t timeoutMs, uint32_t effectIndex, dspmem_chunk *ch,
|
||||
const std::shared_ptr<IVibratorCallback> &callback) {
|
||||
HAPTICS_TRACE("on(timeoutMs:%u, effectIndex:%u, ch, callback)", timeoutMs, effectIndex);
|
||||
ndk::ScopedAStatus status = ndk::ScopedAStatus::ok();
|
||||
|
||||
if (effectIndex >= FF_MAX_EFFECTS) {
|
||||
ALOGE("Invalid waveform index %d", effectIndex);
|
||||
status = ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
|
||||
goto end;
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
|
||||
}
|
||||
if (mAsyncHandle.wait_for(ASYNC_COMPLETION_TIMEOUT) != std::future_status::ready) {
|
||||
ALOGE("Previous vibration pending: prev: %d, curr: %d", mActiveId, effectIndex);
|
||||
status = ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
|
||||
goto end;
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
|
||||
}
|
||||
|
||||
if (ch) {
|
||||
|
@ -684,26 +720,24 @@ ndk::ScopedAStatus Vibrator::on(uint32_t timeoutMs, uint32_t effectIndex, dspmem
|
|||
if (!mHwApi->setFFEffect(mInputFd, &mFfEffects[effectIndex],
|
||||
static_cast<uint16_t>(timeoutMs))) {
|
||||
ALOGE("Failed to edit effect %d (%d): %s", effectIndex, errno, strerror(errno));
|
||||
status = ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
|
||||
goto end;
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
|
||||
}
|
||||
}
|
||||
|
||||
const std::scoped_lock<std::mutex> lock(mActiveId_mutex);
|
||||
mActiveId = effectIndex;
|
||||
/* Play the event now. */
|
||||
if (!mHwApi->setFFPlay(mInputFd, effectIndex, true)) {
|
||||
ALOGE("Failed to play effect %d (%d): %s", effectIndex, errno, strerror(errno));
|
||||
status = ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
|
||||
goto end;
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
|
||||
}
|
||||
|
||||
mAsyncHandle = std::async(&Vibrator::waitForComplete, this, callback);
|
||||
|
||||
end:
|
||||
return status;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::setEffectAmplitude(float amplitude, float maximum) {
|
||||
HAPTICS_TRACE("setEffectAmplitude(amplitude:%f, maximum:%f)", amplitude, maximum);
|
||||
uint16_t scale = amplitudeToScale(amplitude, maximum);
|
||||
if (!mHwApi->setFFGain(mInputFd, scale)) {
|
||||
ALOGE("Failed to set the gain to %u (%d): %s", scale, errno, strerror(errno));
|
||||
|
@ -713,6 +747,7 @@ ndk::ScopedAStatus Vibrator::setEffectAmplitude(float amplitude, float maximum)
|
|||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::setGlobalAmplitude(bool set) {
|
||||
HAPTICS_TRACE("setGlobalAmplitude(set:%u)", set);
|
||||
uint8_t amplitude = set ? roundf(mLongEffectScale * mLongEffectVol[1]) : VOLTAGE_SCALE_MAX;
|
||||
if (!set) {
|
||||
mLongEffectScale = 1.0; // Reset the scale for the later new effect.
|
||||
|
@ -720,57 +755,27 @@ ndk::ScopedAStatus Vibrator::setGlobalAmplitude(bool set) {
|
|||
return setEffectAmplitude(amplitude, VOLTAGE_SCALE_MAX);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getSupportedAlwaysOnEffects(std::vector<Effect> *_aidl_return) {
|
||||
*_aidl_return = {Effect::TEXTURE_TICK, Effect::TICK, Effect::CLICK, Effect::HEAVY_CLICK};
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) {
|
||||
ndk::ScopedAStatus status;
|
||||
uint32_t effectIndex;
|
||||
uint32_t timeMs;
|
||||
uint32_t volLevel;
|
||||
uint16_t scale;
|
||||
status = getSimpleDetails(effect, strength, &effectIndex, &timeMs, &volLevel);
|
||||
if (!status.isOk()) {
|
||||
return status;
|
||||
}
|
||||
|
||||
scale = amplitudeToScale(volLevel, VOLTAGE_SCALE_MAX);
|
||||
|
||||
switch (static_cast<AlwaysOnId>(id)) {
|
||||
case AlwaysOnId::GPIO_RISE:
|
||||
// mHwApi->setGpioRiseIndex(effectIndex);
|
||||
// mHwApi->setGpioRiseScale(scale);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
case AlwaysOnId::GPIO_FALL:
|
||||
// mHwApi->setGpioFallIndex(effectIndex);
|
||||
// mHwApi->setGpioFallScale(scale);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getSupportedAlwaysOnEffects(std::vector<Effect> * /*_aidl_return*/) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
ndk::ScopedAStatus Vibrator::alwaysOnDisable(int32_t id) {
|
||||
switch (static_cast<AlwaysOnId>(id)) {
|
||||
case AlwaysOnId::GPIO_RISE:
|
||||
// mHwApi->setGpioRiseIndex(0);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
case AlwaysOnId::GPIO_FALL:
|
||||
// mHwApi->setGpioFallIndex(0);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::alwaysOnEnable(int32_t /*id*/, Effect /*effect*/,
|
||||
EffectStrength /*strength*/) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
ndk::ScopedAStatus Vibrator::alwaysOnDisable(int32_t /*id*/) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getResonantFrequency(float *resonantFreqHz) {
|
||||
HAPTICS_TRACE("getResonantFrequency(resonantFreqHz)");
|
||||
*resonantFreqHz = mResonantFrequency;
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getQFactor(float *qFactor) {
|
||||
HAPTICS_TRACE("getQFactor(qFactor)");
|
||||
std::string caldata{8, '0'};
|
||||
if (!mHwCal->getQ(&caldata)) {
|
||||
ALOGE("Failed to get q factor (%d): %s", errno, strerror(errno));
|
||||
|
@ -782,6 +787,7 @@ ndk::ScopedAStatus Vibrator::getQFactor(float *qFactor) {
|
|||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getFrequencyResolution(float *freqResolutionHz) {
|
||||
HAPTICS_TRACE("getFrequencyResolution(freqResolutionHz)");
|
||||
int32_t capabilities;
|
||||
Vibrator::getCapabilities(&capabilities);
|
||||
if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
|
||||
|
@ -793,6 +799,7 @@ ndk::ScopedAStatus Vibrator::getFrequencyResolution(float *freqResolutionHz) {
|
|||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getFrequencyMinimum(float *freqMinimumHz) {
|
||||
HAPTICS_TRACE("getFrequencyMinimum(freqMinimumHz)");
|
||||
int32_t capabilities;
|
||||
Vibrator::getCapabilities(&capabilities);
|
||||
if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
|
||||
|
@ -837,11 +844,8 @@ void Vibrator::createPwleMaxLevelLimitMap() {
|
|||
pwleMaxLevelLimitMapIdx =
|
||||
(itr0->first - PWLE_FREQUENCY_MIN_HZ) / PWLE_FREQUENCY_RESOLUTION_HZ;
|
||||
|
||||
// FixLater: avoid floating point loop counters
|
||||
// NOLINTBEGIN(clang-analyzer-security.FloatLoopCounter,cert-flp30-c)
|
||||
for (float xp = x0; xp < (x1 + PWLE_FREQUENCY_RESOLUTION_HZ);
|
||||
xp += PWLE_FREQUENCY_RESOLUTION_HZ) {
|
||||
// NOLINTEND(clang-analyzer-security.FloatLoopCounter,cert-flp30-c)
|
||||
float yp = y0 + ratioOfXY * (xp - x0);
|
||||
|
||||
pwleMaxLevelLimitMap[pwleMaxLevelLimitMapIdx++] = yp;
|
||||
|
@ -925,6 +929,7 @@ void Vibrator::createBandwidthAmplitudeMap() {
|
|||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getBandwidthAmplitudeMap(std::vector<float> *_aidl_return) {
|
||||
HAPTICS_TRACE("getBandwidthAmplitudeMap(_aidl_return)");
|
||||
int32_t capabilities;
|
||||
Vibrator::getCapabilities(&capabilities);
|
||||
if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
|
||||
|
@ -942,6 +947,7 @@ ndk::ScopedAStatus Vibrator::getBandwidthAmplitudeMap(std::vector<float> *_aidl_
|
|||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getPwlePrimitiveDurationMax(int32_t *durationMs) {
|
||||
HAPTICS_TRACE("getPwlePrimitiveDurationMax(durationMs)");
|
||||
int32_t capabilities;
|
||||
Vibrator::getCapabilities(&capabilities);
|
||||
if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
|
||||
|
@ -953,6 +959,7 @@ ndk::ScopedAStatus Vibrator::getPwlePrimitiveDurationMax(int32_t *durationMs) {
|
|||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getPwleCompositionSizeMax(int32_t *maxSize) {
|
||||
HAPTICS_TRACE("getPwleCompositionSizeMax(maxSize)");
|
||||
int32_t capabilities;
|
||||
Vibrator::getCapabilities(&capabilities);
|
||||
if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
|
||||
|
@ -964,6 +971,7 @@ ndk::ScopedAStatus Vibrator::getPwleCompositionSizeMax(int32_t *maxSize) {
|
|||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getSupportedBraking(std::vector<Braking> *supported) {
|
||||
HAPTICS_TRACE("getSupportedBraking(supported)");
|
||||
int32_t capabilities;
|
||||
Vibrator::getCapabilities(&capabilities);
|
||||
if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
|
||||
|
@ -978,6 +986,7 @@ ndk::ScopedAStatus Vibrator::getSupportedBraking(std::vector<Braking> *supported
|
|||
|
||||
static void resetPreviousEndAmplitudeEndFrequency(float *prevEndAmplitude,
|
||||
float *prevEndFrequency) {
|
||||
HAPTICS_TRACE(" resetPreviousEndAmplitudeEndFrequency(prevEndAmplitude, prevEndFrequency)");
|
||||
const float reset = -1.0;
|
||||
*prevEndAmplitude = reset;
|
||||
*prevEndFrequency = reset;
|
||||
|
@ -989,6 +998,10 @@ static void incrementIndex(int *index) {
|
|||
|
||||
static void constructPwleSegment(dspmem_chunk *ch, uint16_t delay, uint16_t amplitude,
|
||||
uint16_t frequency, uint8_t flags, uint32_t vbemfTarget = 0) {
|
||||
HAPTICS_TRACE(
|
||||
" constructPwleSegment(ch, delay:%u, amplitude:%u, frequency:%u, flags:%u"
|
||||
", vbemfTarget:%u)",
|
||||
delay, amplitude, frequency, flags, vbemfTarget);
|
||||
dspmem_chunk_write(ch, 16, delay);
|
||||
dspmem_chunk_write(ch, 12, amplitude);
|
||||
dspmem_chunk_write(ch, 12, frequency);
|
||||
|
@ -1001,6 +1014,8 @@ static void constructPwleSegment(dspmem_chunk *ch, uint16_t delay, uint16_t ampl
|
|||
|
||||
static int constructActiveSegment(dspmem_chunk *ch, int duration, float amplitude, float frequency,
|
||||
bool chirp) {
|
||||
HAPTICS_TRACE(" constructActiveSegment(ch, duration:%d, amplitude:%f, frequency:%f)",
|
||||
duration, amplitude, frequency);
|
||||
uint16_t delay = 0;
|
||||
uint16_t amp = 0;
|
||||
uint16_t freq = 0;
|
||||
|
@ -1020,6 +1035,8 @@ static int constructActiveSegment(dspmem_chunk *ch, int duration, float amplitud
|
|||
}
|
||||
|
||||
static int constructBrakingSegment(dspmem_chunk *ch, int duration, Braking brakingType) {
|
||||
HAPTICS_TRACE(" constructBrakingSegment(ch, duration:%d, brakingType:%s)", duration,
|
||||
toString(brakingType).c_str());
|
||||
uint16_t delay = 0;
|
||||
uint16_t freq = 0;
|
||||
uint8_t flags = 0x00;
|
||||
|
@ -1037,6 +1054,7 @@ static int constructBrakingSegment(dspmem_chunk *ch, int duration, Braking braki
|
|||
}
|
||||
|
||||
static void updateWLength(dspmem_chunk *ch, uint32_t totalDuration) {
|
||||
HAPTICS_TRACE(" updateWLength(ch, totalDuration:%u)", totalDuration);
|
||||
totalDuration *= 8; /* Unit: 0.125 ms (since wlength played @ 8kHz). */
|
||||
totalDuration |= WT_LEN_CALCD; /* Bit 23 is for WT_LEN_CALCD; Bit 22 is for WT_INDEFINITE. */
|
||||
*(ch->head + 0) = (totalDuration >> 24) & 0xFF;
|
||||
|
@ -1046,13 +1064,15 @@ static void updateWLength(dspmem_chunk *ch, uint32_t totalDuration) {
|
|||
}
|
||||
|
||||
static void updateNSection(dspmem_chunk *ch, int segmentIdx) {
|
||||
HAPTICS_TRACE(" updateNSection(ch, segmentIdx:%u)", segmentIdx);
|
||||
*(ch->head + 7) |= (0xF0 & segmentIdx) >> 4; /* Bit 4 to 7 */
|
||||
*(ch->head + 9) |= (0x0F & segmentIdx) << 4; /* Bit 3 to 0 */
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::composePwle(const std::vector<PrimitivePwle> &composite,
|
||||
const std::shared_ptr<IVibratorCallback> &callback) {
|
||||
ATRACE_NAME("Vibrator::composePwle");
|
||||
ATRACE_NAME(StringPrintf("Vibrator::composePwle size=%zu", composite.size()).c_str());
|
||||
HAPTICS_TRACE("composePwle(composite, callback)");
|
||||
int32_t capabilities;
|
||||
|
||||
Vibrator::getCapabilities(&capabilities);
|
||||
|
@ -1185,10 +1205,12 @@ ndk::ScopedAStatus Vibrator::composePwle(const std::vector<PrimitivePwle> &compo
|
|||
}
|
||||
|
||||
bool Vibrator::isUnderExternalControl() {
|
||||
HAPTICS_TRACE("isUnderExternalControl()");
|
||||
return mIsUnderExternalControl;
|
||||
}
|
||||
|
||||
binder_status_t Vibrator::dump(int fd, const char **args, uint32_t numArgs) {
|
||||
HAPTICS_TRACE("dump(fd:%d, args, numArgs:%u)", fd, numArgs);
|
||||
if (fd < 0) {
|
||||
ALOGE("Called debug() with invalid fd.");
|
||||
return STATUS_OK;
|
||||
|
@ -1248,6 +1270,7 @@ binder_status_t Vibrator::dump(int fd, const char **args, uint32_t numArgs) {
|
|||
}
|
||||
|
||||
bool Vibrator::hasHapticAlsaDevice() {
|
||||
HAPTICS_TRACE("hasHapticAlsaDevice()");
|
||||
// We need to call findHapticAlsaDevice once only. Calling in the
|
||||
// constructor is too early in the boot process and the pcm file contents
|
||||
// are empty. Hence we make the call here once only right before we need to.
|
||||
|
@ -1267,6 +1290,10 @@ bool Vibrator::hasHapticAlsaDevice() {
|
|||
ndk::ScopedAStatus Vibrator::getSimpleDetails(Effect effect, EffectStrength strength,
|
||||
uint32_t *outEffectIndex, uint32_t *outTimeMs,
|
||||
uint32_t *outVolLevel) {
|
||||
HAPTICS_TRACE(
|
||||
"getSimpleDetails(effect:%s, strength:%s, outEffectIndex, outTimeMs"
|
||||
", outVolLevel)",
|
||||
toString(effect).c_str(), toString(strength).c_str());
|
||||
uint32_t effectIndex;
|
||||
uint32_t timeMs;
|
||||
float intensity;
|
||||
|
@ -1317,6 +1344,8 @@ ndk::ScopedAStatus Vibrator::getSimpleDetails(Effect effect, EffectStrength stre
|
|||
|
||||
ndk::ScopedAStatus Vibrator::getCompoundDetails(Effect effect, EffectStrength strength,
|
||||
uint32_t *outTimeMs, dspmem_chunk *outCh) {
|
||||
HAPTICS_TRACE("getCompoundDetails(effect:%s, strength:%s, outTimeMs, outCh)",
|
||||
toString(effect).c_str(), toString(strength).c_str());
|
||||
ndk::ScopedAStatus status;
|
||||
uint32_t timeMs = 0;
|
||||
uint32_t thisEffectIndex;
|
||||
|
@ -1370,6 +1399,7 @@ ndk::ScopedAStatus Vibrator::getCompoundDetails(Effect effect, EffectStrength st
|
|||
|
||||
ndk::ScopedAStatus Vibrator::getPrimitiveDetails(CompositePrimitive primitive,
|
||||
uint32_t *outEffectIndex) {
|
||||
HAPTICS_TRACE("getPrimitiveDetails(primitive:%s, outEffectIndex)", toString(primitive).c_str());
|
||||
uint32_t effectIndex;
|
||||
uint32_t primitiveBit = 1 << int32_t(primitive);
|
||||
if ((primitiveBit & mSupportedPrimitivesBits) == 0x0) {
|
||||
|
@ -1415,6 +1445,8 @@ ndk::ScopedAStatus Vibrator::getPrimitiveDetails(CompositePrimitive primitive,
|
|||
ndk::ScopedAStatus Vibrator::performEffect(Effect effect, EffectStrength strength,
|
||||
const std::shared_ptr<IVibratorCallback> &callback,
|
||||
int32_t *outTimeMs) {
|
||||
HAPTICS_TRACE("performEffect(effect:%s, strength:%s, callback, outTimeMs)",
|
||||
toString(effect).c_str(), toString(strength).c_str());
|
||||
ndk::ScopedAStatus status;
|
||||
uint32_t effectIndex;
|
||||
uint32_t timeMs = 0;
|
||||
|
@ -1454,20 +1486,38 @@ exit:
|
|||
ndk::ScopedAStatus Vibrator::performEffect(uint32_t effectIndex, uint32_t volLevel,
|
||||
dspmem_chunk *ch,
|
||||
const std::shared_ptr<IVibratorCallback> &callback) {
|
||||
HAPTICS_TRACE("performEffect(effectIndex:%u, volLevel:%u, ch, callback)", effectIndex,
|
||||
volLevel);
|
||||
setEffectAmplitude(volLevel, VOLTAGE_SCALE_MAX);
|
||||
|
||||
return on(MAX_TIME_MS, effectIndex, ch, callback);
|
||||
}
|
||||
|
||||
void Vibrator::waitForComplete(std::shared_ptr<IVibratorCallback> &&callback) {
|
||||
HAPTICS_TRACE("waitForComplete(callback)");
|
||||
|
||||
if (!mHwApi->pollVibeState(VIBE_STATE_HAPTIC, POLLING_TIMEOUT)) {
|
||||
ALOGW("Failed to get state \"Haptic\"");
|
||||
}
|
||||
ATRACE_BEGIN("Vibrating");
|
||||
mHwApi->pollVibeState(VIBE_STATE_STOPPED);
|
||||
ATRACE_END();
|
||||
|
||||
if (mActiveId >= WAVEFORM_MAX_PHYSICAL_INDEX) {
|
||||
mHwApi->eraseOwtEffect(mInputFd, mActiveId, &mFfEffects);
|
||||
const std::scoped_lock<std::mutex> lock(mActiveId_mutex);
|
||||
uint32_t effectCount = WAVEFORM_MAX_PHYSICAL_INDEX;
|
||||
if ((mActiveId >= WAVEFORM_MAX_PHYSICAL_INDEX) &&
|
||||
(!mHwApi->eraseOwtEffect(mInputFd, mActiveId, &mFfEffects))) {
|
||||
ALOGE("Failed to clean up the composed effect %d", mActiveId);
|
||||
} else {
|
||||
ALOGD("waitForComplete: Vibrator is already off");
|
||||
}
|
||||
mHwApi->getEffectCount(&effectCount);
|
||||
// Do waveform number checking
|
||||
if ((effectCount > WAVEFORM_MAX_PHYSICAL_INDEX) &&
|
||||
(!mHwApi->eraseOwtEffect(mInputFd, WAVEFORM_MAX_INDEX, &mFfEffects))) {
|
||||
ALOGE("Failed to forcibly clean up all composed effect");
|
||||
}
|
||||
|
||||
mActiveId = -1;
|
||||
|
||||
if (callback) {
|
||||
|
@ -1479,6 +1529,8 @@ void Vibrator::waitForComplete(std::shared_ptr<IVibratorCallback> &&callback) {
|
|||
}
|
||||
|
||||
uint32_t Vibrator::intensityToVolLevel(float intensity, uint32_t effectIndex) {
|
||||
HAPTICS_TRACE("intensityToVolLevel(intensity:%f, effectIndex:%u)", intensity, effectIndex);
|
||||
|
||||
uint32_t volLevel;
|
||||
auto calc = [](float intst, std::array<uint32_t, 2> v) -> uint32_t {
|
||||
return std::lround(intst * (v[1] - v[0])) + v[0];
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <aidl/android/hardware/vibrator/BnVibrator.h>
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <android-base/unique_fd.h>
|
||||
#include <linux/input.h>
|
||||
#include <tinyalsa/asoundlib.h>
|
||||
|
@ -29,6 +30,8 @@ namespace android {
|
|||
namespace hardware {
|
||||
namespace vibrator {
|
||||
|
||||
using ::android::base::StringPrintf;
|
||||
|
||||
class Vibrator : public BnVibrator {
|
||||
public:
|
||||
// APIs for interfacing with the kernel driver.
|
||||
|
@ -114,6 +117,10 @@ class Vibrator : public BnVibrator {
|
|||
virtual bool isChirpEnabled() = 0;
|
||||
// Obtains the supported primitive effects.
|
||||
virtual bool getSupportedPrimitives(uint32_t *value) = 0;
|
||||
// Checks if the f0 compensation feature needs to be enabled.
|
||||
virtual bool isF0CompEnabled() = 0;
|
||||
// Checks if the redc compensation feature needs to be enabled.
|
||||
virtual bool isRedcCompEnabled() = 0;
|
||||
// Emit diagnostic information to the given file.
|
||||
virtual void debug(int fd) = 0;
|
||||
};
|
||||
|
@ -154,6 +161,9 @@ class Vibrator : public BnVibrator {
|
|||
|
||||
binder_status_t dump(int fd, const char **args, uint32_t numArgs) override;
|
||||
|
||||
// SVC initialization time
|
||||
static constexpr uint32_t MIN_ON_OFF_INTERVAL_US = 8500;
|
||||
|
||||
private:
|
||||
ndk::ScopedAStatus on(uint32_t timeoutMs, uint32_t effectIndex, struct dspmem_chunk *ch,
|
||||
const std::shared_ptr<IVibratorCallback> &callback);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
on property:vendor.all.modules.ready=1
|
||||
wait /sys/bus/i2c/devices/6-0043/calibration/redc_cal_time_ms
|
||||
wait /sys/bus/i2c/devices/5-0043/calibration/redc_cal_time_ms
|
||||
|
||||
mkdir /mnt/vendor/persist/haptics 0770 system system
|
||||
chmod 770 /mnt/vendor/persist/haptics
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
on property:vendor.all.modules.ready=1
|
||||
wait /sys/bus/i2c/devices/6-0042/calibration/redc_cal_time_ms
|
||||
|
||||
mkdir /mnt/vendor/persist/haptics 0770 system system
|
||||
chmod 770 /mnt/vendor/persist/haptics
|
||||
chmod 440 /mnt/vendor/persist/haptics/cs40l26_dual.cal
|
||||
chown system system /mnt/vendor/persist/haptics
|
||||
chown system system /mnt/vendor/persist/haptics/cs40l26_dual.cal
|
||||
|
||||
chown system system /sys/bus/i2c/devices/6-0042/calibration/f0_stored
|
||||
chown system system /sys/bus/i2c/devices/6-0042/calibration/q_stored
|
||||
chown system system /sys/bus/i2c/devices/6-0042/calibration/redc_stored
|
||||
chown system system /sys/bus/i2c/devices/6-0042/default/vibe_state
|
||||
chown system system /sys/bus/i2c/devices/6-0042/default/num_waves
|
||||
chown system system /sys/bus/i2c/devices/6-0042/default/f0_offset
|
||||
chown system system /sys/bus/i2c/devices/6-0042/default/owt_free_space
|
||||
chown system system /sys/bus/i2c/devices/6-0042/default/f0_comp_enable
|
||||
chown system system /sys/bus/i2c/devices/6-0042/default/redc_comp_enable
|
||||
chown system system /sys/bus/i2c/devices/6-0042/default/delay_before_stop_playback_us
|
||||
|
||||
chown system system /sys/bus/i2c/devices/5-0042/calibration/f0_stored
|
||||
chown system system /sys/bus/i2c/devices/5-0042/calibration/q_stored
|
||||
chown system system /sys/bus/i2c/devices/5-0042/calibration/redc_stored
|
||||
chown system system /sys/bus/i2c/devices/5-0042/default/vibe_state
|
||||
chown system system /sys/bus/i2c/devices/5-0042/default/num_waves
|
||||
chown system system /sys/bus/i2c/devices/5-0042/default/f0_offset
|
||||
chown system system /sys/bus/i2c/devices/5-0042/default/owt_free_space
|
||||
chown system system /sys/bus/i2c/devices/5-0042/default/f0_comp_enable
|
||||
chown system system /sys/bus/i2c/devices/5-0042/default/redc_comp_enable
|
||||
chown system system /sys/bus/i2c/devices/5-0042/default/delay_before_stop_playback_us
|
||||
|
||||
chown system system /sys/bus/i2c/devices/4-0042/calibration/f0_stored
|
||||
chown system system /sys/bus/i2c/devices/4-0042/calibration/q_stored
|
||||
chown system system /sys/bus/i2c/devices/4-0042/calibration/redc_stored
|
||||
chown system system /sys/bus/i2c/devices/4-0042/default/vibe_state
|
||||
chown system system /sys/bus/i2c/devices/4-0042/default/num_waves
|
||||
chown system system /sys/bus/i2c/devices/4-0042/default/f0_offset
|
||||
chown system system /sys/bus/i2c/devices/4-0042/default/owt_free_space
|
||||
chown system system /sys/bus/i2c/devices/4-0042/default/f0_comp_enable
|
||||
chown system system /sys/bus/i2c/devices/4-0042/default/redc_comp_enable
|
||||
chown system system /sys/bus/i2c/devices/4-0042/default/delay_before_stop_playback_us
|
||||
|
||||
enable vendor.vibrator.cs40l26-dual
|
||||
|
||||
service vendor.vibrator.cs40l26-dual /vendor/bin/hw/android.hardware.vibrator-service.cs40l26-dual-akita
|
||||
class hal
|
||||
user system
|
||||
group system input
|
||||
|
||||
setenv INPUT_EVENT_NAME cs40l26_dual_input
|
||||
setenv INPUT_EVENT_PATH /dev/input/event*
|
||||
setenv PROPERTY_PREFIX ro.vendor.vibrator.hal.
|
||||
setenv CALIBRATION_FILEPATH /mnt/vendor/persist/haptics/cs40l26_dual.cal
|
||||
|
||||
setenv HWAPI_PATH_PREFIX /sys/bus/i2c/devices/
|
||||
setenv HWAPI_DEBUG_NODES "
|
||||
6-0042/
|
||||
5-0042/
|
||||
4-0042/
|
||||
"
|
||||
setenv HWAPI_DEBUG_PATHS "
|
||||
calibration/f0_stored
|
||||
calibration/redc_stored
|
||||
calibration/q_stored
|
||||
default/vibe_state
|
||||
default/num_waves
|
||||
default/f0_offset
|
||||
default/owt_free_space
|
||||
default/f0_comp_enable
|
||||
default/redc_comp_enable
|
||||
default/delay_before_stop_playback_us
|
||||
"
|
||||
|
||||
disabled
|
|
@ -1,7 +0,0 @@
|
|||
<manifest version="1.0" type="device">
|
||||
<hal format="aidl">
|
||||
<name>android.hardware.vibrator</name>
|
||||
<version>2</version>
|
||||
<fqname>IVibrator/dual</fqname>
|
||||
</hal>
|
||||
</manifest>
|
|
@ -1,7 +0,0 @@
|
|||
PRODUCT_PACKAGES += \
|
||||
android.hardware.vibrator-service.cs40l26-akita \
|
||||
android.hardware.vibrator-service.cs40l26-dual-akita
|
||||
|
||||
BOARD_SEPOLICY_DIRS += \
|
||||
hardware/google/pixel-sepolicy/vibrator/common \
|
||||
device/google/akita-sepolicy/vibrator/cs40l26
|
|
@ -63,6 +63,8 @@ class MockCal : public ::aidl::android::hardware::vibrator::Vibrator::HwCal {
|
|||
MOCK_METHOD1(getSupportedPrimitives, bool(uint32_t *value));
|
||||
MOCK_METHOD1(getDeviceMass, bool(float *value));
|
||||
MOCK_METHOD1(getLocCoeff, bool(float *value));
|
||||
MOCK_METHOD0(isF0CompEnabled, bool());
|
||||
MOCK_METHOD0(isRedcCompEnabled, bool());
|
||||
MOCK_METHOD1(debug, void(int fd));
|
||||
|
||||
~MockCal() override { destructor(); };
|
||||
|
|
|
@ -298,6 +298,8 @@ class VibratorTest : public Test {
|
|||
EXPECT_CALL(*mMockCal, getLongVolLevels(_)).Times(times);
|
||||
EXPECT_CALL(*mMockCal, isChirpEnabled()).Times(times);
|
||||
EXPECT_CALL(*mMockCal, getLongFrequencyShift(_)).Times(times);
|
||||
EXPECT_CALL(*mMockCal, isF0CompEnabled()).Times(times);
|
||||
EXPECT_CALL(*mMockCal, isRedcCompEnabled()).Times(times);
|
||||
EXPECT_CALL(*mMockCal, debug(_)).Times(times);
|
||||
}
|
||||
|
||||
|
@ -350,7 +352,9 @@ TEST_F(VibratorTest, Constructor) {
|
|||
volGet = EXPECT_CALL(*mMockCal, getLongVolLevels(_)).WillOnce(DoDefault());
|
||||
}
|
||||
|
||||
EXPECT_CALL(*mMockCal, isF0CompEnabled()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*mMockApi, setF0CompEnable(true)).WillOnce(Return(true));
|
||||
EXPECT_CALL(*mMockCal, isRedcCompEnabled()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*mMockApi, setRedcCompEnable(true)).WillOnce(Return(true));
|
||||
|
||||
EXPECT_CALL(*mMockCal, isChirpEnabled()).WillOnce(Return(true));
|
||||
|
@ -379,6 +383,8 @@ TEST_F(VibratorTest, on) {
|
|||
}
|
||||
|
||||
TEST_F(VibratorTest, off) {
|
||||
Sequence s1;
|
||||
EXPECT_CALL(*mMockApi, setFFGain(_, ON_GLOBAL_SCALE)).InSequence(s1).WillOnce(DoDefault());
|
||||
EXPECT_TRUE(mVibrator->off().isOk());
|
||||
}
|
||||
|
||||
|
@ -547,26 +553,6 @@ TEST_P(EffectsTest, perform) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST_P(EffectsTest, alwaysOnEnable) {
|
||||
// No real function now in P22+
|
||||
auto param = GetParam();
|
||||
auto effect = std::get<0>(param);
|
||||
auto strength = std::get<1>(param);
|
||||
auto scale = EFFECT_SCALE.find(param);
|
||||
bool supported = (scale != EFFECT_SCALE.end());
|
||||
|
||||
if (supported) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus status = mVibrator->alwaysOnEnable(0, effect, strength);
|
||||
if (supported) {
|
||||
EXPECT_EQ(EX_NONE, status.getExceptionCode());
|
||||
} else {
|
||||
EXPECT_EQ(EX_UNSUPPORTED_OPERATION, status.getExceptionCode());
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<Effect> kEffects{ndk::enum_range<Effect>().begin(),
|
||||
ndk::enum_range<Effect>().end()};
|
||||
const std::vector<EffectStrength> kEffectStrengths{ndk::enum_range<EffectStrength>().begin(),
|
||||
|
@ -692,50 +678,6 @@ const std::vector<ComposeParam> kComposeParams = {
|
|||
INSTANTIATE_TEST_CASE_P(VibratorTests, ComposeTest,
|
||||
ValuesIn(kComposeParams.begin(), kComposeParams.end()),
|
||||
ComposeTest::PrintParam);
|
||||
|
||||
class AlwaysOnTest : public VibratorTest, public WithParamInterface<int32_t> {
|
||||
public:
|
||||
static auto PrintParam(const TestParamInfo<ParamType> &info) {
|
||||
return std::to_string(info.param);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(AlwaysOnTest, alwaysOnEnable) {
|
||||
auto param = GetParam();
|
||||
auto scale = EFFECT_SCALE.begin();
|
||||
|
||||
std::advance(scale, std::rand() % EFFECT_SCALE.size());
|
||||
|
||||
auto effect = std::get<0>(scale->first);
|
||||
auto strength = std::get<1>(scale->first);
|
||||
|
||||
switch (param) {
|
||||
case 0:
|
||||
case 1:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus status = mVibrator->alwaysOnEnable(param, effect, strength);
|
||||
EXPECT_EQ(EX_NONE, status.getExceptionCode());
|
||||
}
|
||||
|
||||
TEST_P(AlwaysOnTest, alwaysOnDisable) {
|
||||
auto param = GetParam();
|
||||
|
||||
switch (param) {
|
||||
case 0:
|
||||
case 1:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus status = mVibrator->alwaysOnDisable(param);
|
||||
EXPECT_EQ(EX_NONE, status.getExceptionCode());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(VibratorTests, AlwaysOnTest, Range(0, 1), AlwaysOnTest::PrintParam);
|
||||
|
||||
} // namespace vibrator
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue