From 303cefc4021e9f38ced2499b469e231dd34824ac Mon Sep 17 00:00:00 2001 From: peterhuangyu Date: Wed, 31 Jan 2024 11:03:13 +0800 Subject: [PATCH] Add error_manager napi processing function Signed-off-by: peterhuangyu --- frameworks/js/napi/app/error_manager/BUILD.gn | 1 + .../app/error_manager/js_error_manager.cpp | 119 ++++++++++++++++++ frameworks/native/runtime/js_error_utils.cpp | 8 ++ .../runtime/include/js_error_utils.h | 1 + 4 files changed, 129 insertions(+) diff --git a/frameworks/js/napi/app/error_manager/BUILD.gn b/frameworks/js/napi/app/error_manager/BUILD.gn index c004b8e51ad..8949155520c 100644 --- a/frameworks/js/napi/app/error_manager/BUILD.gn +++ b/frameworks/js/napi/app/error_manager/BUILD.gn @@ -41,6 +41,7 @@ template("errormanager") { external_deps = [ "c_utils:utils", + "eventhandler:libeventhandler", "hilog:libhilog", "napi:ace_napi", ] diff --git a/frameworks/js/napi/app/error_manager/js_error_manager.cpp b/frameworks/js/napi/app/error_manager/js_error_manager.cpp index c4973594bff..3e09fd5a705 100644 --- a/frameworks/js/napi/app/error_manager/js_error_manager.cpp +++ b/frameworks/js/napi/app/error_manager/js_error_manager.cpp @@ -16,9 +16,11 @@ #include "js_error_manager.h" #include +#include #include "ability_business_error.h" #include "application_data_manager.h" +#include "event_runner.h" #include "hilog_wrapper.h" #include "js_error_observer.h" #include "js_error_utils.h" @@ -29,13 +31,21 @@ namespace OHOS { namespace AbilityRuntime { namespace { +struct JsLoopObserver { + std::shared_ptr mainRunner; + std::shared_ptr observerObject; + napi_env env; +}; +static std::shared_ptr loopObserver_; constexpr int32_t INDEX_ZERO = 0; constexpr int32_t INDEX_ONE = 1; constexpr int32_t INDEX_TWO = 2; +constexpr size_t ARGC_ONE = 1; constexpr size_t ARGC_TWO = 2; constexpr size_t ARGC_THREE = 3; constexpr const char* ON_OFF_TYPE = "error"; constexpr const char* ON_OFF_TYPE_SYNC = "errorEvent"; +constexpr const char* ON_OFF_TYPE_SYNC_LOOP = "loopObserver"; class JsErrorManager final { public: @@ -66,6 +76,14 @@ private: if (type == ON_OFF_TYPE_SYNC) { return OnOnNew(env, argc, argv); } + if (type == ON_OFF_TYPE_SYNC_LOOP) { + if (!AppExecFwk::EventRunner::IsAppMainThread()) { + HILOG_ERROR("LoopObserver can only be set from main thread."); + ThrowInvaildCallerError(env); + return CreateJsUndefined(env); + } + return OnSetLoopWatch(env, argc, argv); + } return OnOnOld(env, argc, argv); } @@ -139,6 +157,14 @@ private: if (type == ON_OFF_TYPE_SYNC) { return OnOffNew(env, argc, argv); } + if (type == ON_OFF_TYPE_SYNC_LOOP) { + if (!AppExecFwk::EventRunner::IsAppMainThread()) { + HILOG_ERROR("LoopObserver can only be set from main thread."); + ThrowInvaildCallerError(env); + return CreateJsUndefined(env); + } + return OnRemoveLoopWatch(env, argc, argv); + } return OnOffOld(env, argc, argv); } @@ -219,6 +245,99 @@ private: return CreateJsUndefined(env); } + static void CallJsFunction(napi_env env, napi_value obj, const char* methodName, + napi_value const* argv, size_t argc) + { + HILOG_INFO("CallJsFunction begin methodName: %{public}s", methodName); + if (obj == nullptr) { + HILOG_ERROR("Failed to get object"); + return; + } + + napi_value method = nullptr; + napi_get_named_property(env, obj, methodName, &method); + if (method == nullptr) { + HILOG_ERROR("Failed to get method"); + return; + } + napi_value callResult = nullptr; + napi_call_function(env, obj, method, argc, argv, &callResult); + } + + static void CallbackTimeout(int64_t number) + { + std::unique_ptr complete = std::make_unique + ([number](napi_env env, NapiAsyncTask &task, int32_t status) { + if (loopObserver_ == nullptr) { + HILOG_ERROR("CallbackTimeout: loopObserver_ is null."); + return; + } + if (loopObserver_->env == nullptr) { + HILOG_ERROR("CallbackTimeout: env is null."); + return; + } + if (loopObserver_->observerObject == nullptr) { + HILOG_ERROR("CallbackTimeout: observerObject is null."); + return; + } + napi_value jsValue[] = { CreateJsValue(loopObserver_->env, number) }; + CallJsFunction(loopObserver_->env, loopObserver_->observerObject->GetNapiValue(), "onLoopTimeOut", + jsValue, ARGC_ONE); + }); + napi_ref callback = nullptr; + std::unique_ptr execute = nullptr; + if (loopObserver_ && loopObserver_->env) { + NapiAsyncTask::Schedule("JsErrorObserver::CallbackTimeout", + loopObserver_->env, std::make_unique(callback, std::move(execute), std::move(complete))); + } + } + + napi_value OnSetLoopWatch(napi_env env, size_t argc, napi_value* argv) + { + if (argc != ARGC_THREE) { + HILOG_ERROR("OnSetLoopWatch: Not enough params."); + ThrowTooFewParametersError(env); + return CreateJsUndefined(env); + } + if (!CheckTypeForNapiValue(env, argv[INDEX_ONE], napi_number)) { + HILOG_ERROR("OnSetLoopWatch: Invalid param"); + ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_PARAM); + return CreateJsUndefined(env); + } + if (!CheckTypeForNapiValue(env, argv[INDEX_TWO], napi_object)) { + HILOG_ERROR("OnSetLoopWatch: Invalid param"); + ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_PARAM); + return CreateJsUndefined(env); + } + int64_t number; + if (!ConvertFromJsNumber(env, argv[INDEX_ONE], number)) { + HILOG_ERROR("OnSetLoopWatch: Parse timeout failed"); + ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_PARAM); + return CreateJsUndefined(env); + } + + if (loopObserver_ == nullptr) { + loopObserver_ = std::make_shared(); + } + loopObserver_->mainRunner = AppExecFwk::EventRunner::GetMainEventRunner(); + napi_ref ref = nullptr; + napi_create_reference(env, argv[INDEX_TWO], 1, &ref); + loopObserver_->observerObject = std::shared_ptr(reinterpret_cast(ref)); + loopObserver_->env = env; + loopObserver_->mainRunner->SetTimeout(number); + loopObserver_->mainRunner->SetTimeoutCallback(CallbackTimeout); + return nullptr; + } + + napi_value OnRemoveLoopWatch(napi_env env, size_t argc, napi_value* argv) + { + if (loopObserver_) { + loopObserver_.reset(); + loopObserver_ = nullptr; + } + return nullptr; + } + std::string ParseParamType(napi_env env, const size_t argc, napi_value* argv) { std::string type; diff --git a/frameworks/native/runtime/js_error_utils.cpp b/frameworks/native/runtime/js_error_utils.cpp index 08e6f66b554..b4fdabf08d5 100755 --- a/frameworks/native/runtime/js_error_utils.cpp +++ b/frameworks/native/runtime/js_error_utils.cpp @@ -22,6 +22,7 @@ namespace OHOS { namespace AbilityRuntime { namespace { constexpr const char* ERR_MSG_TOO_FEW_PARAM = "Parameter error. Too few parameters."; +constexpr const char* ERR_MSG_NOT_MAINTHREAD = "Caller error. Caller from non-main thread."; } // namespace void ThrowError(napi_env env, int32_t errCode, const std::string& errorMsg) @@ -34,6 +35,13 @@ void ThrowError(napi_env env, const AbilityErrorCode& err) napi_throw(env, CreateJsError(env, static_cast(err), GetErrorMsg(err))); } +void ThrowInvaildCallerError(napi_env env) +{ + napi_throw(env, CreateJsError(env, + static_cast(AbilityErrorCode::ERROR_CODE_INVALID_CALLER), + ERR_MSG_NOT_MAINTHREAD)); +} + void ThrowTooFewParametersError(napi_env env) { napi_throw(env, CreateJsError(env, diff --git a/interfaces/inner_api/runtime/include/js_error_utils.h b/interfaces/inner_api/runtime/include/js_error_utils.h index ac867bb07f1..dd69891b105 100755 --- a/interfaces/inner_api/runtime/include/js_error_utils.h +++ b/interfaces/inner_api/runtime/include/js_error_utils.h @@ -24,6 +24,7 @@ namespace AbilityRuntime { void ThrowError(napi_env env, int32_t errCode, const std::string& errorMsg = ""); void ThrowError(napi_env env, const AbilityErrorCode& err); +void ThrowInvaildCallerError(napi_env env); void ThrowTooFewParametersError(napi_env env); void ThrowNoPermissionError(napi_env env, const std::string& permission); void ThrowErrorByNativeErr(napi_env env, int32_t err); -- Gitee