From c582b96fa72ac10fd3dd203a4af742f0b6d9ba76 Mon Sep 17 00:00:00 2001 From: tanxu2 Date: Fri, 6 Jun 2025 16:19:04 +0800 Subject: [PATCH 1/3] add vibrator package modulation method Signed-off-by: tanxu2 --- .../include/vibrator_service_client.h | 32 +- .../vibrator/src/vibrator_service_client.cpp | 324 ++++++++++++ frameworks/native/vibrator/vibrator_agent.cpp | 18 +- .../inner_api/vibrator/vibrator_agent.h | 14 + test/unittest/vibrator/native/BUILD.gn | 31 ++ .../resource/json_file/modulation_curve.json | 146 ++++++ .../json_file/package_before_modulation.json | 198 +++++++ .../vibrator/native/resource/ohos_test.xml | 6 + .../native/vibrator_agent_modulation_test.cpp | 492 ++++++++++++++++++ 9 files changed, 1258 insertions(+), 3 deletions(-) create mode 100644 test/unittest/vibrator/native/resource/json_file/modulation_curve.json create mode 100644 test/unittest/vibrator/native/resource/json_file/package_before_modulation.json create mode 100644 test/unittest/vibrator/native/vibrator_agent_modulation_test.cpp diff --git a/frameworks/native/vibrator/include/vibrator_service_client.h b/frameworks/native/vibrator/include/vibrator_service_client.h index e51d19e..1a90664 100644 --- a/frameworks/native/vibrator/include/vibrator_service_client.h +++ b/frameworks/native/vibrator/include/vibrator_service_client.h @@ -56,6 +56,13 @@ struct VibratorDecodeHandle { } }; +typedef struct VibratorCurveInterval { + int32_t beginTime; + int32_t endTime; + int32_t intensity; + int32_t frequency; +} VibratorCurveInterval; + class VibratorServiceClient : public Singleton { public: ~VibratorServiceClient() override; @@ -77,7 +84,7 @@ public: bool systemUsage, const VibratorParameter ¶meter); int32_t PlayPattern(const VibratorIdentifier &identifier, const VibratorPattern &pattern, int32_t usage, bool systemUsage, const VibratorParameter ¶meter); - int32_t FreeVibratorPackage(VibratorPackage &package); + static int32_t FreeVibratorPackage(VibratorPackage &package); int32_t PlayPrimitiveEffect(const VibratorIdentifier &identifier, const std::string &effect, const PrimitiveEffect &primitiveEffect); bool IsSupportVibratorCustom(const VibratorIdentifier &identifier); @@ -92,6 +99,8 @@ public: VibratorEffectParameter GetVibratorEffectParameter(const VibratorIdentifier &identifier); int32_t GetVibratorList(const VibratorIdentifier& identifier, std::vector& vibratorInfo); int32_t GetEffectInfo(const VibratorIdentifier& identifier, const std::string& effectType, EffectInfo& effectInfo); + static int32_t ModulatePackage(const VibratorEvent &modulationCurve, + const VibratorPackage &beforeModulationPackage, VibratorPackage &afterModulationPackage); private: int32_t InitServiceClient(); @@ -104,6 +113,27 @@ private: void ConvertVibratorPattern(const VibratorPattern &vibratorPattern, VibratePattern &vibratePattern); bool SkipEventAndConvertVibratorEvent(const VibratorEvent &vibratorEvent, VibratePattern &vibratePattern, int32_t patternStartTime, VibrateEvent &vibrateEvent); + static int32_t GetCurveListAfterModulation( + const std::set& intervalEdges, const std::vector& currentInterval, + const std::vector& modInterval, const int offset, VibratorCurvePoint*& curve, + int32_t& curveNum); + static int32_t CopyNonContinuousVibratorEvent(const VibratorEvent &event, VibratorEvent &eventCopy); + static void FreePartiallyAllocatedVibratorPatterns(VibratorPattern*& patterns, const int32_t partialIdx); + static int32_t ModulateVibratorPattern(const VibratorEvent &modulationCurve, + const VibratorPattern &beforeModulationPattern, VibratorPattern &afterModulationPattern); + static void FreePartiallyAllocatedVibratorEvents(VibratorEvent*& events, const int32_t partialIdx); + static int32_t ModulateVibratorEvent(const VibratorEvent &modulationCurve, const int patternStartTime, + const VibratorEvent &beforeModulationEvent, VibratorEvent &afterModulationEvent); + static int32_t ModulateContinuousVibratorEvent(const VibratorEvent &modulationCurve, const int patternStartTime, + const VibratorEvent &beforeModulationEvent, VibratorEvent &afterModulationEvent); + static bool BinarySearchInterval(const std::vector& interval, + const int32_t val, int32_t& idx); + static void ConvertVibratorEventsToCurveIntervals(const VibratorEvent &vibratorEvent, const int patternTimeOffset, + std::vector& curveInterval); + static void ModulateSingleCurvePoint(const VibratorCurveInterval &modulationInterval, + const VibratorCurveInterval &originalInterval, VibratorCurvePoint& point); + static int32_t RestrictIntensityRange(int32_t intensity); + static int32_t RestrictFrequencyRange(int32_t frequency); void WriteVibratorHiSysIPCEvent(IMiscdeviceServiceIpcCode code, int32_t ret); void WriteOtherHiSysIPCEvent(IMiscdeviceServiceIpcCode code, int32_t ret); sptr serviceDeathObserver_ = nullptr; diff --git a/frameworks/native/vibrator/src/vibrator_service_client.cpp b/frameworks/native/vibrator/src/vibrator_service_client.cpp index b7fb971..ab326c4 100644 --- a/frameworks/native/vibrator/src/vibrator_service_client.cpp +++ b/frameworks/native/vibrator/src/vibrator_service_client.cpp @@ -14,7 +14,11 @@ */ #include "vibrator_service_client.h" +#include "securec.h" +#include +#include +#include #include #include @@ -37,6 +41,13 @@ namespace OHOS { namespace Sensors { static constexpr int32_t MIN_VIBRATOR_EVENT_TIME = 100; +static constexpr int32_t FREQUENCY_UPPER_BOUND = 100; +static constexpr int32_t FREQUENCY_LOWER_BOUND = -100; +static constexpr int32_t INTENSITY_UPPERBOUND = 100; +static constexpr int32_t INTENSITY_LOWERBOUND = 0; +constexpr int32_t CURVE_FREQUENCY_NO_MODIFICATION = 0; +constexpr int32_t CURVE_INTENSITY_NO_MODIFICATION = 100; +constexpr int32_t CURVE_TIME_NO_MODIFICATION = 0; using namespace OHOS::HiviewDFX; namespace { @@ -874,6 +885,319 @@ void VibratorServiceClient::ConvertVibratorPattern(const VibratorPattern &vibrat } } +int32_t VibratorServiceClient::ModulatePackage(const VibratorEvent &modulationCurve, + const VibratorPackage &beforeModulationPackage, VibratorPackage &afterModulationPackage) +{ + if (beforeModulationPackage.patternNum <= 0 || beforeModulationPackage.patterns == nullptr) { + MISC_HILOGE("ModulatePackage failed: patternNum is less than 0 or patterns is null"); + return ERROR; + } + if (modulationCurve.time < 0 || modulationCurve.duration < 0 || modulationCurve.pointNum <= 0 + || modulationCurve.points == nullptr) { + MISC_HILOGE("ModulatePackage failed: invalid modulationCurve"); + return ERROR; + } + afterModulationPackage = beforeModulationPackage; + afterModulationPackage.patterns = nullptr; + VibratorPattern *vibratePattern = nullptr; + vibratePattern = (VibratorPattern *)malloc(beforeModulationPackage.patternNum * sizeof(VibratorPattern)); + if (vibratePattern == nullptr) { + MISC_HILOGE("ModulatePackage failed: failure of memory allocation for VibratePattern"); + return ERROR; + } + for (int32_t i = 0; i < beforeModulationPackage.patternNum; i++) { + const VibratorPattern &beforeModPattern = beforeModulationPackage.patterns[i]; + VibratorPattern &afterModPattern = vibratePattern[i]; + afterModPattern.events = nullptr; + if (VibratorServiceClient::ModulateVibratorPattern( + modulationCurve, beforeModPattern, afterModPattern) != ERR_OK) { + MISC_HILOGE("ModulatePackage failed: failure of ModulateVibratorPattern"); + VibratorServiceClient::FreePartiallyAllocatedVibratorPatterns(vibratePattern, i); + return ERROR; + } + } + afterModulationPackage.patterns = vibratePattern; + return ERR_OK; +} + +/** + * fields 'time' in VibratorPattern,VibratorEvent and VibratorCurvePoint is shown in following figure + * |--------------------------------|-------------------------|-------------------------|---------------- + * VibratorPattern.time when event happens when curve point 1 happens when curve point 2 happens + * |<-------VibratorEvent.time----->| + * |<--curvePoint 1's time-->| + * (VibratorCurvePoint.time) + */ +int32_t VibratorServiceClient::ModulateVibratorPattern(const VibratorEvent &modulationCurve, + const VibratorPattern &beforeModulationPattern, VibratorPattern &afterModulationPattern) +{ + if (beforeModulationPattern.eventNum <= 0 || beforeModulationPattern.events == nullptr) { + MISC_HILOGE("ModulatePackage failed due to invalid parameter"); + return ERROR; + } + VibratorEvent* eventsAfterMod = (VibratorEvent*)malloc(beforeModulationPattern.eventNum * sizeof(VibratorEvent)); + if (eventsAfterMod == nullptr) { + MISC_HILOGE("ModulatePackage failed due to failure of memory allocation for VibratorEvent"); + return ERROR; + } + for (int i = 0; i < beforeModulationPattern.eventNum; i++) { + eventsAfterMod[i].points = nullptr; + if (VibratorServiceClient::ModulateVibratorEvent(modulationCurve, beforeModulationPattern.time, + beforeModulationPattern.events[i], eventsAfterMod[i]) != ERR_OK) { + MISC_HILOGE("ModulatePackage failed due to failure of handling VibrateEvent"); + VibratorServiceClient::FreePartiallyAllocatedVibratorEvents(eventsAfterMod, i); + afterModulationPattern.events = nullptr; + return ERROR; + } + } + afterModulationPattern = beforeModulationPattern; + afterModulationPattern.events = eventsAfterMod; + return ERR_OK; +} + +void VibratorServiceClient::FreePartiallyAllocatedVibratorPatterns(VibratorPattern*& patterns, const int32_t partialIdx) +{ + if (patterns == nullptr) { + MISC_HILOGW("FreePartiallyAllocatedVibratorPatterns failed because patterns is null"); + return; + } + for (int32_t i = partialIdx; i >= 0 ; i--) { + VibratorServiceClient::FreePartiallyAllocatedVibratorEvents(patterns[i].events, patterns[i].eventNum - 1); + patterns[i].events = nullptr; + } + free(patterns); + patterns = nullptr; +} + +void VibratorServiceClient::FreePartiallyAllocatedVibratorEvents(VibratorEvent*& events, const int32_t partialIdx) +{ + if (events == nullptr) { + MISC_HILOGW("FreePartiallyAllocatedVibratorEvents failed because events is null"); + return; + } + for (int32_t i = partialIdx; i >= 0 ; i--) { + free(events[i].points); + events[i].points = nullptr; + } + free(events); + events = nullptr; +} + +int32_t VibratorServiceClient::ModulateVibratorEvent(const VibratorEvent &modulationCurve, const int patternStartTime, + const VibratorEvent &beforeModulationEvent, VibratorEvent &afterModulationEvent) +{ + if (beforeModulationEvent.type != EVENT_TYPE_CONTINUOUS) { + return VibratorServiceClient::CopyNonContinuousVibratorEvent(beforeModulationEvent, afterModulationEvent); + } + VibratorCurvePoint* curvePoints = nullptr; + if (beforeModulationEvent.pointNum <= 0 || beforeModulationEvent.points == nullptr) { + // For VibratorEvent with VibratorEvent::type == EVENT_TYPE_CONTINUOUS, at lease one VibratorCurvePoint + // shoule be assigned to VibratorEvent::points for subsequent process + curvePoints = (VibratorCurvePoint*)malloc(sizeof(VibratorCurvePoint)); + if (curvePoints == nullptr) { + MISC_HILOGE("ModulateVibratorEvent failed: failed to allocate memory for VibratorCurvePoint"); + return ERROR; + } + curvePoints->frequency = CURVE_FREQUENCY_NO_MODIFICATION; + curvePoints->intensity = CURVE_INTENSITY_NO_MODIFICATION; + curvePoints->time = CURVE_TIME_NO_MODIFICATION; + } + VibratorEvent beforeModulationEventCopy = beforeModulationEvent; + if (beforeModulationEventCopy.pointNum == 0 || beforeModulationEventCopy.points == nullptr) { + beforeModulationEventCopy.points = curvePoints; + beforeModulationEventCopy.pointNum = 1; + } + if (VibratorServiceClient::ModulateContinuousVibratorEvent( + modulationCurve, patternStartTime, beforeModulationEventCopy, afterModulationEvent) != ERR_OK) { + MISC_HILOGE("ModulateVibratorEvent failed due to failure of ModulateContinuousVibratorEvent"); + free(curvePoints); + curvePoints = nullptr; + return ERROR; + } + free(curvePoints); + curvePoints = nullptr; + return ERR_OK; +} + +int32_t VibratorServiceClient::CopyNonContinuousVibratorEvent(const VibratorEvent &event, VibratorEvent &eventCopy) +{ + eventCopy = event; + if (event.pointNum <= 0 || event.points == nullptr) { + eventCopy.pointNum = 0; + eventCopy.points = nullptr; + return ERR_OK; + } + int32_t curveMemSize = event.pointNum * sizeof(VibratorCurvePoint); + VibratorCurvePoint* curvePointsCopy = (VibratorCurvePoint*)malloc(curveMemSize); + if (curvePointsCopy == nullptr) { + MISC_HILOGE("ModulateVibratorEvent failed: failed to allocate memory for VibratorCurvePoint"); + return ERROR; + } + if (memcpy_s(curvePointsCopy, curveMemSize, event.points, curveMemSize) != 0) { + free(curvePointsCopy); + curvePointsCopy = nullptr; + MISC_HILOGE("ModulateVibratorEvent failed: failed to memcpy for VibratorCurvePoint"); + return ERROR; + } + eventCopy.points = curvePointsCopy; + return ERR_OK; +} + +// absoluteTime = VibratorPattern::time + VibratorEvent::time + VibratorCurvePoint::time +int32_t VibratorServiceClient::ModulateContinuousVibratorEvent(const VibratorEvent &modulationCurve, + const int patternStartTime, const VibratorEvent &beforeModulationEvent, VibratorEvent &afterModulationEvent) +{ + std::vector currentInterval; + std::vector modInterval; + VibratorServiceClient::ConvertVibratorEventsToCurveIntervals(beforeModulationEvent, + patternStartTime, currentInterval); + VibratorServiceClient::ConvertVibratorEventsToCurveIntervals(modulationCurve, 0, modInterval); + std::set intervalEdges; + for (auto iter = currentInterval.begin(); iter != currentInterval.end() ; iter++) { + intervalEdges.insert(iter->beginTime); + intervalEdges.insert(iter->endTime); + } + for (auto iter = modInterval.begin(); iter != modInterval.end() ; iter++) { + intervalEdges.insert(iter->beginTime); + intervalEdges.insert(iter->endTime); + } + VibratorCurvePoint* curvePoints = nullptr; + int32_t curveNum = 0; + if (VibratorServiceClient::GetCurveListAfterModulation(intervalEdges, currentInterval, modInterval, + patternStartTime + beforeModulationEvent.time, curvePoints, curveNum) != ERR_OK) { + MISC_HILOGE("ModulateContinuousVibratorEvent failed due to failure of GetCurveListAfterModulation"); + return ERROR; + } + afterModulationEvent = beforeModulationEvent; + afterModulationEvent.points = curvePoints; + afterModulationEvent.pointNum = curveNum; + return ERR_OK; +} + +int32_t VibratorServiceClient::GetCurveListAfterModulation(const std::set& intervalEdges, + const std::vector& currentInterval, const std::vector& modInterval, + const int offset, VibratorCurvePoint*& curve, int32_t& curveNum) +{ + // There are atmost (modulationCurve.pointNum + beforeModulationEvent.pointNum + 1) + // VibratorCurvePoints after modulation + VibratorCurvePoint* curvePoints = (VibratorCurvePoint*)malloc( + sizeof(VibratorCurvePoint) * (currentInterval.size() + modInterval.size() + 1)); + if (curvePoints == nullptr) { + MISC_HILOGE("ModulateVibratorEvent failed due to failure of memory allocation for VibratorCurvePoint"); + return ERROR; + } + int32_t curvePointsIdx = 0; + const int32_t originalEventStartTime = currentInterval.begin()->beginTime; + const int32_t originalEventEndTime = currentInterval.rbegin()->endTime; + const int32_t modEventStartTime = modInterval.begin()->beginTime; + int32_t originalIdx = 0; + int32_t modIdx = 0; + int32_t pointStartTime = originalEventStartTime; + for (auto iter = intervalEdges.begin(); iter != intervalEdges.end(); iter++) { + int32_t edge = *iter; + if (edge <= originalEventStartTime) { + continue; + } + if (edge > originalEventEndTime) { + break; + } + if (!VibratorServiceClient::BinarySearchInterval(currentInterval, edge, originalIdx)) { + MISC_HILOGE("ModulateContinuousVibratorEvent failed due to failure of BinarySearchInterval"); + free(curvePoints); + curvePoints = nullptr; + return ERROR; + } + VibratorCurvePoint& currentPoint = curvePoints[curvePointsIdx++]; + if (edge <= modEventStartTime || !VibratorServiceClient::BinarySearchInterval(modInterval, edge, modIdx)) { + currentPoint.frequency = currentInterval[originalIdx].frequency; + currentPoint.intensity = currentInterval[originalIdx].intensity; + } else { + VibratorServiceClient::ModulateSingleCurvePoint( + modInterval[modIdx], currentInterval[originalIdx], currentPoint); + } + currentPoint.time = pointStartTime - offset; + pointStartTime = edge; + } + curve = curvePoints; + curveNum = curvePointsIdx; + return ERR_OK; +} + +bool VibratorServiceClient::BinarySearchInterval( + const std::vector& interval, const int32_t val, int32_t& idx) +{ + if (val < interval.begin()->beginTime || val > interval.rbegin()->endTime) { + return false; + } + if (val >= interval.begin()->beginTime && val <= interval.begin()->endTime) { + idx = 0; + return true; + } + int32_t headIdx = 0; + int32_t tailIdx = interval.size() - 1; + while (tailIdx - headIdx > 1) { + int32_t middleIdx = ((tailIdx - headIdx) / 2) + headIdx; + if (interval[middleIdx].endTime < val) { + headIdx = middleIdx; + } else { + tailIdx = middleIdx; + } + } + idx = tailIdx; + return true; +} + +void VibratorServiceClient::ConvertVibratorEventsToCurveIntervals( + const VibratorEvent &vibratorEvent, const int patternTimeOffset, std::vector& curveInterval) +{ + int32_t fullOffset = patternTimeOffset + vibratorEvent.time; + const VibratorCurvePoint* curvePoints = vibratorEvent.points; + for (int32_t i = 0; i < vibratorEvent.pointNum; i++) { + if (curvePoints[i].time < vibratorEvent.duration) { + int32_t beginTime = fullOffset + curvePoints[i].time; + int32_t endTime = fullOffset + ((i + 1) < vibratorEvent.pointNum ? + std::min(curvePoints[i + 1].time, vibratorEvent.duration) : vibratorEvent.duration); + int32_t frequency = curvePoints[i].frequency; + int32_t intensity = curvePoints[i].intensity; + curveInterval.emplace_back(VibratorCurveInterval{ + .beginTime = beginTime, .endTime = endTime, .intensity = intensity, .frequency = frequency}); + } else { + break; + } + } +} + +void VibratorServiceClient::ModulateSingleCurvePoint(const VibratorCurveInterval &modulationInterval, + const VibratorCurveInterval &originalInterval, VibratorCurvePoint& point) +{ + point.frequency = VibratorServiceClient::RestrictFrequencyRange( + modulationInterval.frequency + originalInterval.frequency); + point.intensity = VibratorServiceClient::RestrictIntensityRange( + modulationInterval.intensity * originalInterval.intensity / (INTENSITY_UPPERBOUND - INTENSITY_LOWERBOUND)); +} + +int32_t VibratorServiceClient::RestrictFrequencyRange(int32_t frequency) +{ + if (frequency > FREQUENCY_UPPER_BOUND) { + return FREQUENCY_UPPER_BOUND; + } else if (frequency < FREQUENCY_LOWER_BOUND) { + return FREQUENCY_LOWER_BOUND; + } else { + return frequency; + } +} + +int32_t VibratorServiceClient::RestrictIntensityRange(int32_t intensity) +{ + if (intensity > INTENSITY_UPPERBOUND) { + return INTENSITY_UPPERBOUND; + } else if (intensity < INTENSITY_LOWERBOUND) { + return INTENSITY_LOWERBOUND; + } else { + return intensity; + } +} + bool VibratorServiceClient::SkipEventAndConvertVibratorEvent(const VibratorEvent &vibratorEvent, VibratePattern &vibratePattern, int32_t patternStartTime, VibrateEvent &vibrateEvent) { diff --git a/frameworks/native/vibrator/vibrator_agent.cpp b/frameworks/native/vibrator/vibrator_agent.cpp index f459f43..580c4f0 100644 --- a/frameworks/native/vibrator/vibrator_agent.cpp +++ b/frameworks/native/vibrator/vibrator_agent.cpp @@ -351,10 +351,24 @@ int32_t SeekTimeOnPackage(int32_t seekTime, const VibratorPackage &completePacka return SUCCESS; } +int32_t ModulatePackage(const VibratorCurvePoint* modulationCurve, const int32_t curvePointNum, const int32_t duration, + const VibratorPackage &beforeModulationPackage, VibratorPackage &afterModulationPackage) +{ + VibratorEvent modulationEvent{.type = EVENT_TYPE_CONTINUOUS, .time = 0, .duration = duration, + .intensity = -1, .frequency = -1, .index = 0, .pointNum = curvePointNum, + .points = const_cast(modulationCurve)}; + int32_t ret = VibratorServiceClient::ModulatePackage( + modulationEvent, beforeModulationPackage, afterModulationPackage); + if (ret != ERR_OK) { + MISC_HILOGD("ModulatePackage failed, ret:%{public}d", ret); + return NormalizeErrCode(ret); + } + return SUCCESS; +} + int32_t FreeVibratorPackage(VibratorPackage &package) { - auto &client = VibratorServiceClient::GetInstance(); - int32_t ret = client.FreeVibratorPackage(package); + int32_t ret = VibratorServiceClient::FreeVibratorPackage(package); if (ret != ERR_OK) { MISC_HILOGD("FreeVibratorPackage failed, ret:%{public}d", ret); return NormalizeErrCode(ret); diff --git a/interfaces/inner_api/vibrator/vibrator_agent.h b/interfaces/inner_api/vibrator/vibrator_agent.h index 595a746..5b60b44 100644 --- a/interfaces/inner_api/vibrator/vibrator_agent.h +++ b/interfaces/inner_api/vibrator/vibrator_agent.h @@ -184,6 +184,20 @@ int32_t PreProcess(const VibratorFileDescription &fd, VibratorPackage &package); */ int32_t SeekTimeOnPackage(int32_t seekTime, const VibratorPackage &completePackage, VibratorPackage &seekPackage); +/** + * @brief Modulate a series of weaveform with another weaveform. + * @param modulationCurve: A weaveform indicating how to modulate, only modulationCurve.points, + * modulationCurve.pointNum, modulationCurve.time and modulationCurve.duration are used. + * @param curvePointNum: count of curvePoints + * @param duration: duration of curvePoints + * @param beforeModulationPackage: Weaveform to be modulated. + * @param afterModulationPackage: Result weaveform after modulation. + * @return 0 indicates success, otherwise indicates failure. + * @since 19 + */ +int32_t ModulatePackage(const VibratorCurvePoint* modulationCurve, const int32_t curvePointNum, const int32_t duration, + const VibratorPackage &beforeModulationPackage, VibratorPackage &afterModulationPackage); + /** * @brief Free up the vibration sequence package memory. * @param package: Vibration sequence packages, such as {@link VibrationPackage}. diff --git a/test/unittest/vibrator/native/BUILD.gn b/test/unittest/vibrator/native/BUILD.gn index 1f93558..c060cf1 100644 --- a/test/unittest/vibrator/native/BUILD.gn +++ b/test/unittest/vibrator/native/BUILD.gn @@ -77,10 +77,41 @@ ohos_unittest("VibratorAgentSeekTest") { } } +ohos_unittest("VibratorAgentModulationTest") { + module_out_path = "miscdevice/miscdevice/native" + + sources = [ "vibrator_agent_modulation_test.cpp" ] + + include_dirs = [ + "$SUBSYSTEM_DIR/interfaces/inner_api/vibrator", + "$SUBSYSTEM_DIR/utils/common/include", + ] + + deps = [ + "$SUBSYSTEM_DIR/frameworks/native/vibrator:vibrator_target", + "$SUBSYSTEM_DIR/utils/common:libmiscdevice_utils", + ] + + external_deps = [ + "c_utils:utils", + "googletest:gmock", + "googletest:gtest_main", + "hilog:libhilog", + "init:libbegetutil", + "ipc:ipc_single", + ] + + if (miscdevice_feature_vibrator_custom) { + resource_config_file = + "$SUBSYSTEM_DIR/test/unittest/vibrator/native/resource/ohos_test.xml" + } +} + group("unittest") { testonly = true deps = [ ":VibratorAgentSeekTest", ":VibratorAgentTest", + ":VibratorAgentModulationTest", ] } diff --git a/test/unittest/vibrator/native/resource/json_file/modulation_curve.json b/test/unittest/vibrator/native/resource/json_file/modulation_curve.json new file mode 100644 index 0000000..a1a0dcc --- /dev/null +++ b/test/unittest/vibrator/native/resource/json_file/modulation_curve.json @@ -0,0 +1,146 @@ +{ + "MetaData": { + "Create": "2025-01-14", + "Description": "a modulation curve testcase", + "Version": 1.0, + "ChannelNumber": 1 + }, + "Channels": [ + { + "Parameters": { + "Index": 0 + }, + "Pattern": [ + { + "Event": { + "Type": "continuous", + "StartTime": 0, + "Duration": 30, + "Parameters": { + "Frequency": 0, + "Intensity": 0, + "Curve": [ + { + "Time": 0, + "Frequency": 0, + "Intensity": 0 + }, + { + "Time": 10, + "Frequency": -10, + "Intensity": 0.15 + }, + { + "Time": 15, + "Frequency": -10, + "Intensity": 0.25 + }, + { + "Time": 20, + "Frequency": -10, + "Intensity": 0.35 + } + ] + } + } + }, + { + "Event": { + "Type": "continuous", + "StartTime": 410, + "Duration": 254, + "Parameters": { + "Frequency": 30, + "Intensity": 38, + "Curve": [ + { + "Time": 0, + "Frequency": -10, + "Intensity": 0.17 + }, + { + "Time": 100, + "Frequency": 10, + "Intensity": 1 + }, + { + "Time": 150, + "Frequency": 10, + "Intensity": 0.5 + }, + { + "Time": 210, + "Frequency": -20, + "Intensity": 0.89 + }, + { + "Time": 234, + "Frequency": 20, + "Intensity": 0.77 + }, + { + "Time": 254, + "Frequency": 20, + "Intensity": 0 + } + ] + } + } + }, + { + "Event": { + "Type": "continuous", + "StartTime": 940, + "Duration": 300, + "Parameters": { + "Frequency": 30, + "Intensity": 38, + "Curve": [ + { + "Time": 0, + "Frequency": 20, + "Intensity": 0.1 + }, + { + "Time": 20, + "Frequency": -30, + "Intensity": 0.2 + }, + { + "Time": 80, + "Frequency": 40, + "Intensity": 0.3 + }, + { + "Time": 100, + "Frequency": -50, + "Intensity": 0.4 + }, + { + "Time": 150, + "Frequency": 20, + "Intensity": 0.6 + }, + { + "Time": 200, + "Frequency": -30, + "Intensity": 0.7 + }, + { + "Time": 240, + "Frequency": 40, + "Intensity": 0.8 + }, + { + "Time": 280, + "Frequency": -50, + "Intensity": 0.9 + } + ] + } + } + } + ] + } + ] +} \ No newline at end of file diff --git a/test/unittest/vibrator/native/resource/json_file/package_before_modulation.json b/test/unittest/vibrator/native/resource/json_file/package_before_modulation.json new file mode 100644 index 0000000..0b9e82f --- /dev/null +++ b/test/unittest/vibrator/native/resource/json_file/package_before_modulation.json @@ -0,0 +1,198 @@ +{ + "MetaData": { + "Create": "2025-01-14", + "Description": "a haptic testcase", + "Version": 1.0, + "ChannelNumber": 1 + }, + "Channels": [ + { + "Parameters": { + "Index": 0 + }, + "Pattern": [ + { + "Event": { + "Type": "transient", + "StartTime": 0, + "Parameters": { + "Frequency": 31, + "Intensity": 100 + } + } + }, + { + "Event": { + "Type": "continuous", + "StartTime": 40, + "Duration": 54, + "Parameters": { + "Frequency": 30, + "Intensity": 38, + "Curve": [ + { + "Time": 0, + "Frequency": 0, + "Intensity": 0 + }, + { + "Time": 1, + "Frequency": 0, + "Intensity": 1 + }, + { + "Time": 40, + "Frequency": 0, + "Intensity": 1 + }, + { + "Time": 54, + "Frequency": 0, + "Intensity": 0 + } + ] + } + } + }, + { + "Event": { + "Type": "transient", + "StartTime": 103, + "Parameters": { + "Frequency": 69, + "Intensity": 79 + } + } + }, + { + "Event": { + "Type": "transient", + "StartTime": 180, + "Parameters": { + "Frequency": 82, + "Intensity": 53 + } + } + }, + { + "Event": { + "Type": "transient", + "StartTime": 239, + "Parameters": { + "Frequency": 82, + "Intensity": 51 + } + } + }, + { + "Event": { + "Type": "transient", + "StartTime": 319, + "Parameters": { + "Frequency": 74, + "Intensity": 37 + } + } + }, + { + "Event": { + "Type": "transient", + "StartTime": 350, + "Parameters": { + "Frequency": 44, + "Intensity": 24 + } + } + }, + { + "Event": { + "Type": "continuous", + "StartTime": 410, + "Duration": 254, + "Parameters": { + "Frequency": 30, + "Intensity": 38, + "Curve": [ + { + "Time": 0, + "Frequency": 0, + "Intensity": 0 + }, + { + "Time": 100, + "Frequency": 0, + "Intensity": 1 + }, + { + "Time": 200, + "Frequency": 0, + "Intensity": 1 + }, + { + "Time": 254, + "Frequency": 0, + "Intensity": 0 + } + ] + } + } + }, + { + "Event": { + "Type": "continuous", + "StartTime": 670, + "Duration": 254, + "Parameters": { + "Frequency": 30, + "Intensity": 38, + "Curve": [ + { + "Time": 0, + "Frequency": 0, + "Intensity": 0 + }, + { + "Time": 100, + "Frequency": 0, + "Intensity": 1 + }, + { + "Time": 200, + "Frequency": 0, + "Intensity": 1 + }, + { + "Time": 254, + "Frequency": 0, + "Intensity": 0 + } + ] + } + } + }, + { + "Event": { + "Type": "continuous", + "StartTime": 940, + "Duration": 160, + "Parameters": { + "Frequency": 37, + "Intensity": 74 + } + } + }, + { + "Event": { + "Type": "continuous", + "StartTime": 1100, + "Duration": 100, + "Parameters": { + "Frequency": 44, + "Intensity": 24 + } + } + } + ] + } + ] +} \ No newline at end of file diff --git a/test/unittest/vibrator/native/resource/ohos_test.xml b/test/unittest/vibrator/native/resource/ohos_test.xml index 2a0d527..ecb8912 100644 --- a/test/unittest/vibrator/native/resource/ohos_test.xml +++ b/test/unittest/vibrator/native/resource/ohos_test.xml @@ -38,4 +38,10 @@