!12381 wantagent支持多线程传递

Merge pull request !12381 from linjunjie/ljj_master_4
This commit is contained in:
openharmony_ci
2025-01-16 03:25:56 +00:00
committed by Gitee
12 changed files with 359 additions and 82 deletions
+9
View File
@@ -253,6 +253,15 @@
},
"name": "//foundation/ability/ability_runtime/frameworks/js/napi/inner/napi_ability_common:napi_ability_common"
},
{
"header": {
"header_base": "//foundation/ability/ability_runtime/frameworks/js/napi/inner/napi_wantagent_common",
"header_files": [
"napi_common_want_agent.h"
]
},
"name": "//foundation/ability/ability_runtime/frameworks/js/napi/inner/napi_wantagent_common:napi_wantagent_common"
},
{
"header": {
"header_base": "//foundation/ability/ability_runtime/interfaces/inner_api/app_manager/include",
+1
View File
@@ -66,6 +66,7 @@ group("napi_packages") {
"${ability_runtime_napi_path}/feature_ability:featureability_napi",
"${ability_runtime_napi_path}/inner/napi_ability_common:napi_ability_common",
"${ability_runtime_napi_path}/inner/napi_common:napi_common",
"${ability_runtime_napi_path}/inner/napi_wantagent_common:napi_wantagent_common",
"${ability_runtime_napi_path}/insight_intent/insight_intent:insightintent_napi",
"${ability_runtime_napi_path}/insight_intent/insight_intent_driver:insightintentdriver_napi",
"${ability_runtime_napi_path}/insight_intent/insight_intent_executor:insightintentexecutor_napi",
@@ -0,0 +1,59 @@
# Copyright (c) 2025 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
import("//foundation/ability/ability_runtime/ability_runtime.gni")
config("napi_wantagent_common_public_config") {
include_dirs = [ "./" ]
}
ohos_shared_library("napi_wantagent_common") {
sanitize = {
integer_overflow = true
ubsan = true
boundary_sanitize = true
cfi = true
cfi_cross_dso = true
cfi_vcall_icall_only = true
debug = false
}
branch_protector_ret = "pac_ret"
include_dirs = [
"${ability_runtime_services_path}/common/include",
"${ability_runtime_path}/interfaces/kits/native/ability/native",
]
public_configs = [ ":napi_wantagent_common_public_config" ]
sources = [ "napi_common_want_agent.cpp" ]
deps = [
"${ability_runtime_innerkits_path}/runtime:runtime",
"${ability_runtime_innerkits_path}/wantagent:wantagent_innerkits",
]
external_deps = [
"access_token:libtokenid_sdk",
"c_utils:utils",
"common_event_service:cesfwk_innerkits",
"hilog:libhilog",
"libuv:uv",
"napi:ace_napi",
]
innerapi_tags = [ "platformsdk" ]
subsystem_name = "ability"
part_name = "ability_runtime"
}
@@ -0,0 +1,152 @@
/*
* Copyright (c) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "napi_common_want_agent.h"
#include "hilog_tag_wrapper.h"
#include "js_runtime_utils.h"
#include "napi/native_api.h"
#include "want_agent.h"
namespace OHOS {
namespace AppExecFwk {
using namespace OHOS::AbilityRuntime;
inline void *DetachCallbackFunc(napi_env env, void *value, void *)
{
return value;
}
napi_value AttachWantAgentFunc(napi_env env, void *value, void *)
{
TAG_LOGI(AAFwkTag::WANTAGENT, "called");
if (value == nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "null value");
return nullptr;
}
napi_value jsObject = nullptr;
NAPI_CALL(env, napi_create_object(env, &jsObject));
if (!AbilityRuntime::WantAgent::WantAgent::GetIsMultithreadingSupported()) {
TAG_LOGI(AAFwkTag::WANTAGENT, "wantAgent not support multi thread current");
return jsObject;
}
auto wantAgent = new (std::nothrow) AbilityRuntime::WantAgent::WantAgent(
reinterpret_cast<AbilityRuntime::WantAgent::WantAgent*>(value)->GetPendingWant());
if (wantAgent == nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "new wantAgent failed");
return jsObject;
}
napi_value wantAgentClass = nullptr;
napi_define_class(env, "WantAgentClass", NAPI_AUTO_LENGTH,
[](napi_env env, napi_callback_info info) -> napi_value {
napi_value thisVar = nullptr;
napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
return thisVar;
}, nullptr, 0, nullptr, &wantAgentClass);
napi_value result = nullptr;
napi_new_instance(env, wantAgentClass, 0, nullptr, &result);
if (result == nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "create instance failed");
delete wantAgent;
wantAgent = nullptr;
return jsObject;
}
napi_coerce_to_native_binding_object(env, result, DetachCallbackFunc, AttachWantAgentFunc, value, nullptr);
auto res = napi_wrap(env, result, reinterpret_cast<void*>(wantAgent),
[](napi_env env, void* data, void* hint) {
TAG_LOGD(AAFwkTag::WANTAGENT, "delete wantAgent");
auto agent = static_cast<AbilityRuntime::WantAgent::WantAgent*>(data);
delete agent;
agent = nullptr;
}, nullptr, nullptr);
if (res != napi_ok && wantAgent != nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "napi_wrap failed:%{public}d", res);
delete wantAgent;
wantAgent = nullptr;
return jsObject;
}
return result;
}
napi_value WrapWantAgent(napi_env env, AbilityRuntime::WantAgent::WantAgent* wantAgent, napi_finalize finalizeCb)
{
TAG_LOGD(AAFwkTag::WANTAGENT, "called");
napi_value wantAgentClass = nullptr;
napi_define_class(
env,
"WantAgentClass",
NAPI_AUTO_LENGTH,
[](napi_env env, napi_callback_info info) -> napi_value {
napi_value thisVar = nullptr;
napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
return thisVar;
},
nullptr,
0,
nullptr,
&wantAgentClass);
napi_value result = nullptr;
napi_new_instance(env, wantAgentClass, 0, nullptr, &result);
if (result == nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "create instance failed");
return nullptr;
}
napi_coerce_to_native_binding_object(env, result, DetachCallbackFunc, AttachWantAgentFunc, wantAgent, nullptr);
napi_finalize finalize = [](napi_env env, void* data, void* hint) {
TAG_LOGD(AAFwkTag::WANTAGENT, "delete wantAgent");
if (data != nullptr) {
auto agent = static_cast<AbilityRuntime::WantAgent::WantAgent*>(data);
delete agent;
agent = nullptr;
}
};
if (finalizeCb != nullptr) {
finalize = finalizeCb;
}
auto res = napi_wrap(env, result, reinterpret_cast<void*>(wantAgent), finalize, nullptr, nullptr);
if (res != napi_ok && wantAgent != nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "napi_wrap failed:%{public}d", res);
return nullptr;
}
return result;
}
void UnwrapWantAgent(napi_env env, napi_value jsParam, void **result)
{
TAG_LOGD(AAFwkTag::WANTAGENT, "called");
if (jsParam == nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "null jsParam");
return;
}
if (!CheckTypeForNapiValue(env, jsParam, napi_object)) {
TAG_LOGE(AAFwkTag::WANTAGENT, "jsParam type error");
return;
}
napi_unwrap(env, jsParam, result);
}
} // namespace AppExecFwk
} // namespace OHOS
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_ABILITY_RUNTIME_NAPI_COMMON_WANT_AGENT_H
#define OHOS_ABILITY_RUNTIME_NAPI_COMMON_WANT_AGENT_H
#include "want_agent.h"
#include "napi/native_api.h"
namespace OHOS {
namespace AppExecFwk {
napi_value WrapWantAgent(napi_env env, AbilityRuntime::WantAgent::WantAgent *wantAgent, napi_finalize finalizeCb);
void UnwrapWantAgent(napi_env env, napi_value jsParam, void **result);
} // namespace AppExecFwk
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_NAPI_COMMON_WANT_AGENT_H
+1
View File
@@ -34,6 +34,7 @@ ohos_shared_library("wantagent") {
"${ability_runtime_innerkits_path}/runtime:runtime",
"${ability_runtime_innerkits_path}/wantagent:wantagent_innerkits",
"${ability_runtime_napi_path}/inner/napi_common:napi_common",
"${ability_runtime_napi_path}/inner/napi_wantagent_common:napi_wantagent_common",
"${ability_runtime_native_path}/ability/native:abilitykit_native",
"${ability_runtime_native_path}/appkit:app_context",
]
@@ -35,6 +35,7 @@ ohos_shared_library("wantagent_napi") {
"${ability_runtime_innerkits_path}/runtime:runtime",
"${ability_runtime_innerkits_path}/wantagent:wantagent_innerkits",
"${ability_runtime_napi_path}/inner/napi_common:napi_common",
"${ability_runtime_napi_path}/inner/napi_wantagent_common:napi_wantagent_common",
"${ability_runtime_native_path}/ability/native:abilitykit_native",
"${ability_runtime_native_path}/appkit:app_context",
]
@@ -62,6 +62,8 @@ napi_value JsNapiWantAgentInit(napi_env env, napi_value exportObj)
BindNativeFunction(env, exportObj, "getWant", moduleName, JsWantAgent::NapiGetWant);
BindNativeFunction(env, exportObj, "getWantAgent", moduleName, JsWantAgent::NapiGetWantAgent);
BindNativeFunction(env, exportObj, "getOperationType", moduleName, JsWantAgent::NapiGetOperationType);
BindNativeFunction(env, exportObj, "setWantAgentMultithreading", moduleName,
JsWantAgent::NapiSetWantAgentMultithreading);
return exportObj;
}
EXTERN_C_END
@@ -24,6 +24,7 @@
#include "hilog_tag_wrapper.h"
#include "ipc_skeleton.h"
#include "napi_common.h"
#include "napi_common_want_agent.h"
#include "start_options.h"
#include "want_agent_helper.h"
#include "tokenid_kit.h"
@@ -155,8 +156,12 @@ auto OnSendFinishedUvAfterWorkCallback = [](uv_work_t* work, int status) {
napi_set_named_property(dataWorkerData->env, objValueFirst, "code",
CreateJsValue(dataWorkerData->env, BUSINESS_ERROR_CODE_OK));
#endif
napi_set_named_property(dataWorkerData->env, objValueSecond, "wantAgent",
JsWantAgent::WrapWantAgent(dataWorkerData->env, dataWorkerData->wantAgent));
napi_value jsWantAgent = OHOS::AppExecFwk::WrapWantAgent(dataWorkerData->env, dataWorkerData->wantAgent, nullptr);
if (jsWantAgent == nullptr && dataWorkerData->wantAgent != nullptr) {
delete dataWorkerData->wantAgent;
dataWorkerData->wantAgent = nullptr;
}
napi_set_named_property(dataWorkerData->env, objValueSecond, "wantAgent", jsWantAgent);
napi_set_named_property(dataWorkerData->env, objValueSecond, "want",
CreateJsWant(dataWorkerData->env, dataWorkerData->want));
napi_set_named_property(dataWorkerData->env, objValueSecond, "finalCode",
@@ -301,6 +306,12 @@ napi_value JsWantAgent::NapiGetOperationType(napi_env env, napi_callback_info in
return (me != nullptr) ? me->OnNapiGetOperationType(env, info) : nullptr;
};
napi_value JsWantAgent::NapiSetWantAgentMultithreading(napi_env env, napi_callback_info info)
{
JsWantAgent* me = CheckParamsAndGetThis<JsWantAgent>(env, info);
return (me != nullptr) ? me->OnNapiSetWantAgentMultithreading(env, info) : nullptr;
};
napi_value JsWantAgent::HandleInvalidParam(napi_env env, napi_value lastParam, const std::string &errorMessage)
{
#ifdef ENABLE_ERRCODE
@@ -1013,68 +1024,6 @@ int32_t JsWantAgent::GetWantAgentParam(napi_env env, napi_callback_info info, Wa
return BUSINESS_ERROR_CODE_OK;
}
napi_value JsWantAgent::WrapWantAgent(napi_env env, WantAgent* wantAgent)
{
TAG_LOGD(AAFwkTag::WANTAGENT, "called");
napi_value wantAgentClass = nullptr;
napi_define_class(
env,
"WantAgentClass",
NAPI_AUTO_LENGTH,
[](napi_env env, napi_callback_info info) -> napi_value {
napi_value thisVar = nullptr;
napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
return thisVar;
},
nullptr,
0,
nullptr,
&wantAgentClass);
napi_value result = nullptr;
napi_new_instance(env, wantAgentClass, 0, nullptr, &result);
if (result == nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "create instance failed");
delete wantAgent;
wantAgent = nullptr;
return nullptr;
}
auto res = napi_wrap(env,
result,
reinterpret_cast<void*>(wantAgent),
[](napi_env env, void* data, void* hint) {
TAG_LOGD(AAFwkTag::WANTAGENT, "delete wantAgent");
auto agent = static_cast<WantAgent*>(data);
delete agent;
agent = nullptr;
},
nullptr,
nullptr);
if (res != napi_ok && wantAgent != nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "napi_wrap failed:%{public}d", res);
delete wantAgent;
wantAgent = nullptr;
return nullptr;
}
return result;
}
void JsWantAgent::UnwrapWantAgent(napi_env env, napi_value jsParam, void** result)
{
TAG_LOGD(AAFwkTag::WANTAGENT, "called");
if (jsParam == nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "null jsParam");
return;
}
if (!CheckTypeForNapiValue(env, jsParam, napi_object)) {
TAG_LOGE(AAFwkTag::WANTAGENT, "jsParam type error");
return;
}
napi_unwrap(env, jsParam, result);
}
napi_value JsWantAgent::OnGetWantAgent(napi_env env, napi_callback_info info)
{
size_t argc = ARGS_MAX_COUNT;
@@ -1109,11 +1058,17 @@ napi_value JsWantAgent::OnGetWantAgent(napi_env env, napi_callback_info info)
std::shared_ptr<WantAgent> wantAgent = nullptr;
WantAgentHelper::GetWantAgent(context, wantAgentInfo, wantAgent);
WantAgent* pWantAgent = nullptr;
napi_value jsWantAgent = nullptr;
if (wantAgent) {
pWantAgent = new WantAgent(wantAgent->GetPendingWant());
}
jsWantAgent = OHOS::AppExecFwk::WrapWantAgent(env, pWantAgent, nullptr);
if (jsWantAgent == nullptr && pWantAgent != nullptr) {
delete pWantAgent;
pWantAgent = nullptr;
}
task.Resolve(env, self->WrapWantAgent(env, pWantAgent));
task.Resolve(env, jsWantAgent);
};
napi_value result = nullptr;
@@ -1257,23 +1212,25 @@ void JsWantAgent::SetOnNapiGetWantAgentCallback(std::shared_ptr<WantAgentWantsPa
ErrCode result = WantAgentHelper::GetWantAgent(context, wantAgentInfo, wantAgent);
if (result != NO_ERROR) {
task.Reject(env, CreateJsError(env, result, AbilityRuntimeErrorUtil::GetErrMessage(result)));
return;
}
if (wantAgent == nullptr) {
result = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
task.Reject(env, CreateJsError(env, result, AbilityRuntimeErrorUtil::GetErrMessage(result)));
return;
}
WantAgent *pWantAgent = new (std::nothrow) WantAgent(wantAgent->GetPendingWant());
if (pWantAgent == nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "null pWantAgent");
result = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
task.Reject(env, CreateJsError(env, result, AbilityRuntimeErrorUtil::GetErrMessage(result)));
} else {
WantAgent* pWantAgent = nullptr;
if (wantAgent == nullptr) {
result = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
task.Reject(env, CreateJsError(env, result, AbilityRuntimeErrorUtil::GetErrMessage(result)));
return;
} else {
pWantAgent = new (std::nothrow) WantAgent(wantAgent->GetPendingWant());
}
if (pWantAgent == nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "null pWantAgent");
result = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
task.Reject(env, CreateJsError(env, result, AbilityRuntimeErrorUtil::GetErrMessage(result)));
} else {
task.ResolveWithNoError(env, self->WrapWantAgent(env, pWantAgent));
napi_value jsWantAgent = OHOS::AppExecFwk::WrapWantAgent(env, pWantAgent, nullptr);
if (jsWantAgent == nullptr) {
delete pWantAgent;
pWantAgent = nullptr;
}
task.ResolveWithNoError(env, jsWantAgent);
}
};
}
@@ -1328,6 +1285,43 @@ napi_value JsWantAgent::OnNapiGetOperationType(napi_env env, napi_callback_info
return result;
}
napi_value JsWantAgent::OnNapiSetWantAgentMultithreading(napi_env env, napi_callback_info info)
{
TAG_LOGI(AAFwkTag::WANTAGENT, "set want agent multithreading");
bool isMultithreadingSupported = false;
size_t argc = ARGS_MAX_COUNT;
napi_value argv[ARGS_MAX_COUNT] = {nullptr};
napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
if (argc != ARGC_ONE) {
TAG_LOGE(AAFwkTag::WANTAGENT, "invalid argc");
ThrowInvalidNumParametersError(env);
return CreateJsUndefined(env);
}
auto selfToken = IPCSkeleton::GetSelfTokenID();
if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken)) {
TAG_LOGE(AAFwkTag::WANTAGENT, "Non-system app forbidden to call");
AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_NOT_SYSTEM_APP);
return CreateJsUndefined(env);
}
if (!CheckTypeForNapiValue(env, argv[0], napi_boolean)) {
TAG_LOGE(AAFwkTag::WANTAGENT, "Type not boolean");
ThrowInvalidParamError(env, "Parameter error! isMultithreadingSupported must be a boolean.");
return CreateJsUndefined(env);
}
if (!ConvertFromJsValue(env, argv[0], isMultithreadingSupported)) {
TAG_LOGE(AAFwkTag::WANTAGENT, "Convert isMultithreadingSupported failed");
ThrowInvalidParamError(env,
"Convert isMultithreadingSupported failed! isMultithreadingSupported must be a boolean.");
return CreateJsUndefined(env);
}
WantAgent::SetIsMultithreadingSupported(isMultithreadingSupported);
return CreateJsNull(env);
}
napi_value WantAgentFlagsInit(napi_env env)
{
if (env == nullptr) {
@@ -93,8 +93,7 @@ public:
static napi_value NapiTrigger(napi_env env, napi_callback_info info);
static napi_value NapiGetWantAgent(napi_env env, napi_callback_info info);
static napi_value NapiGetOperationType(napi_env env, napi_callback_info info);
static napi_value WrapWantAgent(napi_env env, WantAgent *wantAgent);
static void UnwrapWantAgent(napi_env env, napi_value jsParam, void** result);
static napi_value NapiSetWantAgentMultithreading(napi_env env, napi_callback_info info);
private:
napi_value OnEqual(napi_env env, napi_callback_info info);
@@ -109,6 +108,7 @@ private:
napi_value OnNapiTrigger(napi_env env, napi_callback_info info);
napi_value OnNapiGetWantAgent(napi_env env, napi_callback_info info);
napi_value OnNapiGetOperationType(napi_env env, napi_callback_info info);
napi_value OnNapiSetWantAgentMultithreading(napi_env env, napi_callback_info info);
int32_t UnWrapTriggerInfoParam(napi_env env, napi_callback_info info,
std::shared_ptr<WantAgent> &wantAgent, TriggerInfo &triggerInfo,
std::shared_ptr<TriggerCompleteCallBack> &triggerObj);
@@ -65,8 +65,23 @@ public:
*/
static WantAgent *Unmarshalling(Parcel &parcel);
/**
* Get isMultithreadingSupported_
*
* @return Return isMultithreadingSupported_
*/
static bool GetIsMultithreadingSupported();
/**
* Set isMultithreadingSupported_
*
* @param isMultithreadingSupported Indicates the WantAgent support multithreading or not.
*/
static void SetIsMultithreadingSupported(bool isMultithreadingSupported);
private:
std::shared_ptr<PendingWant> pendingWant_;
static bool isMultithreadingSupported_;
};
} // namespace OHOS::AbilityRuntime::WantAgent
#endif // OHOS_ABILITY_RUNTIME_WANT_AGENT_H
@@ -17,6 +17,8 @@
#include "want_agent.h"
namespace OHOS::AbilityRuntime::WantAgent {
bool WantAgent::isMultithreadingSupported_ = false;
WantAgent::WantAgent(const std::shared_ptr<PendingWant> &pendingWant)
{
pendingWant_ = pendingWant;
@@ -54,4 +56,15 @@ WantAgent *WantAgent::Unmarshalling(Parcel &parcel)
return agent;
}
bool WantAgent::GetIsMultithreadingSupported()
{
return isMultithreadingSupported_;
}
void WantAgent::SetIsMultithreadingSupported(bool isMultithreadingSupported)
{
isMultithreadingSupported_ = isMultithreadingSupported;
}
} // namespace OHOS::AbilityRuntime::WantAgent