From 6164e098d5f4bc1fe21b88bcd00ee983d637cd61 Mon Sep 17 00:00:00 2001 From: wuzhihuitmac Date: Sat, 22 Mar 2025 15:53:30 +0800 Subject: [PATCH] Modify the async function Signed-off-by: wuzhihuitmac Change-Id: I71c13896ed9b1d2df6546f3ac097c9b3d1db15a3 --- .../vibrator/include/vibrator_napi_utils.h | 18 ++++ .../js/napi/vibrator/src/vibrator_js.cpp | 88 +++++++----------- .../napi/vibrator/src/vibrator_napi_utils.cpp | 89 +++++++++++++------ .../inner_api/vibrator/vibrator_agent.h | 4 +- 4 files changed, 113 insertions(+), 86 deletions(-) diff --git a/frameworks/js/napi/vibrator/include/vibrator_napi_utils.h b/frameworks/js/napi/vibrator/include/vibrator_napi_utils.h index 87a6191..3cb87e7 100644 --- a/frameworks/js/napi/vibrator/include/vibrator_napi_utils.h +++ b/frameworks/js/napi/vibrator/include/vibrator_napi_utils.h @@ -25,6 +25,7 @@ #include "refbase.h" #include "sensors_errors.h" +#include "vibrator_agent.h" #include "vibrator_agent_type.h" namespace OHOS { @@ -39,6 +40,20 @@ enum CallbackType { IS_SUPPORT_EFFECT_CALLBACK, }; +struct VibrateInfo { + std::string type; + std::string usage; + bool systemUsage {false}; + int32_t duration = 0; + std::string effectId; + int32_t count = 0; + int32_t fd = -1; + int64_t offset = 0; + int64_t length = -1; + int32_t intensity = 0; + VibratorPattern vibratorPattern; +}; + class AsyncCallbackInfo : public RefBase { public: struct AsyncCallbackError { @@ -48,6 +63,7 @@ public: string stack; }; + VibrateInfo info; napi_env env = nullptr; napi_async_work asyncWork = nullptr; napi_deferred deferred = nullptr; @@ -55,6 +71,7 @@ public: AsyncCallbackError error; CallbackType callbackType = COMMON_CALLBACK; bool isSupportEffect {false}; + std::string flag; AsyncCallbackInfo(napi_env env) : env(env) {} ~AsyncCallbackInfo(); }; @@ -83,6 +100,7 @@ bool ConstructIsSupportEffectResult(const napi_env &env, sptr napi_value result[], int32_t length); void EmitAsyncCallbackWork(sptr async_callback_info); void EmitPromiseWork(sptr asyncCallbackInfo); +bool ClearVibratorPattern(VibratorPattern &vibratorPattern); } // namespace Sensors } // namespace OHOS #endif // VIBRATOR_NAPI_UTILS_H \ No newline at end of file diff --git a/frameworks/js/napi/vibrator/src/vibrator_js.cpp b/frameworks/js/napi/vibrator/src/vibrator_js.cpp index 0e678f9..0273505 100644 --- a/frameworks/js/napi/vibrator/src/vibrator_js.cpp +++ b/frameworks/js/napi/vibrator/src/vibrator_js.cpp @@ -25,7 +25,6 @@ #include "file_utils.h" #include "miscdevice_log.h" -#include "vibrator_agent.h" #include "vibrator_napi_error.h" #include "vibrator_napi_utils.h" #include "vibrator_pattern_js.h" @@ -70,20 +69,6 @@ static std::map g_usageType = { static std::set g_allowedTypes = {"time", "preset", "file", "pattern"}; -struct VibrateInfo { - std::string type; - std::string usage; - bool systemUsage; - int32_t duration = 0; - std::string effectId; - int32_t count = 0; - int32_t fd = -1; - int64_t offset = 0; - int64_t length = -1; - int32_t intensity = 0; - VibratorPattern vibratorPattern; -}; - static napi_value EmitAsyncWork(napi_value param, sptr info) { CHKPP(info); @@ -194,26 +179,6 @@ static napi_value VibrateMode(napi_env env, napi_value args[], size_t argc) return nullptr; } -static bool ClearVibratorPattern(VibratorPattern &vibratorPattern) -{ - CALL_LOG_ENTER; - int32_t eventSize = vibratorPattern.eventNum; - if ((eventSize <= 0) || (vibratorPattern.events == nullptr)) { - MISC_HILOGW("events is not need to free, eventSize:%{public}d", eventSize); - return false; - } - auto events = vibratorPattern.events; - for (int32_t j = 0; j < eventSize; ++j) { - if (events[j].points != nullptr) { - free(events[j].points); - events[j].points = nullptr; - } - } - free(events); - events = nullptr; - return true; -} - static bool ParseVibratorCurvePoint(napi_env env, napi_value pointsArray, uint32_t index, VibratorCurvePoint &point) { napi_value pointsElement = nullptr; @@ -463,7 +428,7 @@ bool SetUsage(const std::string &usage, bool systemUsage) return SetUsage(g_usageType[usage], systemUsage); } -int32_t StartVibrate(const VibrateInfo &info) +int32_t CheckParameters(const VibrateInfo &info) { CALL_LOG_ENTER; if (!SetUsage(info.usage, info.systemUsage)) { @@ -474,13 +439,17 @@ int32_t StartVibrate(const VibrateInfo &info) MISC_HILOGE("Invalid vibrate type, type:%{public}s", info.type.c_str()); return PARAMETER_ERROR; } - if (info.type == "preset") { - if (!SetLoopCount(info.count)) { - MISC_HILOGE("SetLoopCount fail"); - return PARAMETER_ERROR; - } - return PlayPrimitiveEffect(info.effectId.c_str(), info.intensity); - } else if (info.type == "file") { + return ERR_OK; +} + +int32_t StartVibrate(const VibrateInfo &info) +{ + CALL_LOG_ENTER; + if (CheckParameters(info) != ERR_OK) { + MISC_HILOGE("CheckParameters fail"); + return PARAMETER_ERROR; + } + if (info.type == "file") { return PlayVibratorCustom(info.fd, info.offset, info.length); } else if (info.type == "pattern") { return PlayPattern(info.vibratorPattern); @@ -490,22 +459,31 @@ int32_t StartVibrate(const VibrateInfo &info) static napi_value VibrateEffect(napi_env env, napi_value args[], size_t argc) { - VibrateInfo info; - if (!ParseParameter(env, args, argc, info)) { - ThrowErr(env, PARAMETER_ERROR, "parameter fail"); - return nullptr; - } sptr asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env); CHKPP(asyncCallbackInfo); - asyncCallbackInfo->error.code = StartVibrate(info); - - if (info.vibratorPattern.events != nullptr) { - CHKCP(ClearVibratorPattern(info.vibratorPattern), "ClearVibratorPattern fail"); - } - if ((asyncCallbackInfo->error.code != SUCCESS) && (asyncCallbackInfo->error.code == PARAMETER_ERROR)) { - ThrowErr(env, PARAMETER_ERROR, "parameters invalid"); + if (!ParseParameter(env, args, argc, asyncCallbackInfo->info)) { + MISC_HILOGE("ParseParameter fail"); + ThrowErr(env, PARAMETER_ERROR, "ParseParameter fail"); return nullptr; } + if (asyncCallbackInfo->info.type == "preset") { + if (!SetLoopCount(asyncCallbackInfo->info.count) || CheckParameters(asyncCallbackInfo->info) != ERR_OK || + asyncCallbackInfo->info.effectId.empty()) { + MISC_HILOGE("SetLoopCount fail or parameter invalid"); + ThrowErr(env, PARAMETER_ERROR, "SetLoopCount fail or parameter invalid"); + return nullptr; + } + asyncCallbackInfo->flag = "preset"; + } else { + asyncCallbackInfo->error.code = StartVibrate(asyncCallbackInfo->info); + if (asyncCallbackInfo->info.vibratorPattern.events != nullptr) { + CHKCP(ClearVibratorPattern(asyncCallbackInfo->info.vibratorPattern), "ClearVibratorPattern fail"); + } + if (asyncCallbackInfo->error.code == PARAMETER_ERROR) { + ThrowErr(env, PARAMETER_ERROR, "Parameters invalid"); + return nullptr; + } + } if (argc >= PARAMETER_THREE && IsMatchType(env, args[2], napi_function)) { return EmitAsyncWork(args[2], asyncCallbackInfo); } diff --git a/frameworks/js/napi/vibrator/src/vibrator_napi_utils.cpp b/frameworks/js/napi/vibrator/src/vibrator_napi_utils.cpp index 6e3c122..6bebfce 100644 --- a/frameworks/js/napi/vibrator/src/vibrator_napi_utils.cpp +++ b/frameworks/js/napi/vibrator/src/vibrator_napi_utils.cpp @@ -45,6 +45,26 @@ AsyncCallbackInfo::~AsyncCallbackInfo() } } +bool ClearVibratorPattern(VibratorPattern &vibratorPattern) +{ + CALL_LOG_ENTER; + int32_t eventSize = vibratorPattern.eventNum; + if ((eventSize <= 0) || (vibratorPattern.events == nullptr)) { + MISC_HILOGW("events is not need to free, eventSize:%{public}d", eventSize); + return false; + } + auto events = vibratorPattern.events; + for (int32_t j = 0; j < eventSize; ++j) { + if (events[j].points != nullptr) { + free(events[j].points); + events[j].points = nullptr; + } + } + free(events); + events = nullptr; + return true; +} + bool CreateInt32Property(napi_env env, napi_value &eventObj, const char* name, int32_t value) { CALL_LOG_ENTER; @@ -308,6 +328,40 @@ void EmitSystemCallback(const napi_env &env, sptr asyncCallba NAPI_CALL_RETURN_VOID(env, napi_call_function(env, nullptr, callback, 1, result, &callResult)); } +void CompleteCallback(napi_env env, napi_status status, void *data) +{ + CALL_LOG_ENTER; + sptr asyncCallbackInfo(static_cast(data)); + /** + * After the asynchronous task is created, the asyncCallbackInfo reference count is reduced + * to 0 destruction, so you need to add 1 to the asyncCallbackInfo reference count when the + * asynchronous task is created, and subtract 1 from the reference count after the naked + * pointer is converted to a pointer when the asynchronous task is executed, the reference + * count of the smart pointer is guaranteed to be 1. + */ + asyncCallbackInfo->DecStrongRef(nullptr); + if (asyncCallbackInfo->callbackType == SYSTEM_VIBRATE_CALLBACK) { + EmitSystemCallback(env, asyncCallbackInfo); + return; + } + if (asyncCallbackInfo->flag == "preset" && asyncCallbackInfo->info.vibratorPattern.events != nullptr) { + CHKCV(ClearVibratorPattern(asyncCallbackInfo->info.vibratorPattern), "ClearVibratorPattern fail"); + } + CHKPV(asyncCallbackInfo->callback[0]); + napi_value callback = nullptr; + napi_status ret = napi_get_reference_value(env, asyncCallbackInfo->callback[0], &callback); + CHKCV((ret == napi_ok), "napi_get_reference_value fail"); + napi_value result[RESULT_LENGTH] = { 0 }; + CHKCV((g_convertFuncList.find(asyncCallbackInfo->callbackType) != g_convertFuncList.end()), + "Callback type invalid in async work"); + bool state = g_convertFuncList[asyncCallbackInfo->callbackType](env, asyncCallbackInfo, result, + sizeof(result) / sizeof(napi_value)); + CHKCV(state, "Create napi data fail in async work"); + napi_value callResult = nullptr; + CHKCV((napi_call_function(env, nullptr, callback, 2, result, &callResult) == napi_ok), + "napi_call_function fail"); +} + void EmitAsyncCallbackWork(sptr asyncCallbackInfo) { CALL_LOG_ENTER; @@ -319,40 +373,17 @@ void EmitAsyncCallbackWork(sptr asyncCallbackInfo) CHKCV((ret == napi_ok), "napi_create_string_latin1 fail"); asyncCallbackInfo->IncStrongRef(nullptr); napi_status status = napi_create_async_work( - env, nullptr, resourceName, [](napi_env env, void *data) {}, - [](napi_env env, napi_status status, void *data) { + env, nullptr, resourceName, [](napi_env env, void *data) { CALL_LOG_ENTER; sptr asyncCallbackInfo(static_cast(data)); - /** - * After the asynchronous task is created, the asyncCallbackInfo reference count is reduced - * to 0 destruction, so you need to add 1 to the asyncCallbackInfo reference count when the - * asynchronous task is created, and subtract 1 from the reference count after the naked - * pointer is converted to a pointer when the asynchronous task is executed, the reference - * count of the smart pointer is guaranteed to be 1. - */ - asyncCallbackInfo->DecStrongRef(nullptr); - if (asyncCallbackInfo->callbackType == SYSTEM_VIBRATE_CALLBACK) { - EmitSystemCallback(env, asyncCallbackInfo); - return; + if (asyncCallbackInfo->flag == "preset") { + asyncCallbackInfo->error.code = PlayPrimitiveEffect(asyncCallbackInfo->info.effectId.c_str(), + asyncCallbackInfo->info.intensity); } - CHKPV(asyncCallbackInfo->callback[0]); - napi_value callback = nullptr; - napi_status ret = napi_get_reference_value(env, asyncCallbackInfo->callback[0], &callback); - CHKCV((ret == napi_ok), "napi_get_reference_value fail"); - napi_value result[RESULT_LENGTH] = { 0 }; - CHKCV((g_convertFuncList.find(asyncCallbackInfo->callbackType) != g_convertFuncList.end()), - "Callback type invalid in async work"); - bool state = g_convertFuncList[asyncCallbackInfo->callbackType](env, asyncCallbackInfo, result, - sizeof(result) / sizeof(napi_value)); - CHKCV(state, "Create napi data fail in async work"); - napi_value callResult = nullptr; - CHKCV((napi_call_function(env, nullptr, callback, 2, result, &callResult) == napi_ok), - "napi_call_function fail"); - }, - asyncCallbackInfo.GetRefPtr(), &asyncCallbackInfo->asyncWork); + }, CompleteCallback, asyncCallbackInfo.GetRefPtr(), &asyncCallbackInfo->asyncWork); if (status != napi_ok || napi_queue_async_work_with_qos( - asyncCallbackInfo->env, asyncCallbackInfo->asyncWork, napi_qos_default) != napi_ok) { + asyncCallbackInfo->env, asyncCallbackInfo->asyncWork, napi_qos_user_initiated) != napi_ok) { MISC_HILOGE("Create async work fail"); asyncCallbackInfo->DecStrongRef(nullptr); } diff --git a/interfaces/inner_api/vibrator/vibrator_agent.h b/interfaces/inner_api/vibrator/vibrator_agent.h index 5f22284..859d7ea 100644 --- a/interfaces/inner_api/vibrator/vibrator_agent.h +++ b/interfaces/inner_api/vibrator/vibrator_agent.h @@ -43,14 +43,14 @@ namespace Sensors { * * @since 6 */ -const char *VIBRATOR_STOP_MODE_TIME = "time"; +static const char *VIBRATOR_STOP_MODE_TIME = "time"; /** * @brief Indicates the mode of stopping a preset vibration effect. * * @since 6 */ -const char *VIBRATOR_STOP_MODE_PRESET = "preset"; +static const char *VIBRATOR_STOP_MODE_PRESET = "preset"; /** * @brief Controls this vibrator to perform a vibration with a preset vibration effect. -- Gitee