vibrator: effect: Create double click effect from click if necessary

Unfortunately, xiaomi did not implement a proper double click effect
on many devices. If a device does not provide fifo data for this
effect, play the click effect twice with a pause in between instead.

Co-authored-by: Adithya R <gh0strider.2k18.reborn@gmail.com>
Change-Id: Iac1bc924d078b45684072ec64e992a38507e908b
This commit is contained in:
Arian 2024-05-21 12:35:55 +02:00 committed by Bruno Martins
parent a4fc6b4e5e
commit b144a0aea4
2 changed files with 27 additions and 0 deletions

View File

@ -9,6 +9,7 @@ cc_library_shared {
"effect.cpp",
],
shared_libs: [
"android.hardware.vibrator-V2-ndk",
"libbase",
"libcutils",
"libutils",

View File

@ -34,6 +34,7 @@
#define LOG_TAG "libqtivibratoreffect.xiaomi"
#include <aidl/android/hardware/vibrator/Effect.h>
#include <android-base/logging.h>
#include <filesystem>
#include <fstream>
@ -43,6 +44,8 @@
#include "effect.h"
using aidl::android::hardware::vibrator::Effect;
namespace {
const uint32_t kDefaultPlayRateHz = 24000;
@ -81,6 +84,21 @@ std::unique_ptr<effect_stream> readEffectStreamFromFile(uint32_t uniqueEffectId)
result.first->second.data());
}
std::unique_ptr<effect_stream> duplicateEffect(const effect_stream* effectStream,
uint32_t newEffectId) {
const std::uint32_t newEffectLength = effectStream->length * 4;
std::vector<int8_t> fifoData(newEffectLength);
std::copy(effectStream->data, effectStream->data + effectStream->length, fifoData.begin());
std::copy(effectStream->data, effectStream->data + effectStream->length,
fifoData.begin() + newEffectLength - effectStream->length);
auto result = sEffectFifoData.emplace(newEffectId, std::move(fifoData));
return std::make_unique<effect_stream>(newEffectId, newEffectLength, kDefaultPlayRateHz,
result.first->second.data());
}
} // namespace
const struct effect_stream* get_effect_stream(uint32_t effectId) {
@ -91,6 +109,14 @@ const struct effect_stream* get_effect_stream(uint32_t effectId) {
if (newEffectStream) {
auto result = sEffectStreams.emplace(effectId, *newEffectStream);
return &result.first->second;
} else if (effectId == (uint32_t)Effect::DOUBLE_CLICK) {
LOG(VERBOSE) << "Could not get double click effect, duplicating click effect";
newEffectStream = duplicateEffect(get_effect_stream((uint32_t)Effect::CLICK),
(uint32_t)Effect::DOUBLE_CLICK);
if (newEffectStream) {
auto result = sEffectStreams.emplace(effectId, *newEffectStream);
return &result.first->second;
}
}
} else {
return &it->second;