mirror of
https://github.com/oplus-giulia-dev/android_hardware_oplus
synced 2025-11-05 06:45:34 +08:00
aidl: vibrator: qti: load effects from blobs
Change-Id: I55350bea3b7c4f31a62b60a6792ba2a343c72970
This commit is contained in:
committed by
Bruno Martins
parent
b0fb5146b2
commit
12190ecbc4
@@ -3,9 +3,12 @@ cc_library_shared {
|
||||
vendor: true,
|
||||
srcs: [
|
||||
"effect.cpp",
|
||||
"VibrationEffectLoader.cpp"
|
||||
],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libcutils",
|
||||
"libjsoncpp",
|
||||
"libutils",
|
||||
],
|
||||
include_dirs: select(soong_config_variable("OPLUS_LINEAGE_VIBRATOR_HAL", "INCLUDE_DIR"), {
|
||||
|
||||
151
aidl/vibrator/qti/effect/VibrationEffectLoader.cpp
Normal file
151
aidl/vibrator/qti/effect/VibrationEffectLoader.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (C) 2025 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define LOG_TAG "VibrationEffectLoader"
|
||||
|
||||
#include "VibrationEffectLoader.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
/*
|
||||
* Example of valid vibrator_effect.json:
|
||||
*
|
||||
* {
|
||||
* "9999": {
|
||||
* "def_style": [
|
||||
* {
|
||||
* "effect_file": "/odm/etc/vibrator/9999/def/effect_0.bin",
|
||||
* "effect_id": 0,
|
||||
* "play_rate_hz": 24000
|
||||
* },
|
||||
* ...
|
||||
* ],
|
||||
* "soft_style": [
|
||||
* {
|
||||
* "effect_file": "/odm/etc/vibrator/9999/soft/effect_0.bin",
|
||||
* "effect_id": 0,
|
||||
* "play_rate_hz": 24000
|
||||
* },
|
||||
* ...
|
||||
* ]
|
||||
* },
|
||||
* ...
|
||||
* }
|
||||
*/
|
||||
|
||||
namespace {
|
||||
const auto kConfigPath = "/odm/etc/vibrator/vibrator_effect.json";
|
||||
|
||||
const auto kKeyDefStyle = "def_style";
|
||||
const auto kKeyEffectFile = "effect_file";
|
||||
const auto kKeyEffectId = "effect_id";
|
||||
const auto kKeyPlayRateHz = "play_rate_hz";
|
||||
|
||||
const int8_t* LoadEffectDataFromFile(const std::string& path, uint32_t& length) {
|
||||
std::ifstream file(path, std::ios::binary);
|
||||
if (!file.is_open()) {
|
||||
LOG(ERROR) << "Failed to open data file: " << path;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
file.seekg(0, std::ios::end);
|
||||
length = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
|
||||
int8_t* data = new int8_t[length];
|
||||
if (!file.read(reinterpret_cast<char*>(data), length)) {
|
||||
LOG(ERROR) << "Failed to read data file: " << path;
|
||||
delete[] data;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LOG(DEBUG) << "Successfully read data from " << path << ", length=" << length;
|
||||
|
||||
return data;
|
||||
}
|
||||
}; // anonymous namespace
|
||||
|
||||
VibrationEffectLoader::VibrationEffectLoader() {
|
||||
std::ifstream config_stream(kConfigPath);
|
||||
if (!config_stream) {
|
||||
LOG(INFO) << "Couldn't open " << kConfigPath
|
||||
<< " for parsing, falling back to built-in effects.";
|
||||
return;
|
||||
}
|
||||
auto node = parseEffectJson(config_stream);
|
||||
if (node.isNull()) {
|
||||
LOG(ERROR) << "Failed to parse " << kConfigPath << ", falling back to built-in effects.";
|
||||
return;
|
||||
}
|
||||
loadEffects(std::move(node));
|
||||
}
|
||||
|
||||
VibrationEffectLoader::~VibrationEffectLoader() {
|
||||
std::for_each(effect_map_.begin(), effect_map_.end(), [](auto&& v) { delete[] v.second.data; });
|
||||
}
|
||||
|
||||
effect_stream* VibrationEffectLoader::getEffectStream(uint32_t effect_id) {
|
||||
auto entry = effect_map_.find(effect_id);
|
||||
if (entry != effect_map_.end()) {
|
||||
return &entry->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Json::Value VibrationEffectLoader::parseEffectJson(std::ifstream& config_stream) {
|
||||
Json::Value root;
|
||||
Json::CharReaderBuilder builder;
|
||||
std::string errs;
|
||||
|
||||
if (!Json::parseFromStream(builder, config_stream, &root, &errs)) {
|
||||
LOG(ERROR) << "Failed to parse config JSON stream, error: " << errs;
|
||||
return Json::Value::null;
|
||||
}
|
||||
if (!root.isObject()) {
|
||||
LOG(ERROR) << "Root must be an object";
|
||||
return Json::Value::null;
|
||||
}
|
||||
|
||||
for (auto&& node : root) {
|
||||
if (node.isObject()) {
|
||||
// TODO: also load soft_style when dynamic switching is supported
|
||||
node = node[kKeyDefStyle];
|
||||
if (node.isArray() && !node.empty()) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG(ERROR) << "No effect node found in config";
|
||||
return Json::Value::null;
|
||||
}
|
||||
|
||||
void VibrationEffectLoader::loadEffects(Json::Value&& effect_nodes) {
|
||||
for (auto&& node : effect_nodes) {
|
||||
auto attr = node[kKeyEffectId];
|
||||
if (!attr.isUInt()) {
|
||||
LOG(ERROR) << "Invalid effect_id";
|
||||
continue;
|
||||
}
|
||||
uint32_t effect_id = attr.asUInt();
|
||||
|
||||
attr = node[kKeyPlayRateHz];
|
||||
if (!attr.isUInt()) {
|
||||
LOG(ERROR) << "Invalid play_rate_hz";
|
||||
continue;
|
||||
}
|
||||
uint32_t play_rate_hz = attr.asUInt();
|
||||
|
||||
uint32_t length;
|
||||
auto data = LoadEffectDataFromFile(node[kKeyEffectFile].asString(), length);
|
||||
if (!data) {
|
||||
continue;
|
||||
}
|
||||
|
||||
effect_map_.emplace(effect_id, effect_stream{effect_id, length, play_rate_hz, data});
|
||||
}
|
||||
}
|
||||
25
aidl/vibrator/qti/effect/VibrationEffectLoader.h
Normal file
25
aidl/vibrator/qti/effect/VibrationEffectLoader.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2025 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "effect.h"
|
||||
|
||||
#include <json/json.h>
|
||||
#include <unordered_map>
|
||||
|
||||
class VibrationEffectLoader {
|
||||
public:
|
||||
VibrationEffectLoader();
|
||||
~VibrationEffectLoader();
|
||||
effect_stream* getEffectStream(uint32_t effect_id);
|
||||
|
||||
private:
|
||||
Json::Value parseEffectJson(std::ifstream& config_stream);
|
||||
void loadEffects(Json::Value&& effect_nodes);
|
||||
|
||||
std::unordered_map<uint32_t, effect_stream> effect_map_;
|
||||
};
|
||||
@@ -33,14 +33,17 @@
|
||||
|
||||
#include <VibrationEffectConfig.h>
|
||||
|
||||
const struct effect_stream *get_effect_stream(uint32_t effect_id)
|
||||
{
|
||||
int i;
|
||||
#include "VibrationEffectLoader.h"
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(effects); i++) {
|
||||
if (effect_id == effects[i].effect_id)
|
||||
return &effects[i];
|
||||
}
|
||||
namespace {
|
||||
VibrationEffectLoader loader;
|
||||
}; // anonymous namespace
|
||||
|
||||
return NULL;
|
||||
const struct effect_stream* get_effect_stream(uint32_t effect_id) {
|
||||
auto ret = loader.getEffectStream(effect_id);
|
||||
if (ret) return ret;
|
||||
|
||||
auto it = std::find_if(std::begin(effects), std::end(effects),
|
||||
[&](auto&& v) { return v.effect_id == effect_id; });
|
||||
return it != std::end(effects) ? &*it : nullptr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user