From 990c17bdef28851f2f956a4537306f5dbad2d057 Mon Sep 17 00:00:00 2001 From: songhuan Date: Tue, 22 Apr 2025 16:55:21 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=8A=9B=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: songhuan Change-Id: I3d0304a53f4a3bf78c0672d457392a8614bdb755 --- frameworks/js/ani/src/sensor_ani.cpp | 84 ++++++++++++++++------------ 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/frameworks/js/ani/src/sensor_ani.cpp b/frameworks/js/ani/src/sensor_ani.cpp index 5eec81d4..9df28203 100644 --- a/frameworks/js/ani/src/sensor_ani.cpp +++ b/frameworks/js/ani/src/sensor_ani.cpp @@ -86,25 +86,43 @@ static float g_bodyState = -1.0f; static std::map>> g_subscribeCallbacks; static std::mutex onMutex_; static std::map>> g_onCallbackInfos; +static thread_local std::shared_ptr mainHandler; -static ani_error CreateAniError(ani_env *env, std::string &&errMsg) +static void ThrowBusinessError(ani_env *env, int errCode, std::string&& errMsg) { - static const char *errorClsName = "Lescompat/Error;"; + SEN_HILOGD("Begin ThrowBusinessError."); + static const char *errorClsName = "L@ohos/base/BusinessError;"; ani_class cls {}; if (ANI_OK != env->FindClass(errorClsName, &cls)) { - SEN_HILOGE("Not found namespace %{public}s.", errorClsName); - return nullptr; + SEN_HILOGE("find class BusinessError %{public}s failed", errorClsName); + return; } ani_method ctor; - if (ANI_OK != env->Class_FindMethod(cls, "", "Lstd/core/String;:V", &ctor)) { - SEN_HILOGE("Not found in %{public}s.", errorClsName); - return nullptr; + if (ANI_OK != env->Class_FindMethod(cls, "", ":V", &ctor)) { + SEN_HILOGE("find method BusinessError.constructor failed"); + return; } - ani_string error_msg; - env->String_NewUTF8(errMsg.c_str(), 17U, &error_msg); ani_object errorObject; - env->Object_New(cls, ctor, &errorObject, error_msg); - return static_cast(errorObject); + if (ANI_OK != env->Object_New(cls, ctor, &errorObject)) { + SEN_HILOGE("create BusinessError object failed"); + return; + } + ani_double aniErrCode = static_cast(errCode); + ani_string errMsgStr; + if (ANI_OK != env->String_NewUTF8(errMsg.c_str(), errMsg.size(), &errMsgStr)) { + SEN_HILOGE("convert errMsg to ani_string failed"); + return; + } + if (ANI_OK != env->Object_SetFieldByName_Double(errorObject, "code", aniErrCode)) { + SEN_HILOGE("set error code failed"); + return; + } + if (ANI_OK != env->Object_SetPropertyByName_Ref(errorObject, "message", errMsgStr)) { + SEN_HILOGE("set error message failed"); + return; + } + env->ThrowError(static_cast(errorObject)); + return; } static bool CheckSubscribe(int32_t sensorTypeId) @@ -170,17 +188,19 @@ static ani_boolean IsInstanceOf(ani_env *env, const std::string &cls_name, ani_o static bool SendEventToMainThread(const std::function func) { if (func == nullptr) { - SEN_HILOGE("func == nullptr"); + SEN_HILOGE("func is nullptr!"); return false; } - auto runner = OHOS::AppExecFwk::EventRunner::GetMainEventRunner(); - if (!runner) { - SEN_HILOGE("runner == nullptr"); - return false; + + if (!mainHandler) { + auto runner = OHOS::AppExecFwk::EventRunner::GetMainEventRunner(); + if (!runner) { + SEN_HILOGE("get main event runner failed!"); + return false; + } + mainHandler = std::make_shared(runner); } - auto handler = std::make_shared(runner); - handler->PostTask(func, "", 0, OHOS::AppExecFwk::EventQueue::Priority::HIGH, {}); - SEN_HILOGD("PostTask success"); + mainHandler->PostTask(func, "", 0, OHOS::AppExecFwk::EventQueue::Priority::HIGH, {}); return true; } @@ -330,11 +350,9 @@ static void EmitUvEventLoop(sptr asyncCallbackInfo) return; } - ani_error error; if (!(g_convertfuncList.find(asyncCallbackInfo->type) != g_convertfuncList.end())) { SEN_HILOGE("asyncCallbackInfo type is invalid"); - error = CreateAniError(asyncCallbackInfo->env, "asyncCallbackInfo type is invalid"); - asyncCallbackInfo->env->ThrowError(error); + ThrowBusinessError(asyncCallbackInfo->env, EINVAL, "asyncCallbackInfo type is invalid"); return; } std::vector args; @@ -344,22 +362,19 @@ static void EmitUvEventLoop(sptr asyncCallbackInfo) SEN_HILOGD("Begin to call FunctionalObject_Call"); if (fnObj == nullptr) { SEN_HILOGE("fnObj == nullptr"); - error = CreateAniError(asyncCallbackInfo->env, "fnObj == nullptr"); - asyncCallbackInfo->env->ThrowError(error); + ThrowBusinessError(asyncCallbackInfo->env, EINVAL, "fnObj == nullptr"); return; } if (IsInstanceOf(asyncCallbackInfo->env, "Lstd/core/Function1;", fnObj) == 0) { SEN_HILOGE("fnObj is not instance Of function"); - error = CreateAniError(asyncCallbackInfo->env, "fnObj is not instance Of function"); - asyncCallbackInfo->env->ThrowError(error); + ThrowBusinessError(asyncCallbackInfo->env, EINVAL, "fnObj is not instance Of function"); return; } ani_ref result; if (ANI_OK != asyncCallbackInfo->env->FunctionalObject_Call(fnObj, 1, args.data(), &result)) { SEN_HILOGE("FunctionalObject_Call failed"); - error = CreateAniError(asyncCallbackInfo->env, "FunctionalObject_Call failed"); - asyncCallbackInfo->env->ThrowError(error); + ThrowBusinessError(asyncCallbackInfo->env, EINVAL, "FunctionalObject_Call failed"); return; } SEN_HILOGD("FunctionalObject_Call success"); @@ -535,8 +550,7 @@ static void On([[maybe_unused]] ani_env *env, ani_string typeId, ani_object call } int32_t ret = SubscribeSensor(sensorTypeId, interval, DataCallbackImpl); if (ret != ERR_OK) { - auto error = CreateAniError(env, "SubscribeSensor fail"); - env->ThrowError(error); + ThrowBusinessError(env, ret, "SubscribeSensor fail"); return; } UpdateCallbackInfos(env, sensorTypeId, callback); @@ -612,11 +626,9 @@ static void Off([[maybe_unused]] ani_env *env, ani_string type, ani_object callb CALL_LOG_ENTER; int32_t sensorTypeId = INVALID_SENSOR_ID; auto typeStr = AniStringUtils::ToStd(env, static_cast(type)); - ani_error error; if (stringToNumberMap.find(typeStr) == stringToNumberMap.end()) { SEN_HILOGE("Invalid sensor type: %{public}s", typeStr.c_str()); - error = CreateAniError(env, "Invalid sensor type"); - env->ThrowError(error); + ThrowBusinessError(env, PARAMETER_ERROR, "Invalid sensor type"); return; } sensorTypeId = stringToNumberMap[typeStr]; @@ -633,8 +645,7 @@ static void Off([[maybe_unused]] ani_env *env, ani_string type, ani_object callb } else if (IsInstanceOf(env, "Lstd/core/Function1;", callback)) { subscribeSize = RemoveCallback(env, sensorTypeId, callback); } else { - error = CreateAniError(env, "Invalid sensor type"); - env->ThrowError(error); + ThrowBusinessError(env, PARAMETER_ERROR, "Invalid callback"); return; } } @@ -645,8 +656,7 @@ static void Off([[maybe_unused]] ani_env *env, ani_string type, ani_object callb } int32_t ret = UnsubscribeSensor(sensorTypeId); if (ret == PARAMETER_ERROR || ret == PERMISSION_DENIED) { - error = CreateAniError(env, "UnsubscribeSensor fail"); - env->ThrowError(error); + ThrowBusinessError(env, ret, "UnsubscribeSensor fail"); } return; } -- Gitee From ba6992737457c21104a4da7bc581528f3206020c Mon Sep 17 00:00:00 2001 From: songhuan Date: Tue, 29 Apr 2025 18:24:47 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dxts=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E7=94=A8=E4=BE=8Bapp=20died?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Id08e71a6e81cf4d78140e7031c84a5563b964829 Signed-off-by: songhuan --- frameworks/js/ani/include/sensor_ani.h | 7 +++++-- frameworks/js/ani/src/sensor_ani.cpp | 21 +++++++++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/frameworks/js/ani/include/sensor_ani.h b/frameworks/js/ani/include/sensor_ani.h index 3fd5c5a6..be11ac17 100644 --- a/frameworks/js/ani/include/sensor_ani.h +++ b/frameworks/js/ani/include/sensor_ani.h @@ -106,13 +106,14 @@ struct BusinessError { class AsyncCallbackInfo : public RefBase { public: - ani_env* env = nullptr; + ani_vm *vm = nullptr; + ani_env *env = nullptr; ani_ref callback[CALLBACK_NUM] = { 0 }; CallbackData data; BusinessError error; CallbackDataType type; vector sensorInfos; - AsyncCallbackInfo(ani_env* env, CallbackDataType type) : env(env), type(type) {} + AsyncCallbackInfo(ani_vm *vm, ani_env *env, CallbackDataType type) : vm(vm), env(env), type(type) {} ~AsyncCallbackInfo() { CALL_LOG_ENTER; @@ -122,6 +123,8 @@ public: SEN_HILOGD("Delete reference, i:%{public}d", i); env->GlobalReference_Delete(callback[i]); callback[i] = nullptr; + env = nullptr; + vm = nullptr; } } } diff --git a/frameworks/js/ani/src/sensor_ani.cpp b/frameworks/js/ani/src/sensor_ani.cpp index 9df28203..361c6e41 100644 --- a/frameworks/js/ani/src/sensor_ani.cpp +++ b/frameworks/js/ani/src/sensor_ani.cpp @@ -86,7 +86,7 @@ static float g_bodyState = -1.0f; static std::map>> g_subscribeCallbacks; static std::mutex onMutex_; static std::map>> g_onCallbackInfos; -static thread_local std::shared_ptr mainHandler; +static thread_local std::shared_ptr mainHandler = nullptr; static void ThrowBusinessError(ani_env *env, int errCode, std::string&& errMsg) { @@ -344,6 +344,16 @@ static void EmitUvEventLoop(sptr asyncCallbackInfo) CHKPV(asyncCallbackInfo); auto task = [asyncCallbackInfo]() { SEN_HILOGD("Begin to call task"); + ani_env *env = nullptr; + ani_options aniArgs {0, nullptr}; + if (ANI_ERROR == asyncCallbackInfo->vm->AttachCurrentThread(&aniArgs, ANI_VERSION_1, &env)) { + if (ANI_OK != asyncCallbackInfo->vm->GetEnv(ANI_VERSION_1, &env)) { + SEN_HILOGE("GetEnv failed"); + return; + } + } + asyncCallbackInfo->env = env; + AniLocalScopeGuard aniLocalScopeGuard(asyncCallbackInfo->env, ANI_SCOPE_SIZE); if (!aniLocalScopeGuard.IsStatusOK()) { SEN_HILOGE("CreateLocalScope failed"); @@ -452,12 +462,19 @@ static bool IsSubscribed(ani_env *env, int32_t sensorTypeId, ani_object callback } return false; } + static void UpdateCallbackInfos(ani_env *env, int32_t sensorTypeId, ani_object callback) { CALL_LOG_ENTER; std::lock_guard onCallbackLock(onMutex_); CHKCV((!IsSubscribed(env, sensorTypeId, callback)), "The callback has been subscribed"); - sptr asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, ON_CALLBACK); + + ani_vm *vm = nullptr; + if (ANI_OK != env->GetVM(&vm)) { + SEN_HILOGE("GetVM failed."); + return; + } + sptr asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(vm, env, ON_CALLBACK); CHKPV(asyncCallbackInfo); if (ANI_OK != env->GlobalReference_Create(callback, &asyncCallbackInfo->callback[0])) { -- Gitee