diff --git a/vibrator/effect/Android.bp b/vibrator/effect/Android.bp index 674a7df..bfd7f11 100644 --- a/vibrator/effect/Android.bp +++ b/vibrator/effect/Android.bp @@ -9,8 +9,12 @@ cc_library_shared { "effect.cpp", ], shared_libs: [ + "libbase", "libcutils", "libutils", ], + static_libs: [ + "libc++fs", + ], export_include_dirs: ["."] } diff --git a/vibrator/effect/effect.cpp b/vibrator/effect/effect.cpp index cb5fcaf..a11ba39 100644 --- a/vibrator/effect/effect.cpp +++ b/vibrator/effect/effect.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (C) 2022-2023 The LineageOS Project * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -31,103 +32,69 @@ * SPDX-License-Identifier: BSD-3-Clause-Clear */ +#define LOG_TAG "libqtivibratoreffect.xiaomi" + +#include +#include +#include +#include +#include +#include + #include "effect.h" -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) +namespace { -/* ~170 HZ sine waveform */ -static const int8_t effect_0[] = { - 17, 34, 50, 65, 79, 92, 103, 112, 119, 124, - 127, 127, 126, 122, 116, 108, 98, 86, 73, 58, - 42, 26, 9, -8, -25, -41, -57, -72, -85, -97, - -108, -116, -122, -126, -127, -127, -125, -120, - -113, -104, -93, -80, -66, -51, -35, -18, -1, -}; +const uint32_t kDefaultPlayRateHz = 24000; +const uint16_t kPrimitiveMask = (1 << 15); -static const int8_t effect_1[] = { - -1, -18, -35, -51, -66, -80, -93, -104, -113, - -120, -125, -127, -127, -126, -122, -116, -108, - -97, -85, -72, -57, -41, -25, -8, 9, 26, 42, - 58, 73, 86, 98, 108, 116, 122, 126, 127, 127, - 124, 119, 112, 103, 92, 79, 65, 50, 34, 17, -}; +std::unordered_map sEffectStreams; +std::unordered_map> sEffectFifoData; -static const int8_t primitive_0[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; +std::unique_ptr readEffectStreamFromFile(uint32_t uniqueEffectId) { + std::filesystem::path filePath; -static const int8_t primitive_1[] = { - 17, 34, 50, 65, 79, 92, 103, 112, 119, 124, - 127, 127, 126, 122, 116, 108, 98, 86, 73, 58, - 42, 26, 9, -8, -25, -41, -57, -72, -85, -97, - -108, -116, -122, -126, -127, -127, -125, -120, - -113, -104, -93, -80, -66, -51, -35, -18, -1, -}; + uint32_t effectId = uniqueEffectId & ~kPrimitiveMask; -static const int8_t primitive_2[] = { - 17, 34, 50, 65, 79, 92, 103, 112, 119, 124, - 127, 127, 126, 122, 116, 108, 98, 86, 73, 58, - 42, 26, 9, -8, -25, -41, -57, -72, -85, -97, - -108, -116, -122, -126, -127, -127, -125, -120, - -113, -104, -93, -80, -66, -51, -35, -18, -1, -}; - -static const struct effect_stream effects[] = { - { - .effect_id = 0, - .data = effect_0, - .length = ARRAY_SIZE(effect_0), - .play_rate_hz = 8000, - }, - - { - .effect_id = 1, - .data = effect_1, - .length = ARRAY_SIZE(effect_1), - .play_rate_hz = 8000, - }, -}; - -static const struct effect_stream primitives[] = { - { - .effect_id = 0, - .data = primitive_0, - .length = ARRAY_SIZE(primitive_0), - .play_rate_hz = 8000, - }, - - { - .effect_id = 1, - .data = primitive_1, - .length = ARRAY_SIZE(primitive_1), - .play_rate_hz = 8000, - }, - - { - .effect_id = 2, - .data = primitive_2, - .length = ARRAY_SIZE(primitive_2), - .play_rate_hz = 8000, - }, -}; - -const struct effect_stream *get_effect_stream(uint32_t effect_id) -{ - int i; - - if ((effect_id & 0x8000) != 0) { - effect_id = effect_id & 0x7fff; - - for (i = 0; i < ARRAY_SIZE(primitives); i++) { - if (effect_id == primitives[i].effect_id) - return &primitives[i]; - } + if ((uniqueEffectId & kPrimitiveMask) != 0) { + filePath = "/vendor/etc/vibrator/primitive_effect_" + std::to_string(effectId) + ".bin"; } else { - for (i = 0; i < ARRAY_SIZE(effects); i++) { - if (effect_id == effects[i].effect_id) - return &effects[i]; - } + filePath = "/vendor/etc/vibrator/effect_" + std::to_string(effectId) + ".bin"; } - return NULL; + LOG(VERBOSE) << "Reading fifo data for effect " << effectId << " from " << filePath; + + std::ifstream data(filePath, std::ios::in | std::ios::binary); + if (!data.is_open()) { + LOG(ERROR) << "Failed to open " << filePath << " for effect " << effectId; + return nullptr; + } + + std::uint32_t fileSize = std::filesystem::file_size(filePath); + + std::vector fifoData(fileSize); + data.read(reinterpret_cast(fifoData.data()), fileSize); + + auto result = sEffectFifoData.emplace(uniqueEffectId, std::move(fifoData)); + + return std::make_unique(effectId, fileSize, kDefaultPlayRateHz, + result.first->second.data()); +} + +} // namespace + +const struct effect_stream* get_effect_stream(uint32_t effectId) { + auto it = sEffectStreams.find(effectId); + if (it == sEffectStreams.end()) { + std::unique_ptr newEffectStream = readEffectStreamFromFile(effectId); + + if (newEffectStream) { + auto result = sEffectStreams.emplace(effectId, *newEffectStream); + return &result.first->second; + } + } else { + return &it->second; + } + + return nullptr; } diff --git a/vibrator/effect/effect.h b/vibrator/effect/effect.h index a588e22..0f177c7 100644 --- a/vibrator/effect/effect.h +++ b/vibrator/effect/effect.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (C) 2022-2023 The LineageOS Project * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -32,12 +33,15 @@ #include struct effect_stream { - uint32_t effect_id; - uint32_t length; - uint32_t play_rate_hz; - const int8_t *data; + uint32_t effect_id; + uint32_t length; + uint32_t play_rate_hz; + const int8_t* data; + + effect_stream(uint32_t effect_id, uint32_t length, uint32_t play_rate_hz, const int8_t* data) + : effect_id(effect_id), length(length), play_rate_hz(play_rate_hz), data(data) {} }; -const struct effect_stream *get_effect_stream(uint32_t effect_id); +const struct effect_stream* get_effect_stream(uint32_t effect_id); #endif